aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/CodeGen/X86/CodeGenerator.cs
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure/CodeGen/X86/CodeGenerator.cs')
-rw-r--r--ARMeilleure/CodeGen/X86/CodeGenerator.cs34
1 files changed, 34 insertions, 0 deletions
diff --git a/ARMeilleure/CodeGen/X86/CodeGenerator.cs b/ARMeilleure/CodeGen/X86/CodeGenerator.cs
index 83ff136a..29a4cd78 100644
--- a/ARMeilleure/CodeGen/X86/CodeGenerator.cs
+++ b/ARMeilleure/CodeGen/X86/CodeGenerator.cs
@@ -250,6 +250,40 @@ namespace ARMeilleure.CodeGen.X86
break;
}
+ case IntrinsicType.Mxcsr:
+ {
+ Operand offset = operation.GetSource(0);
+ Operand bits = operation.GetSource(1);
+
+ Debug.Assert(offset.Kind == OperandKind.Constant && bits.Kind == OperandKind.Constant);
+ Debug.Assert(offset.Type == OperandType.I32 && bits.Type == OperandType.I32);
+
+ int offs = offset.AsInt32() + context.CallArgsRegionSize;
+
+ Operand rsp = Register(X86Register.Rsp);
+
+ MemoryOperand memOp = MemoryOp(OperandType.I32, rsp, null, Multiplier.x1, offs);
+
+ Debug.Assert(HardwareCapabilities.SupportsSse || HardwareCapabilities.SupportsVexEncoding);
+
+ context.Assembler.Stmxcsr(memOp);
+
+ if (intrinOp.Intrinsic == Intrinsic.X86Mxcsrmb)
+ {
+ context.Assembler.Or(memOp, bits, OperandType.I32);
+ }
+ else /* if (intrinOp.Intrinsic == Intrinsic.X86Mxcsrub) */
+ {
+ Operand notBits = Const(~bits.AsInt32());
+
+ context.Assembler.And(memOp, notBits, OperandType.I32);
+ }
+
+ context.Assembler.Ldmxcsr(memOp);
+
+ break;
+ }
+
case IntrinsicType.PopCount:
{
Operand dest = operation.Destination;