From 567ea726e173040ae931a37bc85fd6cd92b69363 Mon Sep 17 00:00:00 2001
From: LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com>
Date: Mon, 7 Dec 2020 10:37:07 +0100
Subject: Add support for guest Fz (Fpcr) mode through host Ftz and Daz (Mxcsr)
 modes (fast paths). (#1630)

* Add support for guest Fz (Fpcr) mode through host Ftz and Daz (Mxcsr) modes (fast paths).

* Ptc.InternalVersion = 1630

* Nits.

* Address comments.

* Update Ptc.cs

* Address comment.
---
 ARMeilleure/CodeGen/X86/CodeGenerator.cs | 34 ++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

(limited to 'ARMeilleure/CodeGen/X86/CodeGenerator.cs')

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;
-- 
cgit v1.2.3-70-g09d2