diff options
Diffstat (limited to 'ARMeilleure/Instructions')
27 files changed, 692 insertions, 852 deletions
diff --git a/ARMeilleure/Instructions/DelegateTypes.cs b/ARMeilleure/Instructions/DelegateTypes.cs deleted file mode 100644 index 41614f88..00000000 --- a/ARMeilleure/Instructions/DelegateTypes.cs +++ /dev/null @@ -1,94 +0,0 @@ -using ARMeilleure.State; -using System; - -namespace ARMeilleure.Instructions -{ - delegate bool _Bool(); - - delegate double _F64_F64(double a1); - delegate double _F64_F64_Bool(double a1, bool a2); - delegate double _F64_F64_F64(double a1, double a2); - delegate double _F64_F64_F64_Bool(double a1, double a2, bool a3); - delegate double _F64_F64_F64_F64(double a1, double a2, double a3); - delegate double _F64_F64_F64_F64_Bool(double a1, double a2, double a3, bool a4); - delegate double _F64_F64_MidpointRounding(double a1, MidpointRounding a2); - - delegate float _F32_F32(float a1); - delegate float _F32_F32_Bool(float a1, bool a2); - delegate float _F32_F32_F32(float a1, float a2); - delegate float _F32_F32_F32_Bool(float a1, float a2, bool a3); - delegate float _F32_F32_F32_F32(float a1, float a2, float a3); - delegate float _F32_F32_F32_F32_Bool(float a1, float a2, float a3, bool a4); - delegate float _F32_F32_MidpointRounding(float a1, MidpointRounding a2); - delegate float _F32_U16(ushort a1); - - delegate int _S32_F32(float a1); - delegate int _S32_F32_F32_Bool(float a1, float a2, bool a3); - delegate int _S32_F64(double a1); - delegate int _S32_F64_F64_Bool(double a1, double a2, bool a3); - delegate int _S32_U64_U16(ulong a1, ushort a2); - delegate int _S32_U64_U32(ulong a1, uint a2); - delegate int _S32_U64_U64(ulong a1, ulong a2); - delegate int _S32_U64_U8(ulong a1, byte a2); - delegate int _S32_U64_V128(ulong a1, V128 a2); - - delegate long _S64_F32(float a1); - delegate long _S64_F64(double a1); - delegate long _S64_S64(long a1); - delegate long _S64_S64_S32(long a1, int a2); - delegate long _S64_S64_S64(long a1, long a2); - delegate long _S64_S64_S64_Bool_S32(long a1, long a2, bool a3, int a4); - delegate long _S64_S64_S64_S32(long a1, long a2, int a3); - delegate long _S64_U64_S32(ulong a1, int a2); - delegate long _S64_U64_S64(ulong a1, long a2); - - delegate ushort _U16_F32(float a1); - delegate ushort _U16_U64(ulong a1); - - delegate uint _U32(); - delegate uint _U32_F32(float a1); - delegate uint _U32_F64(double a1); - delegate uint _U32_U32(uint a1); - delegate uint _U32_U32_U16(uint a1, ushort a2); - delegate uint _U32_U32_U32(uint a1, uint a2); - delegate uint _U32_U32_U64(uint a1, ulong a2); - delegate uint _U32_U32_U8(uint a1, byte a2); - delegate uint _U32_U64(ulong a1); - - delegate ulong _U64(); - delegate ulong _U64_F32(float a1); - delegate ulong _U64_F64(double a1); - delegate ulong _U64_S64_S32(long a1, int a2); - delegate ulong _U64_S64_U64(long a1, ulong a2); - delegate ulong _U64_U64(ulong a1); - delegate ulong _U64_U64_S32(ulong a1, int a2); - delegate ulong _U64_U64_S64_S32(ulong a1, long a2, int a3); - delegate ulong _U64_U64_U64(ulong a1, ulong a2); - delegate ulong _U64_U64_U64_Bool_S32(ulong a1, ulong a2, bool a3, int a4); - - delegate byte _U8_U64(ulong a1); - - delegate V128 _V128_U64(ulong a1); - delegate V128 _V128_V128(V128 a1); - delegate V128 _V128_V128_S32_V128(V128 a1, int a2, V128 a3); - delegate V128 _V128_V128_S32_V128_V128(V128 a1, int a2, V128 a3, V128 a4); - delegate V128 _V128_V128_S32_V128_V128_V128(V128 a1, int a2, V128 a3, V128 a4, V128 a5); - delegate V128 _V128_V128_S32_V128_V128_V128_V128(V128 a1, int a2, V128 a3, V128 a4, V128 a5, V128 a6); - delegate V128 _V128_V128_U32_V128(V128 a1, uint a2, V128 a3); - delegate V128 _V128_V128_V128(V128 a1, V128 a2); - delegate V128 _V128_V128_V128_S32_V128(V128 a1, V128 a2, int a3, V128 a4); - delegate V128 _V128_V128_V128_S32_V128_V128(V128 a1, V128 a2, int a3, V128 a4, V128 a5); - delegate V128 _V128_V128_V128_S32_V128_V128_V128(V128 a1, V128 a2, int a3, V128 a4, V128 a5, V128 a6); - delegate V128 _V128_V128_V128_S32_V128_V128_V128_V128(V128 a1, V128 a2, int a3, V128 a4, V128 a5, V128 a6, V128 a7); - delegate V128 _V128_V128_V128_V128(V128 a1, V128 a2, V128 a3); - - delegate void _Void(); - delegate void _Void_U32(uint a1); - delegate void _Void_U64(ulong a1); - delegate void _Void_U64_S32(ulong a1, int a2); - delegate void _Void_U64_U16(ulong a1, ushort a2); - delegate void _Void_U64_U32(ulong a1, uint a2); - delegate void _Void_U64_U64(ulong a1, ulong a2); - delegate void _Void_U64_U8(ulong a1, byte a2); - delegate void _Void_U64_V128(ulong a1, V128 a2); -} diff --git a/ARMeilleure/Instructions/InstEmitException.cs b/ARMeilleure/Instructions/InstEmitException.cs index f0bde242..cdf6cf34 100644 --- a/ARMeilleure/Instructions/InstEmitException.cs +++ b/ARMeilleure/Instructions/InstEmitException.cs @@ -1,6 +1,5 @@ using ARMeilleure.Decoders; using ARMeilleure.Translation; -using System; using static ARMeilleure.Instructions.InstEmitFlowHelper; using static ARMeilleure.IntermediateRepresentation.OperandHelper; @@ -11,21 +10,21 @@ namespace ARMeilleure.Instructions { public static void Brk(ArmEmitterContext context) { - EmitExceptionCall(context, NativeInterface.Break); + EmitExceptionCall(context, nameof(NativeInterface.Break)); } public static void Svc(ArmEmitterContext context) { - EmitExceptionCall(context, NativeInterface.SupervisorCall); + EmitExceptionCall(context, nameof(NativeInterface.SupervisorCall)); } - private static void EmitExceptionCall(ArmEmitterContext context, _Void_U64_S32 func) + private static void EmitExceptionCall(ArmEmitterContext context, string name) { OpCodeException op = (OpCodeException)context.CurrOp; context.StoreToContext(); - context.Call(func, Const(op.Address), Const(op.Id)); + context.Call(typeof(NativeInterface).GetMethod(name), Const(op.Address), Const(op.Id)); context.LoadFromContext(); @@ -39,11 +38,11 @@ namespace ARMeilleure.Instructions { OpCode op = context.CurrOp; - Delegate dlg = new _Void_U64_S32(NativeInterface.Undefined); + string name = nameof(NativeInterface.Undefined); context.StoreToContext(); - context.Call(dlg, Const(op.Address), Const(op.RawOpCode)); + context.Call(typeof(NativeInterface).GetMethod(name), Const(op.Address), Const(op.RawOpCode)); context.LoadFromContext(); diff --git a/ARMeilleure/Instructions/InstEmitException32.cs b/ARMeilleure/Instructions/InstEmitException32.cs index 8ffad1d1..fd64e7bf 100644 --- a/ARMeilleure/Instructions/InstEmitException32.cs +++ b/ARMeilleure/Instructions/InstEmitException32.cs @@ -10,21 +10,21 @@ namespace ARMeilleure.Instructions { public static void Svc(ArmEmitterContext context) { - EmitExceptionCall(context, NativeInterface.SupervisorCall); + EmitExceptionCall(context, nameof(NativeInterface.SupervisorCall)); } public static void Trap(ArmEmitterContext context) { - EmitExceptionCall(context, NativeInterface.Break); + EmitExceptionCall(context, nameof(NativeInterface.Break)); } - private static void EmitExceptionCall(ArmEmitterContext context, _Void_U64_S32 func) + private static void EmitExceptionCall(ArmEmitterContext context, string name) { OpCode32Exception op = (OpCode32Exception)context.CurrOp; context.StoreToContext(); - context.Call(func, Const(op.Address), Const(op.Id)); + context.Call(typeof(NativeInterface).GetMethod(name), Const(op.Address), Const(op.Id)); context.LoadFromContext(); diff --git a/ARMeilleure/Instructions/InstEmitFlowHelper.cs b/ARMeilleure/Instructions/InstEmitFlowHelper.cs index 7b244296..e99afa75 100644 --- a/ARMeilleure/Instructions/InstEmitFlowHelper.cs +++ b/ARMeilleure/Instructions/InstEmitFlowHelper.cs @@ -2,6 +2,7 @@ using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; +using ARMeilleure.Translation.PTC; using System; using static ARMeilleure.Instructions.InstEmitHelper; @@ -223,6 +224,7 @@ namespace ARMeilleure.Instructions public static void EmitTailContinue(ArmEmitterContext context, Operand address, bool allowRejit = false) { bool useTailContinue = true; // Left option here as it may be useful if we need to return to managed rather than tail call in future. (eg. for debug) + if (useTailContinue) { if (context.HighCq) @@ -230,7 +232,7 @@ namespace ARMeilleure.Instructions // If we're doing a tail continue in HighCq, reserve a space in the jump table to avoid calling back to the translator. // This will always try to get a HighCq version of our continue target as well. EmitJumpTableBranch(context, address, true); - } + } else { if (allowRejit) @@ -238,11 +240,11 @@ namespace ARMeilleure.Instructions address = context.BitwiseOr(address, Const(CallFlag)); } - Operand fallbackAddr = context.Call(new _U64_U64(NativeInterface.GetFunctionAddress), address); + Operand fallbackAddr = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), address); EmitNativeCall(context, fallbackAddr, true); } - } + } else { context.Return(address); @@ -260,7 +262,7 @@ namespace ARMeilleure.Instructions private static void EmitBranchFallback(ArmEmitterContext context, Operand address, bool isJump) { address = context.BitwiseOr(address, Const(address.Type, (long)CallFlag)); // Set call flag. - Operand fallbackAddr = context.Call(new _U64_U64(NativeInterface.GetFunctionAddress), address); + Operand fallbackAddr = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), address); EmitNativeCall(context, fallbackAddr, isJump); } @@ -290,12 +292,12 @@ namespace ARMeilleure.Instructions }; // Currently this uses a size of 1, as higher values inflate code size for no real benefit. - for (int i = 0; i < JumpTable.DynamicTableElems; i++) + for (int i = 0; i < JumpTable.DynamicTableElems; i++) { if (i == JumpTable.DynamicTableElems - 1) { emitTableEntry(fallbackLabel); // If this is the last entry, avoid emitting the additional label and add. - } + } else { Operand nextLabel = Label(); @@ -339,7 +341,18 @@ namespace ARMeilleure.Instructions int entry = context.JumpTable.ReserveDynamicEntry(isJump); int jumpOffset = entry * JumpTable.JumpTableStride * JumpTable.DynamicTableElems; - Operand dynTablePtr = Const(context.JumpTable.DynamicPointer.ToInt64() + jumpOffset); + + Operand dynTablePtr; + + if (Ptc.State == PtcState.Disabled) + { + dynTablePtr = Const(context.JumpTable.DynamicPointer.ToInt64() + jumpOffset); + } + else + { + dynTablePtr = Const(context.JumpTable.DynamicPointer.ToInt64(), true, Ptc.DynamicPointerIndex); + dynTablePtr = context.Add(dynTablePtr, Const((long)jumpOffset)); + } EmitDynamicTableCall(context, dynTablePtr, address, isJump); } @@ -349,8 +362,17 @@ namespace ARMeilleure.Instructions int jumpOffset = entry * JumpTable.JumpTableStride + 8; // Offset directly to the host address. - // TODO: Relocatable jump table ptr for AOT. Would prefer a solution to patch this constant into functions as they are loaded rather than calculate at runtime. - Operand tableEntryPtr = Const(context.JumpTable.JumpPointer.ToInt64() + jumpOffset); + Operand tableEntryPtr; + + if (Ptc.State == PtcState.Disabled) + { + tableEntryPtr = Const(context.JumpTable.JumpPointer.ToInt64() + jumpOffset); + } + else + { + tableEntryPtr = Const(context.JumpTable.JumpPointer.ToInt64(), true, Ptc.JumpPointerIndex); + tableEntryPtr = context.Add(tableEntryPtr, Const((long)jumpOffset)); + } Operand funcAddr = context.Load(OperandType.I64, tableEntryPtr); diff --git a/ARMeilleure/Instructions/InstEmitHash.cs b/ARMeilleure/Instructions/InstEmitHash.cs index 8a539666..2a8b3488 100644 --- a/ARMeilleure/Instructions/InstEmitHash.cs +++ b/ARMeilleure/Instructions/InstEmitHash.cs @@ -3,7 +3,6 @@ using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; -using System; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; @@ -21,7 +20,7 @@ namespace ARMeilleure.Instructions } else { - EmitCrc32Call(context, new _U32_U32_U8(SoftFallback.Crc32b)); + EmitCrc32Call(context, nameof(SoftFallback.Crc32b)); } } @@ -33,7 +32,7 @@ namespace ARMeilleure.Instructions } else { - EmitCrc32Call(context, new _U32_U32_U16(SoftFallback.Crc32h)); + EmitCrc32Call(context, nameof(SoftFallback.Crc32h)); } } @@ -45,7 +44,7 @@ namespace ARMeilleure.Instructions } else { - EmitCrc32Call(context, new _U32_U32_U32(SoftFallback.Crc32w)); + EmitCrc32Call(context, nameof(SoftFallback.Crc32w)); } } @@ -57,7 +56,7 @@ namespace ARMeilleure.Instructions } else { - EmitCrc32Call(context, new _U32_U32_U64(SoftFallback.Crc32x)); + EmitCrc32Call(context, nameof(SoftFallback.Crc32x)); } } @@ -69,7 +68,7 @@ namespace ARMeilleure.Instructions } else { - EmitCrc32Call(context, new _U32_U32_U8(SoftFallback.Crc32cb)); + EmitCrc32Call(context, nameof(SoftFallback.Crc32cb)); } } @@ -81,7 +80,7 @@ namespace ARMeilleure.Instructions } else { - EmitCrc32Call(context, new _U32_U32_U16(SoftFallback.Crc32ch)); + EmitCrc32Call(context, nameof(SoftFallback.Crc32ch)); } } @@ -93,7 +92,7 @@ namespace ARMeilleure.Instructions } else { - EmitCrc32Call(context, new _U32_U32_U32(SoftFallback.Crc32cw)); + EmitCrc32Call(context, nameof(SoftFallback.Crc32cw)); } } @@ -105,7 +104,7 @@ namespace ARMeilleure.Instructions } else { - EmitCrc32Call(context, new _U32_U32_U64(SoftFallback.Crc32cx)); + EmitCrc32Call(context, nameof(SoftFallback.Crc32cx)); } } @@ -170,14 +169,14 @@ namespace ARMeilleure.Instructions SetIntOrZR(context, op.Rd, context.VectorExtract(OperandType.I32, tmp, 2)); } - private static void EmitCrc32Call(ArmEmitterContext context, Delegate dlg) + private static void EmitCrc32Call(ArmEmitterContext context, string name) { OpCodeAluBinary op = (OpCodeAluBinary)context.CurrOp; Operand n = GetIntOrZR(context, op.Rn); Operand m = GetIntOrZR(context, op.Rm); - Operand d = context.Call(dlg, n, m); + Operand d = context.Call(typeof(SoftFallback).GetMethod(name), n, m); SetIntOrZR(context, op.Rd, d); } diff --git a/ARMeilleure/Instructions/InstEmitMemoryEx.cs b/ARMeilleure/Instructions/InstEmitMemoryEx.cs index 93c20cb5..7ca019de 100644 --- a/ARMeilleure/Instructions/InstEmitMemoryEx.cs +++ b/ARMeilleure/Instructions/InstEmitMemoryEx.cs @@ -23,7 +23,7 @@ namespace ARMeilleure.Instructions public static void Clrex(ArmEmitterContext context) { - context.Call(new _Void(NativeInterface.ClearExclusive)); + context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ClearExclusive))); } public static void Dmb(ArmEmitterContext context) => EmitBarrier(context); @@ -101,6 +101,7 @@ namespace ARMeilleure.Instructions SetIntOrZR(context, op.Rt, value); } } + public static void Pfrm(ArmEmitterContext context) { // Memory Prefetch, execute as no-op. diff --git a/ARMeilleure/Instructions/InstEmitMemoryEx32.cs b/ARMeilleure/Instructions/InstEmitMemoryEx32.cs index 0ab990f8..e8e660ee 100644 --- a/ARMeilleure/Instructions/InstEmitMemoryEx32.cs +++ b/ARMeilleure/Instructions/InstEmitMemoryEx32.cs @@ -13,7 +13,7 @@ namespace ARMeilleure.Instructions { public static void Clrex(ArmEmitterContext context) { - context.Call(new _Void(NativeInterface.ClearExclusive)); + context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ClearExclusive))); } public static void Dmb(ArmEmitterContext context) => EmitBarrier(context); diff --git a/ARMeilleure/Instructions/InstEmitMemoryExHelper.cs b/ARMeilleure/Instructions/InstEmitMemoryExHelper.cs index 00a5385b..059b9b6a 100644 --- a/ARMeilleure/Instructions/InstEmitMemoryExHelper.cs +++ b/ARMeilleure/Instructions/InstEmitMemoryExHelper.cs @@ -1,6 +1,6 @@ using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; -using System; +using System.Reflection; namespace ARMeilleure.Instructions { @@ -12,32 +12,32 @@ namespace ARMeilleure.Instructions bool exclusive, int size) { - Delegate fallbackMethodDlg = null; + MethodInfo info = null; if (exclusive) { switch (size) { - case 0: fallbackMethodDlg = new _U8_U64(NativeInterface.ReadByteExclusive); break; - case 1: fallbackMethodDlg = new _U16_U64(NativeInterface.ReadUInt16Exclusive); break; - case 2: fallbackMethodDlg = new _U32_U64(NativeInterface.ReadUInt32Exclusive); break; - case 3: fallbackMethodDlg = new _U64_U64(NativeInterface.ReadUInt64Exclusive); break; - case 4: fallbackMethodDlg = new _V128_U64(NativeInterface.ReadVector128Exclusive); break; + case 0: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByteExclusive)); break; + case 1: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16Exclusive)); break; + case 2: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32Exclusive)); break; + case 3: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64Exclusive)); break; + case 4: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadVector128Exclusive)); break; } } else { switch (size) { - case 0: fallbackMethodDlg = new _U8_U64(NativeInterface.ReadByte); break; - case 1: fallbackMethodDlg = new _U16_U64(NativeInterface.ReadUInt16); break; - case 2: fallbackMethodDlg = new _U32_U64(NativeInterface.ReadUInt32); break; - case 3: fallbackMethodDlg = new _U64_U64(NativeInterface.ReadUInt64); break; - case 4: fallbackMethodDlg = new _V128_U64(NativeInterface.ReadVector128); break; + case 0: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte)); break; + case 1: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16)); break; + case 2: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32)); break; + case 3: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64)); break; + case 4: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadVector128)); break; } } - return context.Call(fallbackMethodDlg, address); + return context.Call(info, address); } public static Operand EmitStoreExclusive( @@ -52,33 +52,33 @@ namespace ARMeilleure.Instructions value = context.ConvertI64ToI32(value); } - Delegate fallbackMethodDlg = null; + MethodInfo info = null; if (exclusive) { switch (size) { - case 0: fallbackMethodDlg = new _S32_U64_U8(NativeInterface.WriteByteExclusive); break; - case 1: fallbackMethodDlg = new _S32_U64_U16(NativeInterface.WriteUInt16Exclusive); break; - case 2: fallbackMethodDlg = new _S32_U64_U32(NativeInterface.WriteUInt32Exclusive); break; - case 3: fallbackMethodDlg = new _S32_U64_U64(NativeInterface.WriteUInt64Exclusive); break; - case 4: fallbackMethodDlg = new _S32_U64_V128(NativeInterface.WriteVector128Exclusive); break; + case 0: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteByteExclusive)); break; + case 1: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt16Exclusive)); break; + case 2: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt32Exclusive)); break; + case 3: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64Exclusive)); break; + case 4: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteVector128Exclusive)); break; } - return context.Call(fallbackMethodDlg, address, value); + return context.Call(info, address, value); } else { switch (size) { - case 0: fallbackMethodDlg = new _Void_U64_U8(NativeInterface.WriteByte); break; - case 1: fallbackMethodDlg = new _Void_U64_U16(NativeInterface.WriteUInt16); break; - case 2: fallbackMethodDlg = new _Void_U64_U32(NativeInterface.WriteUInt32); break; - case 3: fallbackMethodDlg = new _Void_U64_U64(NativeInterface.WriteUInt64); break; - case 4: fallbackMethodDlg = new _Void_U64_V128(NativeInterface.WriteVector128); break; + case 0: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteByte)); break; + case 1: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt16)); break; + case 2: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt32)); break; + case 3: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64)); break; + case 4: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteVector128)); break; } - context.Call(fallbackMethodDlg, address, value); + context.Call(info, address, value); return null; } diff --git a/ARMeilleure/Instructions/InstEmitMemoryHelper.cs b/ARMeilleure/Instructions/InstEmitMemoryHelper.cs index b6a4d391..18e27e5a 100644 --- a/ARMeilleure/Instructions/InstEmitMemoryHelper.cs +++ b/ARMeilleure/Instructions/InstEmitMemoryHelper.cs @@ -1,7 +1,9 @@ using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; +using ARMeilleure.Translation.PTC; using System; +using System.Reflection; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.IntermediateRepresentation.OperandHelper; @@ -144,21 +146,10 @@ namespace ARMeilleure.Instructions switch (size) { - case 0: - value = context.Load8(physAddr); - break; - - case 1: - value = context.Load16(physAddr); - break; - - case 2: - value = context.Load(OperandType.I32, physAddr); - break; - - case 3: - value = context.Load(OperandType.I64, physAddr); - break; + case 0: value = context.Load8 (physAddr); break; + case 1: value = context.Load16(physAddr); break; + case 2: value = context.Load (OperandType.I32, physAddr); break; + case 3: value = context.Load (OperandType.I64, physAddr); break; } SetInt(context, rt, value); @@ -196,25 +187,11 @@ namespace ARMeilleure.Instructions switch (size) { - case 0: - value = context.VectorInsert8(vector, context.Load8(physAddr), elem); - break; - - case 1: - value = context.VectorInsert16(vector, context.Load16(physAddr), elem); - break; - - case 2: - value = context.VectorInsert(vector, context.Load(OperandType.I32, physAddr), elem); - break; - - case 3: - value = context.VectorInsert(vector, context.Load(OperandType.I64, physAddr), elem); - break; - - case 4: - value = context.Load(OperandType.V128, physAddr); - break; + case 0: value = context.VectorInsert8 (vector, context.Load8(physAddr), elem); break; + case 1: value = context.VectorInsert16(vector, context.Load16(physAddr), elem); break; + case 2: value = context.VectorInsert (vector, context.Load(OperandType.I32, physAddr), elem); break; + case 3: value = context.VectorInsert (vector, context.Load(OperandType.I64, physAddr), elem); break; + case 4: value = context.Load (OperandType.V128, physAddr); break; } context.Copy(GetVec(rt), value); @@ -294,25 +271,11 @@ namespace ARMeilleure.Instructions switch (size) { - case 0: - context.Store8(physAddr, context.VectorExtract8(value, elem)); - break; - - case 1: - context.Store16(physAddr, context.VectorExtract16(value, elem)); - break; - - case 2: - context.Store(physAddr, context.VectorExtract(OperandType.FP32, value, elem)); - break; - - case 3: - context.Store(physAddr, context.VectorExtract(OperandType.FP64, value, elem)); - break; - - case 4: - context.Store(physAddr, value); - break; + case 0: context.Store8 (physAddr, context.VectorExtract8(value, elem)); break; + case 1: context.Store16(physAddr, context.VectorExtract16(value, elem)); break; + case 2: context.Store (physAddr, context.VectorExtract(OperandType.FP32, value, elem)); break; + case 3: context.Store (physAddr, context.VectorExtract(OperandType.FP64, value, elem)); break; + case 4: context.Store (physAddr, value); break; } context.MarkLabel(lblEnd); @@ -333,7 +296,9 @@ namespace ARMeilleure.Instructions int ptLevelSize = 1 << ptLevelBits; int ptLevelMask = ptLevelSize - 1; - Operand pte = Const(context.Memory.PageTablePointer.ToInt64()); + Operand pte = Ptc.State == PtcState.Disabled + ? Const(context.Memory.PageTablePointer.ToInt64()) + : Const(context.Memory.PageTablePointer.ToInt64(), true, Ptc.PageTablePointerIndex); int bit = PageBits; @@ -375,17 +340,17 @@ namespace ARMeilleure.Instructions private static void EmitReadIntFallback(ArmEmitterContext context, Operand address, int rt, int size) { - Delegate fallbackMethodDlg = null; + MethodInfo info = null; switch (size) { - case 0: fallbackMethodDlg = new _U8_U64 (NativeInterface.ReadByte); break; - case 1: fallbackMethodDlg = new _U16_U64(NativeInterface.ReadUInt16); break; - case 2: fallbackMethodDlg = new _U32_U64(NativeInterface.ReadUInt32); break; - case 3: fallbackMethodDlg = new _U64_U64(NativeInterface.ReadUInt64); break; + case 0: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte)); break; + case 1: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16)); break; + case 2: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32)); break; + case 3: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64)); break; } - SetInt(context, rt, context.Call(fallbackMethodDlg, address)); + SetInt(context, rt, context.Call(info, address)); } private static void EmitReadVectorFallback( @@ -396,18 +361,18 @@ namespace ARMeilleure.Instructions int elem, int size) { - Delegate fallbackMethodDlg = null; + MethodInfo info = null; switch (size) { - case 0: fallbackMethodDlg = new _U8_U64 (NativeInterface.ReadByte); break; - case 1: fallbackMethodDlg = new _U16_U64 (NativeInterface.ReadUInt16); break; - case 2: fallbackMethodDlg = new _U32_U64 (NativeInterface.ReadUInt32); break; - case 3: fallbackMethodDlg = new _U64_U64 (NativeInterface.ReadUInt64); break; - case 4: fallbackMethodDlg = new _V128_U64(NativeInterface.ReadVector128); break; + case 0: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte)); break; + case 1: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16)); break; + case 2: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32)); break; + case 3: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64)); break; + case 4: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadVector128)); break; } - Operand value = context.Call(fallbackMethodDlg, address); + Operand value = context.Call(info, address); switch (size) { @@ -422,14 +387,14 @@ namespace ARMeilleure.Instructions private static void EmitWriteIntFallback(ArmEmitterContext context, Operand address, int rt, int size) { - Delegate fallbackMethodDlg = null; + MethodInfo info = null; switch (size) { - case 0: fallbackMethodDlg = new _Void_U64_U8 (NativeInterface.WriteByte); break; - case 1: fallbackMethodDlg = new _Void_U64_U16(NativeInterface.WriteUInt16); break; - case 2: fallbackMethodDlg = new _Void_U64_U32(NativeInterface.WriteUInt32); break; - case 3: fallbackMethodDlg = new _Void_U64_U64(NativeInterface.WriteUInt64); break; + case 0: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteByte)); break; + case 1: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt16)); break; + case 2: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt32)); break; + case 3: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64)); break; } Operand value = GetInt(context, rt); @@ -439,7 +404,7 @@ namespace ARMeilleure.Instructions value = context.ConvertI64ToI32(value); } - context.Call(fallbackMethodDlg, address, value); + context.Call(info, address, value); } private static void EmitWriteVectorFallback( @@ -449,15 +414,15 @@ namespace ARMeilleure.Instructions int elem, int size) { - Delegate fallbackMethodDlg = null; + MethodInfo info = null; switch (size) { - case 0: fallbackMethodDlg = new _Void_U64_U8 (NativeInterface.WriteByte); break; - case 1: fallbackMethodDlg = new _Void_U64_U16 (NativeInterface.WriteUInt16); break; - case 2: fallbackMethodDlg = new _Void_U64_U32 (NativeInterface.WriteUInt32); break; - case 3: fallbackMethodDlg = new _Void_U64_U64 (NativeInterface.WriteUInt64); break; - case 4: fallbackMethodDlg = new _Void_U64_V128(NativeInterface.WriteVector128); break; + case 0: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteByte)); break; + case 1: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt16)); break; + case 2: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt32)); break; + case 3: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64)); break; + case 4: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteVector128)); break; } Operand value = null; @@ -466,21 +431,10 @@ namespace ARMeilleure.Instructions { switch (size) { - case 0: - value = context.VectorExtract8(GetVec(rt), elem); - break; - - case 1: - value = context.VectorExtract16(GetVec(rt), elem); - break; - - case 2: - value = context.VectorExtract(OperandType.I32, GetVec(rt), elem); - break; - - case 3: - value = context.VectorExtract(OperandType.I64, GetVec(rt), elem); - break; + case 0: value = context.VectorExtract8 (GetVec(rt), elem); break; + case 1: value = context.VectorExtract16(GetVec(rt), elem); break; + case 2: value = context.VectorExtract (OperandType.I32, GetVec(rt), elem); break; + case 3: value = context.VectorExtract (OperandType.I64, GetVec(rt), elem); break; } } else @@ -488,7 +442,7 @@ namespace ARMeilleure.Instructions value = GetVec(rt); } - context.Call(fallbackMethodDlg, address, value); + context.Call(info, address, value); } private static Operand GetInt(ArmEmitterContext context, int rt) @@ -571,4 +525,4 @@ namespace ARMeilleure.Instructions return m; } } -}
\ No newline at end of file +} diff --git a/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs b/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs index 8c2d604c..b3041aac 100644 --- a/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs +++ b/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs @@ -6,6 +6,7 @@ using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; using System; +using System.Diagnostics; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; @@ -106,7 +107,7 @@ namespace ARMeilleure.Instructions { Operand ne = EmitVectorExtractZx(context, op.Rn, index, op.Size); - Operand de = context.Call(new _U64_U64_S32(SoftFallback.CountLeadingSigns), ne, Const(eSize)); + Operand de = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingSigns)), ne, Const(eSize)); res = EmitVectorInsert(context, res, de, index, op.Size); } @@ -128,16 +129,7 @@ namespace ARMeilleure.Instructions { Operand ne = EmitVectorExtractZx(context, op.Rn, index, op.Size); - Operand de; - - if (eSize == 64) - { - de = context.CountLeadingZeros(ne); - } - else - { - de = context.Call(new _U64_U64_S32(SoftFallback.CountLeadingZeros), ne, Const(eSize)); - } + Operand de = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingZeros)), ne, Const(eSize)); res = EmitVectorInsert(context, res, de, index, op.Size); } @@ -165,7 +157,7 @@ namespace ARMeilleure.Instructions } else { - de = context.Call(new _U64_U64(SoftFallback.CountSetBits8), ne); + de = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountSetBits8)), ne); } res = EmitVectorInsert(context, res, de, index, 0); @@ -203,9 +195,9 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF(context, (op1, op2) => { - Operand res = EmitSoftFloatCall(context, SoftFloat32.FPSub, SoftFloat64.FPSub, op1, op2); + Operand res = EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub), op1, op2); - return EmitUnaryMathCall(context, MathF.Abs, Math.Abs, res); + return EmitUnaryMathCall(context, nameof(Math.Abs), res); }); } } @@ -244,9 +236,9 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF(context, (op1, op2) => { - Operand res = EmitSoftFloatCall(context, SoftFloat32.FPSub, SoftFloat64.FPSub, op1, op2); + Operand res = EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub), op1, op2); - return EmitUnaryMathCall(context, MathF.Abs, Math.Abs, res); + return EmitUnaryMathCall(context, nameof(Math.Abs), res); }); } } @@ -274,7 +266,7 @@ namespace ARMeilleure.Instructions { EmitScalarUnaryOpF(context, (op1) => { - return EmitUnaryMathCall(context, MathF.Abs, Math.Abs, op1); + return EmitUnaryMathCall(context, nameof(Math.Abs), op1); }); } } @@ -309,7 +301,7 @@ namespace ARMeilleure.Instructions { EmitVectorUnaryOpF(context, (op1) => { - return EmitUnaryMathCall(context, MathF.Abs, Math.Abs, op1); + return EmitUnaryMathCall(context, nameof(Math.Abs), op1); }); } } @@ -328,7 +320,7 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPAdd, SoftFloat64.FPAdd, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPAdd), op1, op2); }); } } @@ -347,7 +339,7 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPAdd, SoftFloat64.FPAdd, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPAdd), op1, op2); }); } } @@ -380,7 +372,7 @@ namespace ARMeilleure.Instructions Operand ne0 = context.VectorExtract(type, GetVec(op.Rn), 0); Operand ne1 = context.VectorExtract(type, GetVec(op.Rn), 1); - Operand res = EmitSoftFloatCall(context, SoftFloat32.FPAdd, SoftFloat64.FPAdd, ne0, ne1); + Operand res = EmitSoftFloatCall(context, nameof(SoftFloat32.FPAdd), ne0, ne1); context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), res, 0)); } @@ -396,7 +388,7 @@ namespace ARMeilleure.Instructions { EmitVectorPairwiseOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPAdd, SoftFloat64.FPAdd, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPAdd), op1, op2); }); } } @@ -415,7 +407,7 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPDiv, SoftFloat64.FPDiv, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPDiv), op1, op2); }); } } @@ -434,7 +426,7 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPDiv, SoftFloat64.FPDiv, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPDiv), op1, op2); }); } } @@ -469,7 +461,7 @@ namespace ARMeilleure.Instructions { EmitScalarTernaryRaOpF(context, (op1, op2, op3) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMulAdd, SoftFloat64.FPMulAdd, op1, op2, op3); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulAdd), op1, op2, op3); }); } } @@ -484,7 +476,7 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMax, SoftFloat64.FPMax, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMax), op1, op2); }); } } @@ -499,7 +491,7 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMax, SoftFloat64.FPMax, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMax), op1, op2); }); } } @@ -514,7 +506,7 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMaxNum, SoftFloat64.FPMaxNum, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMaxNum), op1, op2); }); } } @@ -529,7 +521,7 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMaxNum, SoftFloat64.FPMaxNum, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMaxNum), op1, op2); }); } } @@ -538,7 +530,7 @@ namespace ARMeilleure.Instructions { EmitVectorAcrossVectorOpF(context, (op1, op2) => { - return context.Call(new _F32_F32_F32(SoftFloat32.FPMaxNum), op1, op2); + return context.Call(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxNum)), op1, op2); }); } @@ -552,7 +544,7 @@ namespace ARMeilleure.Instructions { EmitVectorPairwiseOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMax, SoftFloat64.FPMax, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMax), op1, op2); }); } } @@ -567,7 +559,7 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMin, SoftFloat64.FPMin, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMin), op1, op2); }); } } @@ -582,7 +574,7 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMin, SoftFloat64.FPMin, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMin), op1, op2); }); } } @@ -597,7 +589,7 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMinNum, SoftFloat64.FPMinNum, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMinNum), op1, op2); }); } } @@ -612,7 +604,7 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMinNum, SoftFloat64.FPMinNum, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMinNum), op1, op2); }); } } @@ -621,7 +613,7 @@ namespace ARMeilleure.Instructions { EmitVectorAcrossVectorOpF(context, (op1, op2) => { - return context.Call(new _F32_F32_F32(SoftFloat32.FPMinNum), op1, op2); + return context.Call(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinNum)), op1, op2); }); } @@ -635,7 +627,7 @@ namespace ARMeilleure.Instructions { EmitVectorPairwiseOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMin, SoftFloat64.FPMin, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMin), op1, op2); }); } } @@ -686,7 +678,7 @@ namespace ARMeilleure.Instructions { EmitVectorTernaryOpF(context, (op1, op2, op3) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMulAdd, SoftFloat64.FPMulAdd, op1, op2, op3); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulAdd), op1, op2, op3); }); } } @@ -735,7 +727,7 @@ namespace ARMeilleure.Instructions { EmitVectorTernaryOpByElemF(context, (op1, op2, op3) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMulAdd, SoftFloat64.FPMulAdd, op1, op2, op3); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulAdd), op1, op2, op3); }); } } @@ -786,7 +778,7 @@ namespace ARMeilleure.Instructions { EmitVectorTernaryOpF(context, (op1, op2, op3) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMulSub, SoftFloat64.FPMulSub, op1, op2, op3); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulSub), op1, op2, op3); }); } } @@ -835,7 +827,7 @@ namespace ARMeilleure.Instructions { EmitVectorTernaryOpByElemF(context, (op1, op2, op3) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMulSub, SoftFloat64.FPMulSub, op1, op2, op3); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulSub), op1, op2, op3); }); } } @@ -870,7 +862,7 @@ namespace ARMeilleure.Instructions { EmitScalarTernaryRaOpF(context, (op1, op2, op3) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMulSub, SoftFloat64.FPMulSub, op1, op2, op3); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulSub), op1, op2, op3); }); } } @@ -889,7 +881,7 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMul, SoftFloat64.FPMul, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMul), op1, op2); }); } } @@ -913,7 +905,7 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMul, SoftFloat64.FPMul, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMul), op1, op2); }); } } @@ -963,7 +955,7 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpByElemF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMul, SoftFloat64.FPMul, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMul), op1, op2); }); } } @@ -972,7 +964,7 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMulX, SoftFloat64.FPMulX, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulX), op1, op2); }); } @@ -980,7 +972,7 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpByElemF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMulX, SoftFloat64.FPMulX, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulX), op1, op2); }); } @@ -988,7 +980,7 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMulX, SoftFloat64.FPMulX, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulX), op1, op2); }); } @@ -996,7 +988,7 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpByElemF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMulX, SoftFloat64.FPMulX, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulX), op1, op2); }); } @@ -1103,7 +1095,7 @@ namespace ARMeilleure.Instructions { EmitScalarTernaryRaOpF(context, (op1, op2, op3) => { - return EmitSoftFloatCall(context, SoftFloat32.FPNegMulAdd, SoftFloat64.FPNegMulAdd, op1, op2, op3); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPNegMulAdd), op1, op2, op3); }); } } @@ -1146,7 +1138,7 @@ namespace ARMeilleure.Instructions { EmitScalarTernaryRaOpF(context, (op1, op2, op3) => { - return EmitSoftFloatCall(context, SoftFloat32.FPNegMulSub, SoftFloat64.FPNegMulSub, op1, op2, op3); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPNegMulSub), op1, op2, op3); }); } } @@ -1170,7 +1162,7 @@ namespace ARMeilleure.Instructions { EmitScalarUnaryOpF(context, (op1) => { - return EmitSoftFloatCall(context, SoftFloat32.FPRecipEstimate, SoftFloat64.FPRecipEstimate, op1); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPRecipEstimate), op1); }); } } @@ -1189,7 +1181,7 @@ namespace ARMeilleure.Instructions { EmitVectorUnaryOpF(context, (op1) => { - return EmitSoftFloatCall(context, SoftFloat32.FPRecipEstimate, SoftFloat64.FPRecipEstimate, op1); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPRecipEstimate), op1); }); } } @@ -1227,7 +1219,7 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPRecipStepFused, SoftFloat64.FPRecipStepFused, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPRecipStepFused), op1, op2); }); } } @@ -1270,7 +1262,7 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPRecipStepFused, SoftFloat64.FPRecipStepFused, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPRecipStepFused), op1, op2); }); } } @@ -1279,7 +1271,7 @@ namespace ARMeilleure.Instructions { EmitScalarUnaryOpF(context, (op1) => { - return EmitSoftFloatCall(context, SoftFloat32.FPRecpX, SoftFloat64.FPRecpX, op1); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPRecpX), op1); }); } @@ -1307,11 +1299,11 @@ namespace ARMeilleure.Instructions { if (op.Size == 0) { - return context.Call(new _F32_F32(SoftFallback.RoundF), op1); + return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.RoundF)), op1); } else /* if (op.Size == 1) */ { - return context.Call(new _F64_F64(SoftFallback.Round), op1); + return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Round)), op1); } }); } @@ -1326,11 +1318,11 @@ namespace ARMeilleure.Instructions { if (sizeF == 0) { - return context.Call(new _F32_F32(SoftFallback.RoundF), op1); + return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.RoundF)), op1); } else /* if (sizeF == 1) */ { - return context.Call(new _F64_F64(SoftFallback.Round), op1); + return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Round)), op1); } }); } @@ -1345,7 +1337,7 @@ namespace ARMeilleure.Instructions { EmitScalarUnaryOpF(context, (op1) => { - return EmitUnaryMathCall(context, MathF.Floor, Math.Floor, op1); + return EmitUnaryMathCall(context, nameof(Math.Floor), op1); }); } } @@ -1360,7 +1352,7 @@ namespace ARMeilleure.Instructions { EmitVectorUnaryOpF(context, (op1) => { - return EmitUnaryMathCall(context, MathF.Floor, Math.Floor, op1); + return EmitUnaryMathCall(context, nameof(Math.Floor), op1); }); } } @@ -1405,7 +1397,7 @@ namespace ARMeilleure.Instructions { EmitScalarUnaryOpF(context, (op1) => { - return EmitUnaryMathCall(context, MathF.Ceiling, Math.Ceiling, op1); + return EmitUnaryMathCall(context, nameof(Math.Ceiling), op1); }); } } @@ -1420,7 +1412,7 @@ namespace ARMeilleure.Instructions { EmitVectorUnaryOpF(context, (op1) => { - return EmitUnaryMathCall(context, MathF.Ceiling, Math.Ceiling, op1); + return EmitUnaryMathCall(context, nameof(Math.Ceiling), op1); }); } } @@ -1433,11 +1425,11 @@ namespace ARMeilleure.Instructions { if (op.Size == 0) { - return context.Call(new _F32_F32(SoftFallback.RoundF), op1); + return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.RoundF)), op1); } else /* if (op.Size == 1) */ { - return context.Call(new _F64_F64(SoftFallback.Round), op1); + return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Round)), op1); } }); } @@ -1452,11 +1444,11 @@ namespace ARMeilleure.Instructions { if (sizeF == 0) { - return context.Call(new _F32_F32(SoftFallback.RoundF), op1); + return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.RoundF)), op1); } else /* if (sizeF == 1) */ { - return context.Call(new _F64_F64(SoftFallback.Round), op1); + return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Round)), op1); } }); } @@ -1471,7 +1463,7 @@ namespace ARMeilleure.Instructions { EmitScalarUnaryOpF(context, (op1) => { - return EmitUnaryMathCall(context, MathF.Truncate, Math.Truncate, op1); + return EmitUnaryMathCall(context, nameof(Math.Truncate), op1); }); } } @@ -1486,7 +1478,7 @@ namespace ARMeilleure.Instructions { EmitVectorUnaryOpF(context, (op1) => { - return EmitUnaryMathCall(context, MathF.Truncate, Math.Truncate, op1); + return EmitUnaryMathCall(context, nameof(Math.Truncate), op1); }); } } @@ -1505,7 +1497,7 @@ namespace ARMeilleure.Instructions { EmitScalarUnaryOpF(context, (op1) => { - return EmitSoftFloatCall(context, SoftFloat32.FPRSqrtEstimate, SoftFloat64.FPRSqrtEstimate, op1); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPRSqrtEstimate), op1); }); } } @@ -1524,7 +1516,7 @@ namespace ARMeilleure.Instructions { EmitVectorUnaryOpF(context, (op1) => { - return EmitSoftFloatCall(context, SoftFloat32.FPRSqrtEstimate, SoftFloat64.FPRSqrtEstimate, op1); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPRSqrtEstimate), op1); }); } } @@ -1566,7 +1558,7 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPRSqrtStepFused, SoftFloat64.FPRSqrtStepFused, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPRSqrtStepFused), op1, op2); }); } } @@ -1613,7 +1605,7 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPRSqrtStepFused, SoftFloat64.FPRSqrtStepFused, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPRSqrtStepFused), op1, op2); }); } } @@ -1628,7 +1620,7 @@ namespace ARMeilleure.Instructions { EmitScalarUnaryOpF(context, (op1) => { - return EmitSoftFloatCall(context, SoftFloat32.FPSqrt, SoftFloat64.FPSqrt, op1); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPSqrt), op1); }); } } @@ -1643,7 +1635,7 @@ namespace ARMeilleure.Instructions { EmitVectorUnaryOpF(context, (op1) => { - return EmitSoftFloatCall(context, SoftFloat32.FPSqrt, SoftFloat64.FPSqrt, op1); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPSqrt), op1); }); } } @@ -1662,7 +1654,7 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPSub, SoftFloat64.FPSub, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub), op1, op2); }); } } @@ -1681,7 +1673,7 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPSub, SoftFloat64.FPSub, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub), op1, op2); }); } } @@ -1690,7 +1682,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse41) { - EmitSse41Mul_AddSub(context, AddSub.Add); + EmitSse41VectorMul_AddSub(context, AddSub.Add); } else { @@ -1713,7 +1705,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse41) { - EmitSse41Mul_AddSub(context, AddSub.Subtract); + EmitSse41VectorMul_AddSub(context, AddSub.Subtract); } else { @@ -1736,7 +1728,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse41) { - EmitSse41Mul_AddSub(context, AddSub.None); + EmitSse41VectorMul_AddSub(context, AddSub.None); } else { @@ -1805,14 +1797,14 @@ namespace ARMeilleure.Instructions public static void Sabd_V(ArmEmitterContext context) { - if (Optimizations.UseSse2) + if (Optimizations.UseSse41) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; Operand n = GetVec(op.Rn); Operand m = GetVec(op.Rm); - EmitSse41Sabd(context, op, n, m, isLong: false); + EmitSse41VectorSabdOp(context, op, n, m, isLong: false); } else { @@ -1845,7 +1837,7 @@ namespace ARMeilleure.Instructions n = context.AddIntrinsic(movInst, n); m = context.AddIntrinsic(movInst, m); - EmitSse41Sabd(context, op, n, m, isLong: true); + EmitSse41VectorSabdOp(context, op, n, m, isLong: true); } else { @@ -2027,9 +2019,7 @@ namespace ARMeilleure.Instructions } else { - Delegate dlg = new _S64_S64_S64(Math.Max); - - EmitVectorBinaryOpSx(context, (op1, op2) => context.Call(dlg, op1, op2)); + EmitVectorBinaryOpSx(context, (op1, op2) => EmitMax64Op(context, op1, op2, signed: true)); } } @@ -2041,17 +2031,13 @@ namespace ARMeilleure.Instructions } else { - Delegate dlg = new _S64_S64_S64(Math.Max); - - EmitVectorPairwiseOpSx(context, (op1, op2) => context.Call(dlg, op1, op2)); + EmitVectorPairwiseOpSx(context, (op1, op2) => EmitMax64Op(context, op1, op2, signed: true)); } } public static void Smaxv_V(ArmEmitterContext context) { - Delegate dlg = new _S64_S64_S64(Math.Max); - - EmitVectorAcrossVectorOpSx(context, (op1, op2) => context.Call(dlg, op1, op2)); + EmitVectorAcrossVectorOpSx(context, (op1, op2) => EmitMax64Op(context, op1, op2, signed: true)); } public static void Smin_V(ArmEmitterContext context) @@ -2076,9 +2062,7 @@ namespace ARMeilleure.Instructions } else { - Delegate dlg = new _S64_S64_S64(Math.Min); - - EmitVectorBinaryOpSx(context, (op1, op2) => context.Call(dlg, op1, op2)); + EmitVectorBinaryOpSx(context, (op1, op2) => EmitMin64Op(context, op1, op2, signed: true)); } } @@ -2090,17 +2074,13 @@ namespace ARMeilleure.Instructions } else { - Delegate dlg = new _S64_S64_S64(Math.Min); - - EmitVectorPairwiseOpSx(context, (op1, op2) => context.Call(dlg, op1, op2)); + EmitVectorPairwiseOpSx(context, (op1, op2) => EmitMin64Op(context, op1, op2, signed: true)); } } public static void Sminv_V(ArmEmitterContext context) { - Delegate dlg = new _S64_S64_S64(Math.Min); - - EmitVectorAcrossVectorOpSx(context, (op1, op2) => context.Call(dlg, op1, op2)); + EmitVectorAcrossVectorOpSx(context, (op1, op2) => EmitMin64Op(context, op1, op2, signed: true)); } public static void Smlal_V(ArmEmitterContext context) @@ -2458,7 +2438,7 @@ namespace ARMeilleure.Instructions Operand n = GetVec(op.Rn); Operand m = GetVec(op.Rm); - EmitSse41Uabd(context, op, n, m, isLong: false); + EmitSse41VectorUabdOp(context, op, n, m, isLong: false); } else { @@ -2491,7 +2471,7 @@ namespace ARMeilleure.Instructions n = context.AddIntrinsic(movInst, n); m = context.AddIntrinsic(movInst, m); - EmitSse41Uabd(context, op, n, m, isLong: true); + EmitSse41VectorUabdOp(context, op, n, m, isLong: true); } else { @@ -2666,9 +2646,7 @@ namespace ARMeilleure.Instructions } else { - Delegate dlg = new _U64_U64_U64(Math.Max); - - EmitVectorBinaryOpZx(context, (op1, op2) => context.Call(dlg, op1, op2)); + EmitVectorBinaryOpZx(context, (op1, op2) => EmitMax64Op(context, op1, op2, signed: false)); } } @@ -2680,17 +2658,13 @@ namespace ARMeilleure.Instructions } else { - Delegate dlg = new _U64_U64_U64(Math.Max); - - EmitVectorPairwiseOpZx(context, (op1, op2) => context.Call(dlg, op1, op2)); + EmitVectorPairwiseOpZx(context, (op1, op2) => EmitMax64Op(context, op1, op2, signed: false)); } } public static void Umaxv_V(ArmEmitterContext context) { - Delegate dlg = new _U64_U64_U64(Math.Max); - - EmitVectorAcrossVectorOpZx(context, (op1, op2) => context.Call(dlg, op1, op2)); + EmitVectorAcrossVectorOpZx(context, (op1, op2) => EmitMax64Op(context, op1, op2, signed: false)); } public static void Umin_V(ArmEmitterContext context) @@ -2715,9 +2689,7 @@ namespace ARMeilleure.Instructions } else { - Delegate dlg = new _U64_U64_U64(Math.Min); - - EmitVectorBinaryOpZx(context, (op1, op2) => context.Call(dlg, op1, op2)); + EmitVectorBinaryOpZx(context, (op1, op2) => EmitMin64Op(context, op1, op2, signed: false)); } } @@ -2729,17 +2701,13 @@ namespace ARMeilleure.Instructions } else { - Delegate dlg = new _U64_U64_U64(Math.Min); - - EmitVectorPairwiseOpZx(context, (op1, op2) => context.Call(dlg, op1, op2)); + EmitVectorPairwiseOpZx(context, (op1, op2) => EmitMin64Op(context, op1, op2, signed: false)); } } public static void Uminv_V(ArmEmitterContext context) { - Delegate dlg = new _U64_U64_U64(Math.Min); - - EmitVectorAcrossVectorOpZx(context, (op1, op2) => context.Call(dlg, op1, op2)); + EmitVectorAcrossVectorOpZx(context, (op1, op2) => EmitMin64Op(context, op1, op2, signed: false)); } public static void Umlal_V(ArmEmitterContext context) @@ -3081,7 +3049,29 @@ namespace ARMeilleure.Instructions context.Copy(d, res); } - public static void EmitScalarRoundOpF(ArmEmitterContext context, FPRoundingMode roundMode) + private static Operand EmitMax64Op(ArmEmitterContext context, Operand op1, Operand op2, bool signed) + { + Debug.Assert(op1.Type == OperandType.I64 && op2.Type == OperandType.I64); + + Operand cmp = signed + ? context.ICompareGreaterOrEqual (op1, op2) + : context.ICompareGreaterOrEqualUI(op1, op2); + + return context.ConditionalSelect(cmp, op1, op2); + } + + private static Operand EmitMin64Op(ArmEmitterContext context, Operand op1, Operand op2, bool signed) + { + Debug.Assert(op1.Type == OperandType.I64 && op2.Type == OperandType.I64); + + Operand cmp = signed + ? context.ICompareLessOrEqual (op1, op2) + : context.ICompareLessOrEqualUI(op1, op2); + + return context.ConditionalSelect(cmp, op1, op2); + } + + private static void EmitScalarRoundOpF(ArmEmitterContext context, FPRoundingMode roundMode) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -3103,7 +3093,7 @@ namespace ARMeilleure.Instructions context.Copy(GetVec(op.Rd), res); } - public static void EmitVectorRoundOpF(ArmEmitterContext context, FPRoundingMode roundMode) + private static void EmitVectorRoundOpF(ArmEmitterContext context, FPRoundingMode roundMode) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -3220,14 +3210,14 @@ namespace ARMeilleure.Instructions Subtract } - private static void EmitSse41Mul_AddSub(ArmEmitterContext context, AddSub addSub) + private static void EmitSse41VectorMul_AddSub(ArmEmitterContext context, AddSub addSub) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; Operand n = GetVec(op.Rn); Operand m = GetVec(op.Rm); - Operand res = null; + Operand res; if (op.Size == 0) { @@ -3257,23 +3247,15 @@ namespace ARMeilleure.Instructions if (addSub == AddSub.Add) { - switch (op.Size) - { - case 0: res = context.AddIntrinsic(Intrinsic.X86Paddb, d, res); break; - case 1: res = context.AddIntrinsic(Intrinsic.X86Paddw, d, res); break; - case 2: res = context.AddIntrinsic(Intrinsic.X86Paddd, d, res); break; - case 3: res = context.AddIntrinsic(Intrinsic.X86Paddq, d, res); break; - } + Intrinsic addInst = X86PaddInstruction[op.Size]; + + res = context.AddIntrinsic(addInst, d, res); } else if (addSub == AddSub.Subtract) { - switch (op.Size) - { - case 0: res = context.AddIntrinsic(Intrinsic.X86Psubb, d, res); break; - case 1: res = context.AddIntrinsic(Intrinsic.X86Psubw, d, res); break; - case 2: res = context.AddIntrinsic(Intrinsic.X86Psubd, d, res); break; - case 3: res = context.AddIntrinsic(Intrinsic.X86Psubq, d, res); break; - } + Intrinsic subInst = X86PsubInstruction[op.Size]; + + res = context.AddIntrinsic(subInst, d, res); } if (op.RegisterSize == RegisterSize.Simd64) @@ -3284,7 +3266,7 @@ namespace ARMeilleure.Instructions context.Copy(d, res); } - private static void EmitSse41Sabd( + private static void EmitSse41VectorSabdOp( ArmEmitterContext context, OpCodeSimdReg op, Operand n, @@ -3317,7 +3299,7 @@ namespace ARMeilleure.Instructions context.Copy(GetVec(op.Rd), res); } - private static void EmitSse41Uabd( + private static void EmitSse41VectorUabdOp( ArmEmitterContext context, OpCodeSimdReg op, Operand n, diff --git a/ARMeilleure/Instructions/InstEmitSimdArithmetic32.cs b/ARMeilleure/Instructions/InstEmitSimdArithmetic32.cs index 19a10f68..fdc1bb46 100644 --- a/ARMeilleure/Instructions/InstEmitSimdArithmetic32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdArithmetic32.cs @@ -27,7 +27,7 @@ namespace ARMeilleure.Instructions } else { - EmitScalarUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, MathF.Abs, Math.Abs, op1)); + EmitScalarUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Abs), op1)); } } @@ -46,7 +46,7 @@ namespace ARMeilleure.Instructions } else { - EmitVectorUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, MathF.Abs, Math.Abs, op1)); + EmitVectorUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Abs), op1)); } } else @@ -74,7 +74,7 @@ namespace ARMeilleure.Instructions } else { - EmitScalarBinaryOpF32(context, (op1, op2) => EmitSoftFloatCall(context, SoftFloat32.FPAdd, SoftFloat64.FPAdd, op1, op2)); + EmitScalarBinaryOpF32(context, (op1, op2) => EmitSoftFloatCall(context, nameof(SoftFloat32.FPAdd), op1, op2)); } } @@ -90,7 +90,7 @@ namespace ARMeilleure.Instructions } else { - EmitVectorBinaryOpF32(context, (op1, op2) => EmitSoftFloatCallDefaultFpscr(context, SoftFloat32.FPAddFpscr, SoftFloat64.FPAddFpscr, op1, op2)); + EmitVectorBinaryOpF32(context, (op1, op2) => EmitSoftFloatCallDefaultFpscr(context, nameof(SoftFloat32.FPAddFpscr), op1, op2)); } } @@ -330,7 +330,7 @@ namespace ARMeilleure.Instructions { EmitScalarTernaryOpF32(context, (op1, op2, op3) => { - return EmitSoftFloatCall(context, SoftFloat32.FPNegMulAdd, SoftFloat64.FPNegMulAdd, op1, op2, op3); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPNegMulAdd), op1, op2, op3); }); } } @@ -371,7 +371,7 @@ namespace ARMeilleure.Instructions { EmitScalarTernaryOpF32(context, (op1, op2, op3) => { - return EmitSoftFloatCall(context, SoftFloat32.FPNegMulSub, SoftFloat64.FPNegMulSub, op1, op2, op3); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPNegMulSub), op1, op2, op3); }); } } @@ -423,7 +423,7 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF32(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPDiv, SoftFloat64.FPDiv, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPDiv), op1, op2); }); } } @@ -436,7 +436,7 @@ namespace ARMeilleure.Instructions } else { - EmitScalarBinaryOpF32(context, (op1, op2) => EmitSoftFloatCall(context, SoftFloat32.FPMaxNum, SoftFloat64.FPMaxNum, op1, op2)); + EmitScalarBinaryOpF32(context, (op1, op2) => EmitSoftFloatCall(context, nameof(SoftFloat32.FPMaxNum), op1, op2)); } } @@ -448,7 +448,7 @@ namespace ARMeilleure.Instructions } else { - EmitVectorBinaryOpSx32(context, (op1, op2) => EmitSoftFloatCallDefaultFpscr(context, SoftFloat32.FPMaxNumFpscr, SoftFloat64.FPMaxNumFpscr, op1, op2)); + EmitVectorBinaryOpSx32(context, (op1, op2) => EmitSoftFloatCallDefaultFpscr(context, nameof(SoftFloat32.FPMaxNumFpscr), op1, op2)); } } @@ -460,7 +460,7 @@ namespace ARMeilleure.Instructions } else { - EmitScalarBinaryOpF32(context, (op1, op2) => EmitSoftFloatCall(context, SoftFloat32.FPMinNum, SoftFloat64.FPMinNum, op1, op2)); + EmitScalarBinaryOpF32(context, (op1, op2) => EmitSoftFloatCall(context, nameof(SoftFloat32.FPMinNum), op1, op2)); } } @@ -472,7 +472,7 @@ namespace ARMeilleure.Instructions } else { - EmitVectorBinaryOpSx32(context, (op1, op2) => EmitSoftFloatCallDefaultFpscr(context, SoftFloat32.FPMinNumFpscr, SoftFloat64.FPMinNumFpscr, op1, op2)); + EmitVectorBinaryOpSx32(context, (op1, op2) => EmitSoftFloatCallDefaultFpscr(context, nameof(SoftFloat32.FPMinNumFpscr), op1, op2)); } } @@ -486,7 +486,7 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF32(context, (op1, op2) => { - return EmitSoftFloatCallDefaultFpscr(context, SoftFloat32.FPMaxFpscr, SoftFloat64.FPMaxFpscr, op1, op2); + return EmitSoftFloatCallDefaultFpscr(context, nameof(SoftFloat32.FPMaxFpscr), op1, op2); }); } } @@ -529,7 +529,7 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF32(context, (op1, op2) => { - return EmitSoftFloatCallDefaultFpscr(context, SoftFloat32.FPMinFpscr, SoftFloat64.FPMinFpscr, op1, op2); + return EmitSoftFloatCallDefaultFpscr(context, nameof(SoftFloat32.FPMinFpscr), op1, op2); }); } } @@ -579,7 +579,7 @@ namespace ARMeilleure.Instructions { EmitScalarTernaryOpF32(context, (op1, op2, op3) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMulAdd, SoftFloat64.FPMulAdd, op1, op2, op3); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulAdd), op1, op2, op3); }); } } @@ -598,7 +598,7 @@ namespace ARMeilleure.Instructions { EmitVectorTernaryOpF32(context, (op1, op2, op3) => { - return EmitSoftFloatCallDefaultFpscr(context, SoftFloat32.FPMulAddFpscr, SoftFloat64.FPMulAddFpscr, op1, op2, op3); + return EmitSoftFloatCallDefaultFpscr(context, nameof(SoftFloat32.FPMulAddFpscr), op1, op2, op3); }); } } @@ -624,7 +624,7 @@ namespace ARMeilleure.Instructions } else { - EmitVectorsByScalarOpF32(context, (op1, op2, op3) => EmitSoftFloatCallDefaultFpscr(context, SoftFloat32.FPMulAddFpscr, SoftFloat64.FPMulAddFpscr, op1, op2, op3)); + EmitVectorsByScalarOpF32(context, (op1, op2, op3) => EmitSoftFloatCallDefaultFpscr(context, nameof(SoftFloat32.FPMulAddFpscr), op1, op2, op3)); } } else @@ -650,7 +650,7 @@ namespace ARMeilleure.Instructions { EmitScalarTernaryOpF32(context, (op1, op2, op3) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMulSub, SoftFloat64.FPMulSub, op1, op2, op3); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulSub), op1, op2, op3); }); } } @@ -669,7 +669,7 @@ namespace ARMeilleure.Instructions { EmitVectorTernaryOpF32(context, (op1, op2, op3) => { - return EmitSoftFloatCallDefaultFpscr(context, SoftFloat32.FPMulSubFpscr, SoftFloat64.FPMulSubFpscr, op1, op2, op3); + return EmitSoftFloatCallDefaultFpscr(context, nameof(SoftFloat32.FPMulSubFpscr), op1, op2, op3); }); } } @@ -695,7 +695,7 @@ namespace ARMeilleure.Instructions } else { - EmitVectorsByScalarOpF32(context, (op1, op2, op3) => EmitSoftFloatCallDefaultFpscr(context, SoftFloat32.FPMulSubFpscr, SoftFloat64.FPMulSubFpscr, op1, op2, op3)); + EmitVectorsByScalarOpF32(context, (op1, op2, op3) => EmitSoftFloatCallDefaultFpscr(context, nameof(SoftFloat32.FPMulSubFpscr), op1, op2, op3)); } } else @@ -725,7 +725,7 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF32(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPMul, SoftFloat64.FPMul, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMul), op1, op2); }); } } @@ -744,7 +744,7 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF32(context, (op1, op2) => { - return EmitSoftFloatCallDefaultFpscr(context, SoftFloat32.FPMulFpscr, SoftFloat64.FPMulFpscr, op1, op2); + return EmitSoftFloatCallDefaultFpscr(context, nameof(SoftFloat32.FPMulFpscr), op1, op2); }); } } @@ -779,7 +779,7 @@ namespace ARMeilleure.Instructions } else { - EmitVectorByScalarOpF32(context, (op1, op2) => EmitSoftFloatCallDefaultFpscr(context, SoftFloat32.FPMulFpscr, SoftFloat64.FPMulFpscr, op1, op2)); + EmitVectorByScalarOpF32(context, (op1, op2) => EmitSoftFloatCallDefaultFpscr(context, nameof(SoftFloat32.FPMulFpscr), op1, op2)); } } else @@ -938,7 +938,7 @@ namespace ARMeilleure.Instructions { EmitVectorUnaryOpF32(context, (op1) => { - return EmitSoftFloatCallDefaultFpscr(context, SoftFloat32.FPRecipEstimateFpscr, SoftFloat64.FPRecipEstimateFpscr, op1); + return EmitSoftFloatCallDefaultFpscr(context, nameof(SoftFloat32.FPRecipEstimateFpscr), op1); }); } } @@ -980,7 +980,7 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF32(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPRecipStep, SoftFloat64.FPRecipStep, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPRecipStep), op1, op2); }); } } @@ -1001,7 +1001,7 @@ namespace ARMeilleure.Instructions { EmitVectorUnaryOpF32(context, (op1) => { - return EmitSoftFloatCallDefaultFpscr(context, SoftFloat32.FPRSqrtEstimateFpscr, SoftFloat64.FPRSqrtEstimateFpscr, op1); + return EmitSoftFloatCallDefaultFpscr(context, nameof(SoftFloat32.FPRSqrtEstimateFpscr), op1); }); } } @@ -1047,7 +1047,7 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF32(context, (op1, op2) => { - return EmitSoftFloatCall(context, SoftFloat32.FPRSqrtStep, SoftFloat64.FPRSqrtStep, op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPRSqrtStep), op1, op2); }); } } @@ -1089,7 +1089,7 @@ namespace ARMeilleure.Instructions { EmitScalarUnaryOpF32(context, (op1) => { - return EmitSoftFloatCall(context, SoftFloat32.FPSqrt, SoftFloat64.FPSqrt, op1); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPSqrt), op1); }); } } diff --git a/ARMeilleure/Instructions/InstEmitSimdCmp.cs b/ARMeilleure/Instructions/InstEmitSimdCmp.cs index d11adf19..ff97084b 100644 --- a/ARMeilleure/Instructions/InstEmitSimdCmp.cs +++ b/ARMeilleure/Instructions/InstEmitSimdCmp.cs @@ -288,49 +288,49 @@ namespace ARMeilleure.Instructions public static void Facge_S(ArmEmitterContext context) { - if (Optimizations.FastFP && Optimizations.UseSse2) + if (Optimizations.FastFP && Optimizations.UseAvx) { - EmitSse2CmpOpF(context, CmpCondition.GreaterThanOrEqual, scalar: true, absolute: true); + EmitSse2OrAvxCmpOpF(context, CmpCondition.GreaterThanOrEqual, scalar: true, absolute: true); } else { - EmitCmpOpF(context, SoftFloat32.FPCompareGE, SoftFloat64.FPCompareGE, scalar: true, absolute: true); + EmitCmpOpF(context, nameof(SoftFloat32.FPCompareGE), scalar: true, absolute: true); } } public static void Facge_V(ArmEmitterContext context) { - if (Optimizations.FastFP && Optimizations.UseSse2) + if (Optimizations.FastFP && Optimizations.UseAvx) { - EmitSse2CmpOpF(context, CmpCondition.GreaterThanOrEqual, scalar: false, absolute: true); + EmitSse2OrAvxCmpOpF(context, CmpCondition.GreaterThanOrEqual, scalar: false, absolute: true); } else { - EmitCmpOpF(context, SoftFloat32.FPCompareGE, SoftFloat64.FPCompareGE, scalar: false, absolute: true); + EmitCmpOpF(context, nameof(SoftFloat32.FPCompareGE), scalar: false, absolute: true); } } public static void Facgt_S(ArmEmitterContext context) { - if (Optimizations.FastFP && Optimizations.UseSse2) + if (Optimizations.FastFP && Optimizations.UseAvx) { - EmitSse2CmpOpF(context, CmpCondition.GreaterThan, scalar: true, absolute: true); + EmitSse2OrAvxCmpOpF(context, CmpCondition.GreaterThan, scalar: true, absolute: true); } else { - EmitCmpOpF(context, SoftFloat32.FPCompareGT, SoftFloat64.FPCompareGT, scalar: true, absolute: true); + EmitCmpOpF(context, nameof(SoftFloat32.FPCompareGT), scalar: true, absolute: true); } } public static void Facgt_V(ArmEmitterContext context) { - if (Optimizations.FastFP && Optimizations.UseSse2) + if (Optimizations.FastFP && Optimizations.UseAvx) { - EmitSse2CmpOpF(context, CmpCondition.GreaterThan, scalar: false, absolute: true); + EmitSse2OrAvxCmpOpF(context, CmpCondition.GreaterThan, scalar: false, absolute: true); } else { - EmitCmpOpF(context, SoftFloat32.FPCompareGT, SoftFloat64.FPCompareGT, scalar: false, absolute: true); + EmitCmpOpF(context, nameof(SoftFloat32.FPCompareGT), scalar: false, absolute: true); } } @@ -348,11 +348,11 @@ namespace ARMeilleure.Instructions { if (Optimizations.FastFP && Optimizations.UseSse2) { - EmitSse2CmpOpF(context, CmpCondition.Equal, scalar: true); + EmitSse2OrAvxCmpOpF(context, CmpCondition.Equal, scalar: true); } else { - EmitCmpOpF(context, SoftFloat32.FPCompareEQ, SoftFloat64.FPCompareEQ, scalar: true); + EmitCmpOpF(context, nameof(SoftFloat32.FPCompareEQ), scalar: true); } } @@ -360,11 +360,11 @@ namespace ARMeilleure.Instructions { if (Optimizations.FastFP && Optimizations.UseSse2) { - EmitSse2CmpOpF(context, CmpCondition.Equal, scalar: false); + EmitSse2OrAvxCmpOpF(context, CmpCondition.Equal, scalar: false); } else { - EmitCmpOpF(context, SoftFloat32.FPCompareEQ, SoftFloat64.FPCompareEQ, scalar: false); + EmitCmpOpF(context, nameof(SoftFloat32.FPCompareEQ), scalar: false); } } @@ -372,11 +372,11 @@ namespace ARMeilleure.Instructions { if (Optimizations.FastFP && Optimizations.UseAvx) { - EmitSse2CmpOpF(context, CmpCondition.GreaterThanOrEqual, scalar: true); + EmitSse2OrAvxCmpOpF(context, CmpCondition.GreaterThanOrEqual, scalar: true); } else { - EmitCmpOpF(context, SoftFloat32.FPCompareGE, SoftFloat64.FPCompareGE, scalar: true); + EmitCmpOpF(context, nameof(SoftFloat32.FPCompareGE), scalar: true); } } @@ -384,11 +384,11 @@ namespace ARMeilleure.Instructions { if (Optimizations.FastFP && Optimizations.UseAvx) { - EmitSse2CmpOpF(context, CmpCondition.GreaterThanOrEqual, scalar: false); + EmitSse2OrAvxCmpOpF(context, CmpCondition.GreaterThanOrEqual, scalar: false); } else { - EmitCmpOpF(context, SoftFloat32.FPCompareGE, SoftFloat64.FPCompareGE, scalar: false); + EmitCmpOpF(context, nameof(SoftFloat32.FPCompareGE), scalar: false); } } @@ -396,11 +396,11 @@ namespace ARMeilleure.Instructions { if (Optimizations.FastFP && Optimizations.UseAvx) { - EmitSse2CmpOpF(context, CmpCondition.GreaterThan, scalar: true); + EmitSse2OrAvxCmpOpF(context, CmpCondition.GreaterThan, scalar: true); } else { - EmitCmpOpF(context, SoftFloat32.FPCompareGT, SoftFloat64.FPCompareGT, scalar: true); + EmitCmpOpF(context, nameof(SoftFloat32.FPCompareGT), scalar: true); } } @@ -408,11 +408,11 @@ namespace ARMeilleure.Instructions { if (Optimizations.FastFP && Optimizations.UseAvx) { - EmitSse2CmpOpF(context, CmpCondition.GreaterThan, scalar: false); + EmitSse2OrAvxCmpOpF(context, CmpCondition.GreaterThan, scalar: false); } else { - EmitCmpOpF(context, SoftFloat32.FPCompareGT, SoftFloat64.FPCompareGT, scalar: false); + EmitCmpOpF(context, nameof(SoftFloat32.FPCompareGT), scalar: false); } } @@ -420,11 +420,11 @@ namespace ARMeilleure.Instructions { if (Optimizations.FastFP && Optimizations.UseSse2) { - EmitSse2CmpOpF(context, CmpCondition.LessThanOrEqual, scalar: true); + EmitSse2OrAvxCmpOpF(context, CmpCondition.LessThanOrEqual, scalar: true); } else { - EmitCmpOpF(context, SoftFloat32.FPCompareLE, SoftFloat64.FPCompareLE, scalar: true); + EmitCmpOpF(context, nameof(SoftFloat32.FPCompareLE), scalar: true); } } @@ -432,11 +432,11 @@ namespace ARMeilleure.Instructions { if (Optimizations.FastFP && Optimizations.UseSse2) { - EmitSse2CmpOpF(context, CmpCondition.LessThanOrEqual, scalar: false); + EmitSse2OrAvxCmpOpF(context, CmpCondition.LessThanOrEqual, scalar: false); } else { - EmitCmpOpF(context, SoftFloat32.FPCompareLE, SoftFloat64.FPCompareLE, scalar: false); + EmitCmpOpF(context, nameof(SoftFloat32.FPCompareLE), scalar: false); } } @@ -444,11 +444,11 @@ namespace ARMeilleure.Instructions { if (Optimizations.FastFP && Optimizations.UseSse2) { - EmitSse2CmpOpF(context, CmpCondition.LessThan, scalar: true); + EmitSse2OrAvxCmpOpF(context, CmpCondition.LessThan, scalar: true); } else { - EmitCmpOpF(context, SoftFloat32.FPCompareLT, SoftFloat64.FPCompareLT, scalar: true); + EmitCmpOpF(context, nameof(SoftFloat32.FPCompareLT), scalar: true); } } @@ -456,11 +456,11 @@ namespace ARMeilleure.Instructions { if (Optimizations.FastFP && Optimizations.UseSse2) { - EmitSse2CmpOpF(context, CmpCondition.LessThan, scalar: false); + EmitSse2OrAvxCmpOpF(context, CmpCondition.LessThan, scalar: false); } else { - EmitCmpOpF(context, SoftFloat32.FPCompareLT, SoftFloat64.FPCompareLT, scalar: false); + EmitCmpOpF(context, nameof(SoftFloat32.FPCompareLT), scalar: false); } } @@ -592,11 +592,7 @@ namespace ARMeilleure.Instructions me = context.VectorExtract(type, GetVec(op.Rm), 0); } - Delegate dlg = op.Size != 0 - ? (Delegate)new _S32_F64_F64_Bool(SoftFloat64.FPCompare) - : (Delegate)new _S32_F32_F32_Bool(SoftFloat32.FPCompare); - - Operand nzcv = context.Call(dlg, ne, me, Const(signalNaNs)); + Operand nzcv = EmitSoftFloatCall(context, nameof(SoftFloat32.FPCompare), ne, me, Const(signalNaNs)); EmitSetNzcv(context, nzcv); } @@ -683,12 +679,7 @@ namespace ARMeilleure.Instructions context.Copy(GetVec(op.Rd), res); } - private static void EmitCmpOpF( - ArmEmitterContext context, - _F32_F32_F32 f32, - _F64_F64_F64 f64, - bool scalar, - bool absolute = false) + private static void EmitCmpOpF(ArmEmitterContext context, string name, bool scalar, bool absolute = false) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -716,11 +707,11 @@ namespace ARMeilleure.Instructions if (absolute) { - ne = EmitUnaryMathCall(context, MathF.Abs, Math.Abs, ne); - me = EmitUnaryMathCall(context, MathF.Abs, Math.Abs, me); + ne = EmitUnaryMathCall(context, nameof(Math.Abs), ne); + me = EmitUnaryMathCall(context, nameof(Math.Abs), me); } - Operand e = EmitSoftFloatCall(context, f32, f64, ne, me); + Operand e = EmitSoftFloatCall(context, name, ne, me); res = context.VectorInsert(res, e, index); } @@ -728,7 +719,7 @@ namespace ARMeilleure.Instructions context.Copy(GetVec(op.Rd), res); } - private static void EmitSse2CmpOpF(ArmEmitterContext context, CmpCondition cond, bool scalar, bool absolute = false) + private static void EmitSse2OrAvxCmpOpF(ArmEmitterContext context, CmpCondition cond, bool scalar, bool absolute = false) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; diff --git a/ARMeilleure/Instructions/InstEmitSimdCmp32.cs b/ARMeilleure/Instructions/InstEmitSimdCmp32.cs index a4f64ad6..db925053 100644 --- a/ARMeilleure/Instructions/InstEmitSimdCmp32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdCmp32.cs @@ -3,6 +3,7 @@ using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; using System; +using System.Reflection; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; @@ -19,11 +20,11 @@ namespace ARMeilleure.Instructions { if (Optimizations.FastFP && Optimizations.UseSse2) { - EmitSse2CmpOpF32(context, CmpCondition.Equal, false); + EmitSse2OrAvxCmpOpF32(context, CmpCondition.Equal, false); } else { - EmitCmpOpF32(context, SoftFloat32.FPCompareEQFpscr, SoftFloat64.FPCompareEQFpscr, false); + EmitCmpOpF32(context, nameof(SoftFloat32.FPCompareEQFpscr), false); } } @@ -40,11 +41,11 @@ namespace ARMeilleure.Instructions { if (Optimizations.FastFP && Optimizations.UseSse2) { - EmitSse2CmpOpF32(context, CmpCondition.Equal, true); + EmitSse2OrAvxCmpOpF32(context, CmpCondition.Equal, true); } else { - EmitCmpOpF32(context, SoftFloat32.FPCompareEQFpscr, SoftFloat64.FPCompareEQFpscr, true); + EmitCmpOpF32(context, nameof(SoftFloat32.FPCompareEQFpscr), true); } } else @@ -55,13 +56,13 @@ namespace ARMeilleure.Instructions public static void Vcge_V(ArmEmitterContext context) { - if (Optimizations.FastFP && Optimizations.UseSse2) + if (Optimizations.FastFP && Optimizations.UseAvx) { - EmitSse2CmpOpF32(context, CmpCondition.GreaterThanOrEqual, false); + EmitSse2OrAvxCmpOpF32(context, CmpCondition.GreaterThanOrEqual, false); } else { - EmitCmpOpF32(context, SoftFloat32.FPCompareGEFpscr, SoftFloat64.FPCompareGEFpscr, false); + EmitCmpOpF32(context, nameof(SoftFloat32.FPCompareGEFpscr), false); } } @@ -78,15 +79,15 @@ namespace ARMeilleure.Instructions if (op.F) { - if (Optimizations.FastFP && Optimizations.UseSse2) + if (Optimizations.FastFP && Optimizations.UseAvx) { - EmitSse2CmpOpF32(context, CmpCondition.GreaterThanOrEqual, true); + EmitSse2OrAvxCmpOpF32(context, CmpCondition.GreaterThanOrEqual, true); } else { - EmitCmpOpF32(context, SoftFloat32.FPCompareGEFpscr, SoftFloat64.FPCompareGEFpscr, true); + EmitCmpOpF32(context, nameof(SoftFloat32.FPCompareGEFpscr), true); } - } + } else { EmitCmpOpI32(context, context.ICompareGreaterOrEqual, context.ICompareGreaterOrEqualUI, true, true); @@ -95,13 +96,13 @@ namespace ARMeilleure.Instructions public static void Vcgt_V(ArmEmitterContext context) { - if (Optimizations.FastFP && Optimizations.UseSse2) + if (Optimizations.FastFP && Optimizations.UseAvx) { - EmitSse2CmpOpF32(context, CmpCondition.GreaterThan, false); + EmitSse2OrAvxCmpOpF32(context, CmpCondition.GreaterThan, false); } else { - EmitCmpOpF32(context, SoftFloat32.FPCompareGTFpscr, SoftFloat64.FPCompareGTFpscr, false); + EmitCmpOpF32(context, nameof(SoftFloat32.FPCompareGTFpscr), false); } } @@ -118,13 +119,13 @@ namespace ARMeilleure.Instructions if (op.F) { - if (Optimizations.FastFP && Optimizations.UseSse2) + if (Optimizations.FastFP && Optimizations.UseAvx) { - EmitSse2CmpOpF32(context, CmpCondition.GreaterThan, true); + EmitSse2OrAvxCmpOpF32(context, CmpCondition.GreaterThan, true); } else { - EmitCmpOpF32(context, SoftFloat32.FPCompareGTFpscr, SoftFloat64.FPCompareGTFpscr, true); + EmitCmpOpF32(context, nameof(SoftFloat32.FPCompareGTFpscr), true); } } else @@ -141,11 +142,11 @@ namespace ARMeilleure.Instructions { if (Optimizations.FastFP && Optimizations.UseSse2) { - EmitSse2CmpOpF32(context, CmpCondition.LessThanOrEqual, true); + EmitSse2OrAvxCmpOpF32(context, CmpCondition.LessThanOrEqual, true); } else { - EmitCmpOpF32(context, SoftFloat32.FPCompareLEFpscr, SoftFloat64.FPCompareLEFpscr, true); + EmitCmpOpF32(context, nameof(SoftFloat32.FPCompareLEFpscr), true); } } else @@ -162,11 +163,11 @@ namespace ARMeilleure.Instructions { if (Optimizations.FastFP && Optimizations.UseSse2) { - EmitSse2CmpOpF32(context, CmpCondition.LessThan, true); + EmitSse2OrAvxCmpOpF32(context, CmpCondition.LessThan, true); } else { - EmitCmpOpF32(context, SoftFloat32.FPCompareLTFpscr, SoftFloat64.FPCompareLTFpscr, true); + EmitCmpOpF32(context, nameof(SoftFloat32.FPCompareLTFpscr), true); } } else @@ -175,11 +176,7 @@ namespace ARMeilleure.Instructions } } - private static void EmitCmpOpF32( - ArmEmitterContext context, - _F32_F32_F32_Bool f32, - _F64_F64_F64_Bool f64, - bool zero) + private static void EmitCmpOpF32(ArmEmitterContext context, string name, bool zero) { Operand one = Const(1); if (zero) @@ -190,11 +187,11 @@ namespace ARMeilleure.Instructions if (type == OperandType.FP64) { - return context.Call(f64, m, ConstF(0.0), one); + return context.Call(typeof(SoftFloat64).GetMethod(name), m, ConstF(0.0d), one); } else { - return context.Call(f32, m, ConstF(0.0f), one); + return context.Call(typeof(SoftFloat32).GetMethod(name), m, ConstF(0.0f), one); } }); } @@ -206,11 +203,11 @@ namespace ARMeilleure.Instructions if (type == OperandType.FP64) { - return context.Call(f64, n, m, one); + return context.Call(typeof(SoftFloat64).GetMethod(name), n, m, one); } else { - return context.Call(f32, n, m, one); + return context.Call(typeof(SoftFloat32).GetMethod(name), n, m, one); } }); } @@ -241,7 +238,7 @@ namespace ARMeilleure.Instructions return ZerosOrOnes(context, signedOp(m, zeroV), type); }); - } + } else { EmitVectorUnaryOpZx32(context, (m) => @@ -258,7 +255,7 @@ namespace ARMeilleure.Instructions if (signed) { EmitVectorBinaryOpSx32(context, (n, m) => ZerosOrOnes(context, signedOp(n, m), n.Type)); - } + } else { EmitVectorBinaryOpZx32(context, (n, m) => ZerosOrOnes(context, unsignedOp(n, m), n.Type)); @@ -351,11 +348,11 @@ namespace ARMeilleure.Instructions me = ExtractScalar(context, type, op.Vm); } - Delegate dlg = sizeF != 0 - ? (Delegate)new _S32_F64_F64_Bool(SoftFloat64.FPCompare) - : (Delegate)new _S32_F32_F32_Bool(SoftFloat32.FPCompare); + MethodInfo info = sizeF != 0 + ? typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompare)) + : typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompare)); - Operand nzcv = context.Call(dlg, ne, me, Const(signalNaNs)); + Operand nzcv = context.Call(info, ne, me, Const(signalNaNs)); EmitSetFPSCRFlags(context, nzcv); } @@ -389,7 +386,7 @@ namespace ARMeilleure.Instructions SetFpFlag(context, FPState.NFlag, n); } - private static void EmitSse2CmpOpF32(ArmEmitterContext context, CmpCondition cond, bool zero) + private static void EmitSse2OrAvxCmpOpF32(ArmEmitterContext context, CmpCondition cond, bool zero) { OpCode32Simd op = (OpCode32Simd)context.CurrOp; diff --git a/ARMeilleure/Instructions/InstEmitSimdCrypto.cs b/ARMeilleure/Instructions/InstEmitSimdCrypto.cs index 5b470567..db24e029 100644 --- a/ARMeilleure/Instructions/InstEmitSimdCrypto.cs +++ b/ARMeilleure/Instructions/InstEmitSimdCrypto.cs @@ -16,13 +16,14 @@ namespace ARMeilleure.Instructions Operand n = GetVec(op.Rn); Operand res; + if (Optimizations.UseAesni) { res = context.AddIntrinsic(Intrinsic.X86Aesdeclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero()); } else { - res = context.Call(new _V128_V128_V128(SoftFallback.Decrypt), d, n); + res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Decrypt)), d, n); } context.Copy(d, res); @@ -36,13 +37,14 @@ namespace ARMeilleure.Instructions Operand n = GetVec(op.Rn); Operand res; + if (Optimizations.UseAesni) { res = context.AddIntrinsic(Intrinsic.X86Aesenclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero()); } else { - res = context.Call(new _V128_V128_V128(SoftFallback.Encrypt), d, n); + res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Encrypt)), d, n); } context.Copy(d, res); @@ -55,13 +57,14 @@ namespace ARMeilleure.Instructions Operand n = GetVec(op.Rn); Operand res; + if (Optimizations.UseAesni) { res = context.AddIntrinsic(Intrinsic.X86Aesimc, n); } else { - res = context.Call(new _V128_V128(SoftFallback.InverseMixColumns), n); + res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.InverseMixColumns)), n); } context.Copy(GetVec(op.Rd), res); @@ -74,6 +77,7 @@ namespace ARMeilleure.Instructions Operand n = GetVec(op.Rn); Operand res; + if (Optimizations.UseAesni) { Operand roundKey = context.VectorZero(); @@ -86,7 +90,7 @@ namespace ARMeilleure.Instructions } else { - res = context.Call(new _V128_V128(SoftFallback.MixColumns), n); + res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.MixColumns)), n); } context.Copy(GetVec(op.Rd), res); diff --git a/ARMeilleure/Instructions/InstEmitSimdCrypto32.cs b/ARMeilleure/Instructions/InstEmitSimdCrypto32.cs index f62fd307..f713a388 100644 --- a/ARMeilleure/Instructions/InstEmitSimdCrypto32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdCrypto32.cs @@ -16,13 +16,14 @@ namespace ARMeilleure.Instructions Operand n = GetVecA32(op.Qm); Operand res; + if (Optimizations.UseAesni) { res = context.AddIntrinsic(Intrinsic.X86Aesdeclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero()); } else { - res = context.Call(new _V128_V128_V128(SoftFallback.Decrypt), d, n); + res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Decrypt)), d, n); } context.Copy(d, res); @@ -36,13 +37,14 @@ namespace ARMeilleure.Instructions Operand n = GetVecA32(op.Qm); Operand res; + if (Optimizations.UseAesni) { res = context.AddIntrinsic(Intrinsic.X86Aesenclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero()); } else { - res = context.Call(new _V128_V128_V128(SoftFallback.Encrypt), d, n); + res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Encrypt)), d, n); } context.Copy(d, res); @@ -55,13 +57,14 @@ namespace ARMeilleure.Instructions Operand n = GetVecA32(op.Qm); Operand res; + if (Optimizations.UseAesni) { res = context.AddIntrinsic(Intrinsic.X86Aesimc, n); } else { - res = context.Call(new _V128_V128(SoftFallback.InverseMixColumns), n); + res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.InverseMixColumns)), n); } context.Copy(GetVecA32(op.Qd), res); @@ -74,6 +77,7 @@ namespace ARMeilleure.Instructions Operand n = GetVecA32(op.Qm); Operand res; + if (Optimizations.UseAesni) { Operand roundKey = context.VectorZero(); @@ -86,7 +90,7 @@ namespace ARMeilleure.Instructions } else { - res = context.Call(new _V128_V128(SoftFallback.MixColumns), n); + res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.MixColumns)), n); } context.Copy(GetVecA32(op.Qd), res); diff --git a/ARMeilleure/Instructions/InstEmitSimdCvt.cs b/ARMeilleure/Instructions/InstEmitSimdCvt.cs index 49f0365b..9696fa28 100644 --- a/ARMeilleure/Instructions/InstEmitSimdCvt.cs +++ b/ARMeilleure/Instructions/InstEmitSimdCvt.cs @@ -4,6 +4,7 @@ using ARMeilleure.State; using ARMeilleure.Translation; using System; using System.Diagnostics; +using System.Reflection; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; @@ -61,9 +62,7 @@ namespace ARMeilleure.Instructions { Operand ne = context.VectorExtract(OperandType.FP32, GetVec(op.Rn), 0); - Delegate dlg = new _U16_F32(SoftFloat32_16.FPConvert); - - Operand res = context.Call(dlg, ne); + Operand res = context.Call(typeof(SoftFloat32_16).GetMethod(nameof(SoftFloat32_16.FPConvert)), ne); res = context.ZeroExtend16(OperandType.I64, res); @@ -73,9 +72,7 @@ namespace ARMeilleure.Instructions { Operand ne = EmitVectorExtractZx(context, op.Rn, 0, 1); - Delegate dlg = new _F32_U16(SoftFloat16_32.FPConvert); - - Operand res = context.Call(dlg, ne); + Operand res = context.Call(typeof(SoftFloat16_32).GetMethod(nameof(SoftFloat16_32.FPConvert)), ne); context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), res, 0)); } @@ -161,9 +158,7 @@ namespace ARMeilleure.Instructions { Operand ne = EmitVectorExtractZx(context, op.Rn, part + index, 1); - Delegate dlg = new _F32_U16(SoftFloat16_32.FPConvert); - - Operand e = context.Call(dlg, ne); + Operand e = context.Call(typeof(SoftFloat16_32).GetMethod(nameof(SoftFloat16_32.FPConvert)), ne); res = context.VectorInsert(res, e, index); } @@ -189,7 +184,7 @@ namespace ARMeilleure.Instructions } else { - EmitFcvt_s_Gp(context, (op1) => EmitUnaryMathCall(context, MathF.Floor, Math.Floor, op1)); + EmitFcvt_s_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Floor), op1)); } } @@ -201,7 +196,7 @@ namespace ARMeilleure.Instructions } else { - EmitFcvt_u_Gp(context, (op1) => EmitUnaryMathCall(context, MathF.Floor, Math.Floor, op1)); + EmitFcvt_u_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Floor), op1)); } } @@ -247,9 +242,7 @@ namespace ARMeilleure.Instructions if (sizeF == 0) { - Delegate dlg = new _U16_F32(SoftFloat32_16.FPConvert); - - Operand e = context.Call(dlg, ne); + Operand e = context.Call(typeof(SoftFloat32_16).GetMethod(nameof(SoftFloat32_16.FPConvert)), ne); e = context.ZeroExtend16(OperandType.I64, e); @@ -271,7 +264,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse41) { - EmitSse41Fcvts(context, FPRoundingMode.ToNearest, scalar: true); + EmitSse41FcvtsOpF(context, FPRoundingMode.ToNearest, scalar: true); } else { @@ -283,7 +276,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse41) { - EmitSse41Fcvts(context, FPRoundingMode.ToNearest, scalar: false); + EmitSse41FcvtsOpF(context, FPRoundingMode.ToNearest, scalar: false); } else { @@ -295,7 +288,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse41) { - EmitSse41Fcvtu(context, FPRoundingMode.ToNearest, scalar: true); + EmitSse41FcvtuOpF(context, FPRoundingMode.ToNearest, scalar: true); } else { @@ -307,7 +300,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse41) { - EmitSse41Fcvtu(context, FPRoundingMode.ToNearest, scalar: false); + EmitSse41FcvtuOpF(context, FPRoundingMode.ToNearest, scalar: false); } else { @@ -323,7 +316,7 @@ namespace ARMeilleure.Instructions } else { - EmitFcvt_s_Gp(context, (op1) => EmitUnaryMathCall(context, MathF.Ceiling, Math.Ceiling, op1)); + EmitFcvt_s_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Ceiling), op1)); } } @@ -335,7 +328,7 @@ namespace ARMeilleure.Instructions } else { - EmitFcvt_u_Gp(context, (op1) => EmitUnaryMathCall(context, MathF.Ceiling, Math.Ceiling, op1)); + EmitFcvt_u_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Ceiling), op1)); } } @@ -367,7 +360,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse41) { - EmitSse41Fcvts(context, FPRoundingMode.TowardsZero, scalar: true); + EmitSse41FcvtsOpF(context, FPRoundingMode.TowardsZero, scalar: true); } else { @@ -379,7 +372,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse41) { - EmitSse41Fcvts(context, FPRoundingMode.TowardsZero, scalar: false); + EmitSse41FcvtsOpF(context, FPRoundingMode.TowardsZero, scalar: false); } else { @@ -391,7 +384,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse41) { - EmitSse41Fcvts(context, FPRoundingMode.TowardsZero, scalar: false); + EmitSse41FcvtsOpF(context, FPRoundingMode.TowardsZero, scalar: false); } else { @@ -427,7 +420,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse41) { - EmitSse41Fcvtu(context, FPRoundingMode.TowardsZero, scalar: true); + EmitSse41FcvtuOpF(context, FPRoundingMode.TowardsZero, scalar: true); } else { @@ -439,7 +432,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse41) { - EmitSse41Fcvtu(context, FPRoundingMode.TowardsZero, scalar: false); + EmitSse41FcvtuOpF(context, FPRoundingMode.TowardsZero, scalar: false); } else { @@ -451,7 +444,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse41) { - EmitSse41Fcvtu(context, FPRoundingMode.TowardsZero, scalar: false); + EmitSse41FcvtuOpF(context, FPRoundingMode.TowardsZero, scalar: false); } else { @@ -497,7 +490,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse2) { - EmitSse2Scvtf(context, scalar: true); + EmitSse2ScvtfOp(context, scalar: true); } else { @@ -517,7 +510,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse2) { - EmitSse2Scvtf(context, scalar: false); + EmitSse2ScvtfOp(context, scalar: false); } else { @@ -529,7 +522,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse2) { - EmitSse2Scvtf(context, scalar: false); + EmitSse2ScvtfOp(context, scalar: false); } else { @@ -565,7 +558,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse2) { - EmitSse2Ucvtf(context, scalar: true); + EmitSse2UcvtfOp(context, scalar: true); } else { @@ -585,7 +578,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse2) { - EmitSse2Ucvtf(context, scalar: false); + EmitSse2UcvtfOp(context, scalar: false); } else { @@ -597,7 +590,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse2) { - EmitSse2Ucvtf(context, scalar: false); + EmitSse2UcvtfOp(context, scalar: false); } else { @@ -628,21 +621,21 @@ namespace ARMeilleure.Instructions if (sizeF == 0) { - Delegate dlg = signed - ? (Delegate)new _S32_F32(SoftFallback.SatF32ToS32) - : (Delegate)new _U32_F32(SoftFallback.SatF32ToU32); + MethodInfo info = signed + ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32)) + : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32)); - e = context.Call(dlg, e); + e = context.Call(info, e); e = context.ZeroExtend32(OperandType.I64, e); } else /* if (sizeF == 1) */ { - Delegate dlg = signed - ? (Delegate)new _S64_F64(SoftFallback.SatF64ToS64) - : (Delegate)new _U64_F64(SoftFallback.SatF64ToU64); + MethodInfo info = signed + ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToS64)) + : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToU64)); - e = context.Call(dlg, e); + e = context.Call(info, e); } res = EmitVectorInsert(context, res, e, index, sizeI); @@ -676,21 +669,21 @@ namespace ARMeilleure.Instructions if (sizeF == 0) { - Delegate dlg = signed - ? (Delegate)new _S32_F32(SoftFallback.SatF32ToS32) - : (Delegate)new _U32_F32(SoftFallback.SatF32ToU32); + MethodInfo info = signed + ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32)) + : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32)); - e = context.Call(dlg, e); + e = context.Call(info, e); e = context.ZeroExtend32(OperandType.I64, e); } else /* if (sizeF == 1) */ { - Delegate dlg = signed - ? (Delegate)new _S64_F64(SoftFallback.SatF64ToS64) - : (Delegate)new _U64_F64(SoftFallback.SatF64ToU64); + MethodInfo info = signed + ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToS64)) + : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToU64)); - e = context.Call(dlg, e); + e = context.Call(info, e); } res = EmitVectorInsert(context, res, e, index, sizeI); @@ -809,22 +802,22 @@ namespace ARMeilleure.Instructions value = EmitF2iFBitsMul(context, value, fBits); + MethodInfo info; + if (context.CurrOp.RegisterSize == RegisterSize.Int32) { - Delegate dlg = value.Type == OperandType.FP32 - ? (Delegate)new _S32_F32(SoftFallback.SatF32ToS32) - : (Delegate)new _S32_F64(SoftFallback.SatF64ToS32); - - return context.Call(dlg, value); + info = value.Type == OperandType.FP32 + ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32)) + : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToS32)); } else { - Delegate dlg = value.Type == OperandType.FP32 - ? (Delegate)new _S64_F32(SoftFallback.SatF32ToS64) - : (Delegate)new _S64_F64(SoftFallback.SatF64ToS64); - - return context.Call(dlg, value); + info = value.Type == OperandType.FP32 + ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS64)) + : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToS64)); } + + return context.Call(info, value); } private static Operand EmitScalarFcvtu(ArmEmitterContext context, Operand value, int fBits) @@ -833,22 +826,22 @@ namespace ARMeilleure.Instructions value = EmitF2iFBitsMul(context, value, fBits); + MethodInfo info; + if (context.CurrOp.RegisterSize == RegisterSize.Int32) { - Delegate dlg = value.Type == OperandType.FP32 - ? (Delegate)new _U32_F32(SoftFallback.SatF32ToU32) - : (Delegate)new _U32_F64(SoftFallback.SatF64ToU32); - - return context.Call(dlg, value); + info = value.Type == OperandType.FP32 + ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32)) + : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToU32)); } else { - Delegate dlg = value.Type == OperandType.FP32 - ? (Delegate)new _U64_F32(SoftFallback.SatF32ToU64) - : (Delegate)new _U64_F64(SoftFallback.SatF64ToU64); - - return context.Call(dlg, value); + info = value.Type == OperandType.FP32 + ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU64)) + : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToU64)); } + + return context.Call(info, value); } private static Operand EmitF2iFBitsMul(ArmEmitterContext context, Operand value, int fBits) @@ -925,7 +918,7 @@ namespace ARMeilleure.Instructions return res; } - private static void EmitSse2Scvtf(ArmEmitterContext context, bool scalar) + private static void EmitSse2ScvtfOp(ArmEmitterContext context, bool scalar) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -990,7 +983,7 @@ namespace ARMeilleure.Instructions } } - private static void EmitSse2Ucvtf(ArmEmitterContext context, bool scalar) + private static void EmitSse2UcvtfOp(ArmEmitterContext context, bool scalar) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -1079,7 +1072,7 @@ namespace ARMeilleure.Instructions } } - private static void EmitSse41Fcvts(ArmEmitterContext context, FPRoundingMode roundMode, bool scalar) + private static void EmitSse41FcvtsOpF(ArmEmitterContext context, FPRoundingMode roundMode, bool scalar) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -1170,7 +1163,7 @@ namespace ARMeilleure.Instructions } } - private static void EmitSse41Fcvtu(ArmEmitterContext context, FPRoundingMode roundMode, bool scalar) + private static void EmitSse41FcvtuOpF(ArmEmitterContext context, FPRoundingMode roundMode, bool scalar) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; diff --git a/ARMeilleure/Instructions/InstEmitSimdCvt32.cs b/ARMeilleure/Instructions/InstEmitSimdCvt32.cs index 4f2139a4..00b8ffd6 100644 --- a/ARMeilleure/Instructions/InstEmitSimdCvt32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdCvt32.cs @@ -4,6 +4,7 @@ using ARMeilleure.State; using ARMeilleure.Translation; using System; using System.Diagnostics; +using System.Reflection; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; @@ -20,7 +21,7 @@ namespace ARMeilleure.Instructions { // Move the low bit to the top. return ((vd & 0x1) << 4) | (vd >> 1); - } + } else { // Move the high bit to the bottom. @@ -30,29 +31,22 @@ namespace ARMeilleure.Instructions private static Operand EmitSaturateFloatToInt(ArmEmitterContext context, Operand op1, bool unsigned) { + MethodInfo info; + if (op1.Type == OperandType.FP64) { - if (unsigned) - { - return context.Call(new _U32_F64(SoftFallback.SatF64ToU32), op1); - } - else - { - return context.Call(new _S32_F64(SoftFallback.SatF64ToS32), op1); - } - + info = unsigned + ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToU32)) + : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToS32)); } else { - if (unsigned) - { - return context.Call(new _U32_F32(SoftFallback.SatF32ToU32), op1); - } - else - { - return context.Call(new _S32_F32(SoftFallback.SatF32ToS32), op1); - } + info = unsigned + ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32)) + : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32)); } + + return context.Call(info, op1); } public static void Vcvt_V(ArmEmitterContext context) @@ -96,7 +90,7 @@ namespace ARMeilleure.Instructions res2 = context.AddIntrinsic(Intrinsic.X86Cvtdq2ps, res2); return context.AddIntrinsic(Intrinsic.X86Addps, res, res2); - } + } else { return context.AddIntrinsic(Intrinsic.X86Cvtdq2ps, n); @@ -114,9 +108,7 @@ namespace ARMeilleure.Instructions EmitVectorUnaryOpSx32(context, (op1) => EmitFPConvert(context, op1, floatSize, true)); } } - } - } public static void Vcvt_FD(ArmEmitterContext context) @@ -173,29 +165,22 @@ namespace ARMeilleure.Instructions // TODO: Fast Path. if (roundWithFpscr) { + MethodInfo info; + if (floatSize == OperandType.FP64) { - if (unsigned) - { - asInteger = context.Call(new _U32_F64(SoftFallback.DoubleToUInt32), toConvert); - } - else - { - asInteger = context.Call(new _S32_F64(SoftFallback.DoubleToInt32), toConvert); - } - + info = unsigned + ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.DoubleToUInt32)) + : typeof(SoftFallback).GetMethod(nameof(SoftFallback.DoubleToInt32)); } else { - if (unsigned) - { - asInteger = context.Call(new _U32_F32(SoftFallback.FloatToUInt32), toConvert); - } - else - { - asInteger = context.Call(new _S32_F32(SoftFallback.FloatToInt32), toConvert); - } + info = unsigned + ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.FloatToUInt32)) + : typeof(SoftFallback).GetMethod(nameof(SoftFallback.FloatToInt32)); } + + asInteger = context.Call(info, toConvert); } else { @@ -205,7 +190,7 @@ namespace ARMeilleure.Instructions InsertScalar(context, op.Vd, asInteger); } - } + } else { bool unsigned = op.Opc == 0; @@ -218,22 +203,17 @@ namespace ARMeilleure.Instructions } } - public static Operand EmitRoundMathCall(ArmEmitterContext context, MidpointRounding roundMode, Operand n) + private static Operand EmitRoundMathCall(ArmEmitterContext context, MidpointRounding roundMode, Operand n) { IOpCode32Simd op = (IOpCode32Simd)context.CurrOp; - Delegate dlg; + string name = nameof(Math.Round); - if ((op.Size & 1) == 0) - { - dlg = new _F32_F32_MidpointRounding(MathF.Round); - } - else /* if ((op.Size & 1) == 1) */ - { - dlg = new _F64_F64_MidpointRounding(Math.Round); - } + MethodInfo info = (op.Size & 1) == 0 + ? typeof(MathF).GetMethod(name, new Type[] { typeof(float), typeof(MidpointRounding) }) + : typeof(Math). GetMethod(name, new Type[] { typeof(double), typeof(MidpointRounding) }); - return context.Call(dlg, n, Const((int)roundMode)); + return context.Call(info, n, Const((int)roundMode)); } private static FPRoundingMode RMToRoundMode(int rm) @@ -282,10 +262,10 @@ namespace ARMeilleure.Instructions toConvert = EmitRoundMathCall(context, MidpointRounding.ToEven, toConvert); break; case 0b10: // Towards positive infinity - toConvert = EmitUnaryMathCall(context, MathF.Ceiling, Math.Ceiling, toConvert); + toConvert = EmitUnaryMathCall(context, nameof(Math.Ceiling), toConvert); break; case 0b11: // Towards negative infinity - toConvert = EmitUnaryMathCall(context, MathF.Floor, Math.Floor, toConvert); + toConvert = EmitUnaryMathCall(context, nameof(Math.Floor), toConvert); break; } @@ -316,7 +296,7 @@ namespace ARMeilleure.Instructions return context.AddIntrinsic(inst, m, Const(X86GetRoundControl(roundMode))); }); } - else + else { Operand toConvert = ExtractScalar(context, floatSize, op.Vm); @@ -329,10 +309,10 @@ namespace ARMeilleure.Instructions toConvert = EmitRoundMathCall(context, MidpointRounding.ToEven, toConvert); break; case 0b10: // Towards positive infinity - toConvert = EmitUnaryMathCall(context, MathF.Ceiling, Math.Ceiling, toConvert); + toConvert = EmitUnaryMathCall(context, nameof(Math.Ceiling), toConvert); break; case 0b11: // Towards negative infinity - toConvert = EmitUnaryMathCall(context, MathF.Floor, Math.Floor, toConvert); + toConvert = EmitUnaryMathCall(context, nameof(Math.Floor), toConvert); break; } @@ -351,10 +331,10 @@ namespace ARMeilleure.Instructions Intrinsic inst = (op.Size & 1) == 0 ? Intrinsic.X86Roundss : Intrinsic.X86Roundsd; return context.AddIntrinsic(inst, m, Const(X86GetRoundControl(FPRoundingMode.TowardsZero))); }); - } + } else { - EmitScalarUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, MathF.Truncate, Math.Truncate, op1)); + EmitScalarUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Truncate), op1)); } } @@ -423,7 +403,7 @@ namespace ARMeilleure.Instructions if (signed) { dRes = context.BitwiseExclusiveOr(nIntOrLong, nInt); - } + } else { dRes = context.BitwiseExclusiveOr(nIntOrLong2, nInt); @@ -527,7 +507,7 @@ namespace ARMeilleure.Instructions if (signed) { return context.AddIntrinsic(Intrinsic.X86Pxor, nInt, nRes); - } + } else { Operand dRes = context.AddIntrinsic(Intrinsic.X86Pxor, nInt2, nRes); diff --git a/ARMeilleure/Instructions/InstEmitSimdHash.cs b/ARMeilleure/Instructions/InstEmitSimdHash.cs index 4ed96061..ed8b4afd 100644 --- a/ARMeilleure/Instructions/InstEmitSimdHash.cs +++ b/ARMeilleure/Instructions/InstEmitSimdHash.cs @@ -19,7 +19,7 @@ namespace ARMeilleure.Instructions Operand m = GetVec(op.Rm); - Operand res = context.Call(new _V128_V128_U32_V128(SoftFallback.HashChoose), d, ne, m); + Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashChoose)), d, ne, m); context.Copy(GetVec(op.Rd), res); } @@ -30,7 +30,7 @@ namespace ARMeilleure.Instructions Operand ne = context.VectorExtract(OperandType.I32, GetVec(op.Rn), 0); - Operand res = context.Call(new _U32_U32(SoftFallback.FixedRotate), ne); + Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.FixedRotate)), ne); context.Copy(GetVec(op.Rd), context.VectorCreateScalar(res)); } @@ -45,7 +45,7 @@ namespace ARMeilleure.Instructions Operand m = GetVec(op.Rm); - Operand res = context.Call(new _V128_V128_U32_V128(SoftFallback.HashMajority), d, ne, m); + Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashMajority)), d, ne, m); context.Copy(GetVec(op.Rd), res); } @@ -60,7 +60,7 @@ namespace ARMeilleure.Instructions Operand m = GetVec(op.Rm); - Operand res = context.Call(new _V128_V128_U32_V128(SoftFallback.HashParity), d, ne, m); + Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashParity)), d, ne, m); context.Copy(GetVec(op.Rd), res); } @@ -73,7 +73,7 @@ namespace ARMeilleure.Instructions Operand n = GetVec(op.Rn); Operand m = GetVec(op.Rm); - Operand res = context.Call(new _V128_V128_V128_V128(SoftFallback.Sha1SchedulePart1), d, n, m); + Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha1SchedulePart1)), d, n, m); context.Copy(GetVec(op.Rd), res); } @@ -85,7 +85,7 @@ namespace ARMeilleure.Instructions Operand d = GetVec(op.Rd); Operand n = GetVec(op.Rn); - Operand res = context.Call(new _V128_V128_V128(SoftFallback.Sha1SchedulePart2), d, n); + Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha1SchedulePart2)), d, n); context.Copy(GetVec(op.Rd), res); } @@ -100,7 +100,7 @@ namespace ARMeilleure.Instructions Operand n = GetVec(op.Rn); Operand m = GetVec(op.Rm); - Operand res = context.Call(new _V128_V128_V128_V128(SoftFallback.HashLower), d, n, m); + Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashLower)), d, n, m); context.Copy(GetVec(op.Rd), res); } @@ -113,7 +113,7 @@ namespace ARMeilleure.Instructions Operand n = GetVec(op.Rn); Operand m = GetVec(op.Rm); - Operand res = context.Call(new _V128_V128_V128_V128(SoftFallback.HashUpper), d, n, m); + Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashUpper)), d, n, m); context.Copy(GetVec(op.Rd), res); } @@ -125,7 +125,7 @@ namespace ARMeilleure.Instructions Operand d = GetVec(op.Rd); Operand n = GetVec(op.Rn); - Operand res = context.Call(new _V128_V128_V128(SoftFallback.Sha256SchedulePart1), d, n); + Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart1)), d, n); context.Copy(GetVec(op.Rd), res); } @@ -138,7 +138,7 @@ namespace ARMeilleure.Instructions Operand n = GetVec(op.Rn); Operand m = GetVec(op.Rm); - Operand res = context.Call(new _V128_V128_V128_V128(SoftFallback.Sha256SchedulePart2), d, n, m); + Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart2)), d, n, m); context.Copy(GetVec(op.Rd), res); } diff --git a/ARMeilleure/Instructions/InstEmitSimdHelper.cs b/ARMeilleure/Instructions/InstEmitSimdHelper.cs index bf8d54c1..912c2260 100644 --- a/ARMeilleure/Instructions/InstEmitSimdHelper.cs +++ b/ARMeilleure/Instructions/InstEmitSimdHelper.cs @@ -4,6 +4,7 @@ using ARMeilleure.State; using ARMeilleure.Translation; using System; using System.Diagnostics; +using System.Reflection; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.IntermediateRepresentation.OperandHelper; @@ -310,68 +311,39 @@ namespace ARMeilleure.Instructions context.Copy(GetVec(op.Rd), res); } - public static Operand EmitUnaryMathCall(ArmEmitterContext context, _F32_F32 f32, _F64_F64 f64, Operand n) + public static Operand EmitUnaryMathCall(ArmEmitterContext context, string name, Operand n) { IOpCodeSimd op = (IOpCodeSimd)context.CurrOp; - return (op.Size & 1) == 0 ? context.Call(f32, n) : context.Call(f64, n); - } - - public static Operand EmitRoundMathCall(ArmEmitterContext context, MidpointRounding roundMode, Operand n) - { - IOpCodeSimd op = (IOpCodeSimd)context.CurrOp; - - Delegate dlg; - - if ((op.Size & 1) == 0) - { - dlg = new _F32_F32_MidpointRounding(MathF.Round); - } - else /* if ((op.Size & 1) == 1) */ - { - dlg = new _F64_F64_MidpointRounding(Math.Round); - } + MethodInfo info = (op.Size & 1) == 0 + ? typeof(MathF).GetMethod(name, new Type[] { typeof(float) }) + : typeof(Math). GetMethod(name, new Type[] { typeof(double) }); - return context.Call(dlg, n, Const((int)roundMode)); + return context.Call(info, n); } - public static Operand EmitSoftFloatCall( - ArmEmitterContext context, - _F32_F32 f32, - _F64_F64 f64, - params Operand[] callArgs) + public static Operand EmitRoundMathCall(ArmEmitterContext context, MidpointRounding roundMode, Operand n) { IOpCodeSimd op = (IOpCodeSimd)context.CurrOp; - Delegate dlg = (op.Size & 1) == 0 ? (Delegate)f32 : (Delegate)f64; - - return context.Call(dlg, callArgs); - } - - public static Operand EmitSoftFloatCall( - ArmEmitterContext context, - _F32_F32_F32 f32, - _F64_F64_F64 f64, - params Operand[] callArgs) - { - IOpCodeSimd op = (IOpCodeSimd)context.CurrOp; + string name = nameof(Math.Round); - Delegate dlg = (op.Size & 1) == 0 ? (Delegate)f32 : (Delegate)f64; + MethodInfo info = (op.Size & 1) == 0 + ? typeof(MathF).GetMethod(name, new Type[] { typeof(float), typeof(MidpointRounding) }) + : typeof(Math). GetMethod(name, new Type[] { typeof(double), typeof(MidpointRounding) }); - return context.Call(dlg, callArgs); + return context.Call(info, n, Const((int)roundMode)); } - public static Operand EmitSoftFloatCall( - ArmEmitterContext context, - _F32_F32_F32_F32 f32, - _F64_F64_F64_F64 f64, - params Operand[] callArgs) + public static Operand EmitSoftFloatCall(ArmEmitterContext context, string name, params Operand[] callArgs) { IOpCodeSimd op = (IOpCodeSimd)context.CurrOp; - Delegate dlg = (op.Size & 1) == 0 ? (Delegate)f32 : (Delegate)f64; + MethodInfo info = (op.Size & 1) == 0 + ? typeof(SoftFloat32).GetMethod(name) + : typeof(SoftFloat64).GetMethod(name); - return context.Call(dlg, callArgs); + return context.Call(info, callArgs); } public static void EmitScalarBinaryOpByElemF(ArmEmitterContext context, Func2I emit) @@ -1425,22 +1397,22 @@ namespace ARMeilleure.Instructions throw new ArgumentOutOfRangeException(nameof(sizeDst)); } - Delegate dlg; + MethodInfo info; if (signedSrc) { - dlg = signedDst - ? (Delegate)new _S64_S64_S32(SoftFallback.SignedSrcSignedDstSatQ) - : (Delegate)new _U64_S64_S32(SoftFallback.SignedSrcUnsignedDstSatQ); + info = signedDst + ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedSrcSignedDstSatQ)) + : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedSrcUnsignedDstSatQ)); } else { - dlg = signedDst - ? (Delegate)new _S64_U64_S32(SoftFallback.UnsignedSrcSignedDstSatQ) - : (Delegate)new _U64_U64_S32(SoftFallback.UnsignedSrcUnsignedDstSatQ); + info = signedDst + ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedSrcSignedDstSatQ)) + : typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedSrcUnsignedDstSatQ)); } - return context.Call(dlg, op, Const(sizeDst)); + return context.Call(info, op, Const(sizeDst)); } // TSrc (64bit) == TDst (64bit); signed. @@ -1448,7 +1420,7 @@ namespace ARMeilleure.Instructions { Debug.Assert(((OpCodeSimd)context.CurrOp).Size == 3, "Invalid element size."); - return context.Call(new _S64_S64(SoftFallback.UnarySignedSatQAbsOrNeg), op); + return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnarySignedSatQAbsOrNeg)), op); } // TSrcs (64bit) == TDst (64bit); signed, unsigned. @@ -1456,11 +1428,11 @@ namespace ARMeilleure.Instructions { Debug.Assert(((OpCodeSimd)context.CurrOp).Size == 3, "Invalid element size."); - Delegate dlg = signed - ? (Delegate)new _S64_S64_S64(SoftFallback.BinarySignedSatQAdd) - : (Delegate)new _U64_U64_U64(SoftFallback.BinaryUnsignedSatQAdd); + MethodInfo info = signed + ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinarySignedSatQAdd)) + : typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinaryUnsignedSatQAdd)); - return context.Call(dlg, op1, op2); + return context.Call(info, op1, op2); } // TSrcs (64bit) == TDst (64bit); signed, unsigned. @@ -1468,11 +1440,11 @@ namespace ARMeilleure.Instructions { Debug.Assert(((OpCodeSimd)context.CurrOp).Size == 3, "Invalid element size."); - Delegate dlg = signed - ? (Delegate)new _S64_S64_S64(SoftFallback.BinarySignedSatQSub) - : (Delegate)new _U64_U64_U64(SoftFallback.BinaryUnsignedSatQSub); + MethodInfo info = signed + ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinarySignedSatQSub)) + : typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinaryUnsignedSatQSub)); - return context.Call(dlg, op1, op2); + return context.Call(info, op1, op2); } // TSrcs (64bit) == TDst (64bit); signed, unsigned. @@ -1480,11 +1452,11 @@ namespace ARMeilleure.Instructions { Debug.Assert(((OpCodeSimd)context.CurrOp).Size == 3, "Invalid element size."); - Delegate dlg = signed - ? (Delegate)new _S64_U64_S64(SoftFallback.BinarySignedSatQAcc) - : (Delegate)new _U64_S64_U64(SoftFallback.BinaryUnsignedSatQAcc); + MethodInfo info = signed + ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinarySignedSatQAcc)) + : typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinaryUnsignedSatQAcc)); - return context.Call(dlg, op1, op2); + return context.Call(info, op1, op2); } public static Operand EmitFloatAbs(ArmEmitterContext context, Operand value, bool single, bool vector) @@ -1493,7 +1465,7 @@ namespace ARMeilleure.Instructions if (single) { mask = vector ? X86GetAllElements(context, -0f) : X86GetScalar(context, -0f); - } + } else { mask = vector ? X86GetAllElements(context, -0d) : X86GetScalar(context, -0d); diff --git a/ARMeilleure/Instructions/InstEmitSimdHelper32.cs b/ARMeilleure/Instructions/InstEmitSimdHelper32.cs index 67dc25c7..9697715a 100644 --- a/ARMeilleure/Instructions/InstEmitSimdHelper32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdHelper32.cs @@ -3,6 +3,8 @@ using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using System; using System.Diagnostics; +using System.Reflection; + using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; using static ARMeilleure.IntermediateRepresentation.OperandHelper; @@ -39,7 +41,7 @@ namespace ARMeilleure.Instructions { // From dreg. return context.VectorExtract(type, GetVecA32(reg >> 1), reg & 1); - } + } else { // From sreg. @@ -575,7 +577,7 @@ namespace ARMeilleure.Instructions if (targetSide == 1) { return context.AddIntrinsic(Intrinsic.X86Movlhps, input, input); // Low to high. - } + } else { return context.AddIntrinsic(Intrinsic.X86Movhlps, input, input); // High to low. @@ -592,7 +594,7 @@ namespace ARMeilleure.Instructions if (targetSide == 1) { return context.AddIntrinsic(Intrinsic.X86Shufpd, target, value, Const(shuffleMask)); - } + } else { return context.AddIntrinsic(Intrinsic.X86Shufpd, value, target, Const(shuffleMask)); @@ -622,7 +624,7 @@ namespace ARMeilleure.Instructions if (Optimizations.UseSse41) { return context.AddIntrinsic(Intrinsic.X86Insertps, target, value, Const(index << 4)); - } + } else { target = EmitSwapScalar(context, target, index, doubleWidth); // Swap value to replace into element 0. @@ -642,7 +644,7 @@ namespace ARMeilleure.Instructions { int shuffleMask = 1; // Swap top and bottom. (b0 = 1, b1 = 0) return context.AddIntrinsic(Intrinsic.X86Shufpd, target, target, Const(shuffleMask)); - } + } else { int shuffleMask = (3 << 6) | (2 << 4) | (1 << 2) | index; // Swap index and 0. (others remain) @@ -1000,52 +1002,18 @@ namespace ARMeilleure.Instructions // Generic Functions - public static Operand EmitSoftFloatCallDefaultFpscr( - ArmEmitterContext context, - _F32_F32_Bool f32, - _F64_F64_Bool f64, - params Operand[] callArgs) - { - IOpCodeSimd op = (IOpCodeSimd)context.CurrOp; - - Delegate dlg = (op.Size & 1) == 0 ? (Delegate)f32 : (Delegate)f64; - - Array.Resize(ref callArgs, callArgs.Length + 1); - callArgs[callArgs.Length - 1] = Const(1); - - return context.Call(dlg, callArgs); - } - - public static Operand EmitSoftFloatCallDefaultFpscr( - ArmEmitterContext context, - _F32_F32_F32_Bool f32, - _F64_F64_F64_Bool f64, - params Operand[] callArgs) - { - IOpCodeSimd op = (IOpCodeSimd)context.CurrOp; - - Delegate dlg = (op.Size & 1) == 0 ? (Delegate)f32 : (Delegate)f64; - - Array.Resize(ref callArgs, callArgs.Length + 1); - callArgs[callArgs.Length - 1] = Const(1); - - return context.Call(dlg, callArgs); - } - - public static Operand EmitSoftFloatCallDefaultFpscr( - ArmEmitterContext context, - _F32_F32_F32_F32_Bool f32, - _F64_F64_F64_F64_Bool f64, - params Operand[] callArgs) + public static Operand EmitSoftFloatCallDefaultFpscr(ArmEmitterContext context, string name, params Operand[] callArgs) { IOpCodeSimd op = (IOpCodeSimd)context.CurrOp; - Delegate dlg = (op.Size & 1) == 0 ? (Delegate)f32 : (Delegate)f64; + MethodInfo info = (op.Size & 1) == 0 + ? typeof(SoftFloat32).GetMethod(name) + : typeof(SoftFloat64).GetMethod(name); Array.Resize(ref callArgs, callArgs.Length + 1); callArgs[callArgs.Length - 1] = Const(1); - return context.Call(dlg, callArgs); + return context.Call(info, callArgs); } public static Operand EmitVectorExtractSx32(ArmEmitterContext context, int reg, int index, int size) diff --git a/ARMeilleure/Instructions/InstEmitSimdMove.cs b/ARMeilleure/Instructions/InstEmitSimdMove.cs index a1a4635f..12fc71c9 100644 --- a/ARMeilleure/Instructions/InstEmitSimdMove.cs +++ b/ARMeilleure/Instructions/InstEmitSimdMove.cs @@ -1,8 +1,8 @@ using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; -using System; using System.Collections.Generic; +using System.Reflection; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; @@ -284,13 +284,26 @@ namespace ARMeilleure.Instructions { OpCodeSimdFmov op = (OpCodeSimdFmov)context.CurrOp; - if (op.Size == 0) + if (Optimizations.UseSse2) { - context.Copy(GetVec(op.Rd), X86GetScalar(context, (int)op.Immediate)); + if (op.Size == 0) + { + context.Copy(GetVec(op.Rd), X86GetScalar(context, (int)op.Immediate)); + } + else + { + context.Copy(GetVec(op.Rd), X86GetScalar(context, op.Immediate)); + } } else { - context.Copy(GetVec(op.Rd), X86GetScalar(context, op.Immediate)); + Operand e = Const(op.Immediate); + + Operand res = context.VectorZero(); + + res = EmitVectorInsert(context, res, e, 0, op.Size + 2); + + context.Copy(GetVec(op.Rd), res); } } @@ -350,7 +363,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse2) { - EmitSse2MoviMvni(context, not: false); + EmitSse2VectorMoviMvniOp(context, not: false); } else { @@ -362,7 +375,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.UseSse2) { - EmitSse2MoviMvni(context, not: true); + EmitSse2VectorMoviMvniOp(context, not: true); } else { @@ -476,7 +489,7 @@ namespace ARMeilleure.Instructions EmitVectorZip(context, part: 1); } - private static void EmitSse2MoviMvni(ArmEmitterContext context, bool not) + private static void EmitSse2VectorMoviMvniOp(ArmEmitterContext context, bool not) { OpCodeSimdImm op = (OpCodeSimdImm)context.CurrOp; @@ -593,32 +606,30 @@ namespace ARMeilleure.Instructions args.Add(GetVec((op.Rn + index) & 0x1F)); } - Delegate dlg = null; + MethodInfo info = null; - switch (op.Size) + if (isTbl) { - case 1: dlg = isTbl - ? (Delegate)new _V128_V128_S32_V128 (SoftFallback.Tbl1) - : (Delegate)new _V128_V128_V128_S32_V128(SoftFallback.Tbx1); - break; - - case 2: dlg = isTbl - ? (Delegate)new _V128_V128_S32_V128_V128 (SoftFallback.Tbl2) - : (Delegate)new _V128_V128_V128_S32_V128_V128(SoftFallback.Tbx2); - break; - - case 3: dlg = isTbl - ? (Delegate)new _V128_V128_S32_V128_V128_V128 (SoftFallback.Tbl3) - : (Delegate)new _V128_V128_V128_S32_V128_V128_V128(SoftFallback.Tbx3); - break; - - case 4: dlg = isTbl - ? (Delegate)new _V128_V128_S32_V128_V128_V128_V128 (SoftFallback.Tbl4) - : (Delegate)new _V128_V128_V128_S32_V128_V128_V128_V128(SoftFallback.Tbx4); - break; + switch (op.Size) + { + case 1: info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl1)); break; + case 2: info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl2)); break; + case 3: info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl3)); break; + case 4: info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl4)); break; + } + } + else + { + switch (op.Size) + { + case 1: info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx1)); break; + case 2: info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx2)); break; + case 3: info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx3)); break; + case 4: info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx4)); break; + } } - context.Copy(d, context.Call(dlg, args.ToArray())); + context.Copy(d, context.Call(info, args.ToArray())); } } diff --git a/ARMeilleure/Instructions/InstEmitSimdShift.cs b/ARMeilleure/Instructions/InstEmitSimdShift.cs index 19c0a74d..0b3d85ae 100644 --- a/ARMeilleure/Instructions/InstEmitSimdShift.cs +++ b/ARMeilleure/Instructions/InstEmitSimdShift.cs @@ -5,6 +5,7 @@ using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using System; using System.Diagnostics; +using System.Reflection; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; @@ -198,7 +199,7 @@ namespace ARMeilleure.Instructions Operand ne = EmitVectorExtractSx(context, op.Rn, index, op.Size); Operand me = EmitVectorExtractSx(context, op.Rm, index, op.Size); - Operand e = context.Call(new _S64_S64_S64_Bool_S32(SoftFallback.SignedShlRegSatQ), ne, me, Const(1), Const(op.Size)); + Operand e = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShlRegSatQ)), ne, me, Const(1), Const(op.Size)); res = EmitVectorInsert(context, res, e, index, op.Size); } @@ -239,7 +240,7 @@ namespace ARMeilleure.Instructions Operand ne = EmitVectorExtractSx(context, op.Rn, index, op.Size); Operand me = EmitVectorExtractSx(context, op.Rm, index, op.Size); - Operand e = context.Call(new _S64_S64_S64_Bool_S32(SoftFallback.SignedShlRegSatQ), ne, me, Const(0), Const(op.Size)); + Operand e = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShlRegSatQ)), ne, me, Const(0), Const(op.Size)); res = EmitVectorInsert(context, res, e, index, op.Size); } @@ -290,7 +291,7 @@ namespace ARMeilleure.Instructions Operand ne = EmitVectorExtractSx(context, op.Rn, index, op.Size); Operand me = EmitVectorExtractSx(context, op.Rm, index, op.Size); - Operand e = context.Call(new _S64_S64_S64_Bool_S32(SoftFallback.SignedShlReg), ne, me, Const(1), Const(op.Size)); + Operand e = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShlReg)), ne, me, Const(1), Const(op.Size)); res = EmitVectorInsert(context, res, e, index, op.Size); } @@ -403,7 +404,7 @@ namespace ARMeilleure.Instructions Operand ne = EmitVectorExtractSx(context, op.Rn, index, op.Size); Operand me = EmitVectorExtractSx(context, op.Rm, index, op.Size); - Operand e = context.Call(new _S64_S64_S64_Bool_S32(SoftFallback.SignedShlReg), ne, me, Const(0), Const(op.Size)); + Operand e = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShlReg)), ne, me, Const(0), Const(op.Size)); res = EmitVectorInsert(context, res, e, index, op.Size); } @@ -527,7 +528,7 @@ namespace ARMeilleure.Instructions Operand ne = EmitVectorExtractZx(context, op.Rn, index, op.Size); Operand me = EmitVectorExtractZx(context, op.Rm, index, op.Size); - Operand e = context.Call(new _U64_U64_U64_Bool_S32(SoftFallback.UnsignedShlRegSatQ), ne, me, Const(1), Const(op.Size)); + Operand e = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShlRegSatQ)), ne, me, Const(1), Const(op.Size)); res = EmitVectorInsert(context, res, e, index, op.Size); } @@ -558,7 +559,7 @@ namespace ARMeilleure.Instructions Operand ne = EmitVectorExtractZx(context, op.Rn, index, op.Size); Operand me = EmitVectorExtractZx(context, op.Rm, index, op.Size); - Operand e = context.Call(new _U64_U64_U64_Bool_S32(SoftFallback.UnsignedShlRegSatQ), ne, me, Const(0), Const(op.Size)); + Operand e = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShlRegSatQ)), ne, me, Const(0), Const(op.Size)); res = EmitVectorInsert(context, res, e, index, op.Size); } @@ -589,7 +590,7 @@ namespace ARMeilleure.Instructions Operand ne = EmitVectorExtractZx(context, op.Rn, index, op.Size); Operand me = EmitVectorExtractZx(context, op.Rm, index, op.Size); - Operand e = context.Call(new _U64_U64_U64_Bool_S32(SoftFallback.UnsignedShlReg), ne, me, Const(1), Const(op.Size)); + Operand e = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShlReg)), ne, me, Const(1), Const(op.Size)); res = EmitVectorInsert(context, res, e, index, op.Size); } @@ -1026,11 +1027,11 @@ namespace ARMeilleure.Instructions long roundConst, int shift) { - Delegate dlg = signed - ? (Delegate)new _S64_S64_S64_S32(SoftFallback.SignedShrImm64) - : (Delegate)new _U64_U64_S64_S32(SoftFallback.UnsignedShrImm64); + MethodInfo info = signed + ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShrImm64)) + : typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShrImm64)); - return context.Call(dlg, value, Const(roundConst), Const(shift)); + return context.Call(info, value, Const(roundConst), Const(shift)); } private static void EmitVectorShImmWidenBinarySx(ArmEmitterContext context, Func2I emit, int imm) diff --git a/ARMeilleure/Instructions/InstEmitSimdShift32.cs b/ARMeilleure/Instructions/InstEmitSimdShift32.cs index e57c92a3..b9055c30 100644 --- a/ARMeilleure/Instructions/InstEmitSimdShift32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdShift32.cs @@ -1,9 +1,9 @@ using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; -using ARMeilleure.State; using ARMeilleure.Translation; using System; using System.Diagnostics; +using System.Reflection; using static ARMeilleure.Instructions.InstEmitSimdHelper32; using static ARMeilleure.IntermediateRepresentation.OperandHelper; @@ -244,11 +244,11 @@ namespace ARMeilleure.Instructions long roundConst, int shift) { - Delegate dlg = signed - ? (Delegate)new _S64_S64_S64_S32(SoftFallback.SignedShrImm64) - : (Delegate)new _U64_U64_S64_S32(SoftFallback.UnsignedShrImm64); + MethodInfo info = signed + ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShrImm64)) + : typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShrImm64)); - return context.Call(dlg, value, Const(roundConst), Const(shift)); + return context.Call(info, value, Const(roundConst), Const(shift)); } private static Operand EmitSatQ(ArmEmitterContext context, Operand value, int eSize, bool signed) diff --git a/ARMeilleure/Instructions/InstEmitSystem.cs b/ARMeilleure/Instructions/InstEmitSystem.cs index c13f0c3e..827c3a79 100644 --- a/ARMeilleure/Instructions/InstEmitSystem.cs +++ b/ARMeilleure/Instructions/InstEmitSystem.cs @@ -3,6 +3,7 @@ using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; using System; +using System.Reflection; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.IntermediateRepresentation.OperandHelper; @@ -27,44 +28,44 @@ namespace ARMeilleure.Instructions { OpCodeSystem op = (OpCodeSystem)context.CurrOp; - Delegate dlg; + MethodInfo info; switch (GetPackedId(op)) { - case 0b11_011_0000_0000_001: dlg = new _U64(NativeInterface.GetCtrEl0); break; - case 0b11_011_0000_0000_111: dlg = new _U64(NativeInterface.GetDczidEl0); break; - case 0b11_011_0100_0010_000: EmitGetNzcv(context); return; - case 0b11_011_0100_0100_000: dlg = new _U64(NativeInterface.GetFpcr); break; - case 0b11_011_0100_0100_001: dlg = new _U64(NativeInterface.GetFpsr); break; - case 0b11_011_1101_0000_010: dlg = new _U64(NativeInterface.GetTpidrEl0); break; - case 0b11_011_1101_0000_011: dlg = new _U64(NativeInterface.GetTpidr); break; - case 0b11_011_1110_0000_000: dlg = new _U64(NativeInterface.GetCntfrqEl0); break; - case 0b11_011_1110_0000_001: dlg = new _U64(NativeInterface.GetCntpctEl0); break; - case 0b11_011_1110_0000_010: dlg = new _U64(NativeInterface.GetCntvctEl0); break; + case 0b11_011_0000_0000_001: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCtrEl0)); break; + case 0b11_011_0000_0000_111: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetDczidEl0)); break; + case 0b11_011_0100_0010_000: EmitGetNzcv(context); return; + case 0b11_011_0100_0100_000: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFpcr)); break; + case 0b11_011_0100_0100_001: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFpsr)); break; + case 0b11_011_1101_0000_010: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidrEl0)); break; + case 0b11_011_1101_0000_011: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidr)); break; + case 0b11_011_1110_0000_000: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntfrqEl0)); break; + case 0b11_011_1110_0000_001: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntpctEl0)); break; + case 0b11_011_1110_0000_010: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntvctEl0)); break; default: throw new NotImplementedException($"Unknown MRS 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); } - SetIntOrZR(context, op.Rt, context.Call(dlg)); + SetIntOrZR(context, op.Rt, context.Call(info)); } public static void Msr(ArmEmitterContext context) { OpCodeSystem op = (OpCodeSystem)context.CurrOp; - Delegate dlg; + MethodInfo info; switch (GetPackedId(op)) { - case 0b11_011_0100_0010_000: EmitSetNzcv(context); return; - case 0b11_011_0100_0100_000: dlg = new _Void_U64(NativeInterface.SetFpcr); break; - case 0b11_011_0100_0100_001: dlg = new _Void_U64(NativeInterface.SetFpsr); break; - case 0b11_011_1101_0000_010: dlg = new _Void_U64(NativeInterface.SetTpidrEl0); break; + case 0b11_011_0100_0010_000: EmitSetNzcv(context); return; + case 0b11_011_0100_0100_000: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpcr)); break; + case 0b11_011_0100_0100_001: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsr)); break; + case 0b11_011_1101_0000_010: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl0)); break; default: throw new NotImplementedException($"Unknown MSR 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); } - context.Call(dlg, GetIntOrZR(context, op.Rt)); + context.Call(info, GetIntOrZR(context, op.Rt)); } public static void Nop(ArmEmitterContext context) @@ -90,7 +91,7 @@ namespace ARMeilleure.Instructions { Operand address = context.Add(t, Const(offset)); - context.Call(new _Void_U64_U64(NativeInterface.WriteUInt64), address, Const(0L)); + context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64)), address, Const(0L)); } break; diff --git a/ARMeilleure/Instructions/InstEmitSystem32.cs b/ARMeilleure/Instructions/InstEmitSystem32.cs index ebf829a0..14f73c3a 100644 --- a/ARMeilleure/Instructions/InstEmitSystem32.cs +++ b/ARMeilleure/Instructions/InstEmitSystem32.cs @@ -3,6 +3,7 @@ using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; using System; +using System.Reflection; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.IntermediateRepresentation.OperandHelper; @@ -18,6 +19,7 @@ namespace ARMeilleure.Instructions if (op.Coproc != 15) { InstEmit.Und(context); + return; } @@ -26,7 +28,8 @@ namespace ARMeilleure.Instructions throw new NotImplementedException($"Unknown MRC Opc1 0x{op.Opc1:X16} at 0x{op.Address:X16}."); } - Delegate dlg; + MethodInfo info; + switch (op.CRn) { case 13: // Process and Thread Info. @@ -34,13 +37,16 @@ namespace ARMeilleure.Instructions { throw new NotImplementedException($"Unknown MRC CRm 0x{op.CRm:X16} at 0x{op.Address:X16}."); } + switch (op.Opc2) { case 2: - dlg = new _Void_U32(NativeInterface.SetTpidrEl032); break; + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl032)); break; + default: throw new NotImplementedException($"Unknown MRC Opc2 0x{op.Opc2:X16} at 0x{op.Address:X16}."); } + break; case 7: @@ -51,18 +57,20 @@ namespace ARMeilleure.Instructions { case 5: // Data Memory Barrier Register. return; // No-op. + default: throw new NotImplementedException($"Unknown MRC Opc2 0x{op.Opc2:X16} at 0x{op.Address:X16}."); } + default: throw new NotImplementedException($"Unknown MRC CRm 0x{op.CRm:X16} at 0x{op.Address:X16}."); } - default: + default: throw new NotImplementedException($"Unknown MRC 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); } - context.Call(dlg, GetIntA32(context, op.Rt)); + context.Call(info, GetIntA32(context, op.Rt)); } public static void Mrc(ArmEmitterContext context) @@ -72,6 +80,7 @@ namespace ARMeilleure.Instructions if (op.Coproc != 15) { InstEmit.Und(context); + return; } @@ -80,7 +89,8 @@ namespace ARMeilleure.Instructions throw new NotImplementedException($"Unknown MRC Opc1 0x{op.Opc1:X16} at 0x{op.Address:X16}."); } - Delegate dlg; + MethodInfo info; + switch (op.CRn) { case 13: // Process and Thread Info. @@ -88,30 +98,35 @@ namespace ARMeilleure.Instructions { throw new NotImplementedException($"Unknown MRC CRm 0x{op.CRm:X16} at 0x{op.Address:X16}."); } + switch (op.Opc2) { case 2: - dlg = new _U32(NativeInterface.GetTpidrEl032); break; + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidrEl032)); break; + case 3: - dlg = new _U32(NativeInterface.GetTpidr32); break; + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidr32)); break; + default: throw new NotImplementedException($"Unknown MRC Opc2 0x{op.Opc2:X16} at 0x{op.Address:X16}."); } + break; - default: + + default: throw new NotImplementedException($"Unknown MRC 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); } if (op.Rt == RegisterAlias.Aarch32Pc) { // Special behavior: copy NZCV flags into APSR. - EmitSetNzcv(context, context.Call(dlg)); - + EmitSetNzcv(context, context.Call(info)); + return; } else { - SetIntA32(context, op.Rt, context.Call(dlg)); + SetIntA32(context, op.Rt, context.Call(info)); } } @@ -122,28 +137,33 @@ namespace ARMeilleure.Instructions if (op.Coproc != 15) { InstEmit.Und(context); + return; } - var opc = op.MrrcOp; + int opc = op.MrrcOp; + + MethodInfo info; - Delegate dlg; switch (op.CRm) { case 14: // Timer. switch (opc) { case 0: - dlg = new _U64(NativeInterface.GetCntpctEl0); break; + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntpctEl0)); break; + default: throw new NotImplementedException($"Unknown MRRC Opc1 0x{opc:X16} at 0x{op.Address:X16}."); } + break; - default: + + default: throw new NotImplementedException($"Unknown MRRC 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); } - Operand result = context.Call(dlg); + Operand result = context.Call(info); SetIntA32(context, op.Rt, context.ConvertI64ToI32(result)); SetIntA32(context, op.CRn, context.ConvertI64ToI32(context.ShiftRightUI(result, Const(32)))); @@ -162,16 +182,18 @@ namespace ARMeilleure.Instructions SetFlag(context, PState.CFlag, GetFpFlag(FPState.CFlag)); SetFlag(context, PState.ZFlag, GetFpFlag(FPState.ZFlag)); SetFlag(context, PState.NFlag, GetFpFlag(FPState.NFlag)); + return; } - Delegate dlg; + MethodInfo info; + switch (op.Sreg) { case 0b0000: // FPSID throw new NotImplementedException("Supervisor Only"); case 0b0001: // FPSCR - dlg = new _U32(NativeInterface.GetFpscr); break; + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFpscr)); break; case 0b0101: // MVFR2 throw new NotImplementedException("MVFR2"); case 0b0110: // MVFR1 @@ -180,24 +202,25 @@ namespace ARMeilleure.Instructions throw new NotImplementedException("MVFR0"); case 0b1000: // FPEXC throw new NotImplementedException("Supervisor Only"); - default: + default: throw new NotImplementedException($"Unknown VMRS 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); } - SetIntA32(context, op.Rt, context.Call(dlg)); + SetIntA32(context, op.Rt, context.Call(info)); } public static void Vmsr(ArmEmitterContext context) { OpCode32SimdSpecial op = (OpCode32SimdSpecial)context.CurrOp; - Delegate dlg; + MethodInfo info; + switch (op.Sreg) { case 0b0000: // FPSID throw new NotImplementedException("Supervisor Only"); case 0b0001: // FPSCR - dlg = new _Void_U32(NativeInterface.SetFpscr); break; + info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpscr)); break; case 0b0101: // MVFR2 throw new NotImplementedException("MVFR2"); case 0b0110: // MVFR1 @@ -206,11 +229,11 @@ namespace ARMeilleure.Instructions throw new NotImplementedException("MVFR0"); case 0b1000: // FPEXC throw new NotImplementedException("Supervisor Only"); - default: + default: throw new NotImplementedException($"Unknown VMSR 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); } - context.Call(dlg, GetIntA32(context, op.Rt)); + context.Call(info, GetIntA32(context, op.Rt)); } private static void EmitSetNzcv(ArmEmitterContext context, Operand t) diff --git a/ARMeilleure/Instructions/NativeInterface.cs b/ARMeilleure/Instructions/NativeInterface.cs index 49faab35..1b2a9288 100644 --- a/ARMeilleure/Instructions/NativeInterface.cs +++ b/ARMeilleure/Instructions/NativeInterface.cs @@ -407,18 +407,22 @@ namespace ARMeilleure.Instructions public static ulong GetFunctionAddress(ulong address) { TranslatedFunction function = _context.Translator.GetOrTranslate(address, GetContext().ExecutionMode); - return (ulong)function.GetPointer().ToInt64(); + + return (ulong)function.FuncPtr.ToInt64(); } public static ulong GetIndirectFunctionAddress(ulong address, ulong entryAddress) { TranslatedFunction function = _context.Translator.GetOrTranslate(address, GetContext().ExecutionMode); - ulong ptr = (ulong)function.GetPointer().ToInt64(); + + ulong ptr = (ulong)function.FuncPtr.ToInt64(); + if (function.HighCq) { // Rewrite the host function address in the table to point to the highCq function. Marshal.WriteInt64((IntPtr)entryAddress, 8, (long)ptr); } + return ptr; } diff --git a/ARMeilleure/Instructions/SoftFloat.cs b/ARMeilleure/Instructions/SoftFloat.cs index d3e15a2c..ec66bb86 100644 --- a/ARMeilleure/Instructions/SoftFloat.cs +++ b/ARMeilleure/Instructions/SoftFloat.cs @@ -903,6 +903,13 @@ namespace ARMeilleure.Instructions else { result = value1; + + if ((fpcr & FPCR.Fz) != 0 && float.IsSubnormal(result)) + { + context.Fpsr |= FPSR.Ufc; + + result = FPZero(result < 0f); + } } } else @@ -987,6 +994,13 @@ namespace ARMeilleure.Instructions else { result = value1; + + if ((fpcr & FPCR.Fz) != 0 && float.IsSubnormal(result)) + { + context.Fpsr |= FPSR.Ufc; + + result = FPZero(result < 0f); + } } } else @@ -2196,6 +2210,13 @@ namespace ARMeilleure.Instructions else { result = value1; + + if ((fpcr & FPCR.Fz) != 0 && double.IsSubnormal(result)) + { + context.Fpsr |= FPSR.Ufc; + + result = FPZero(result < 0d); + } } } else @@ -2280,6 +2301,13 @@ namespace ARMeilleure.Instructions else { result = value1; + + if ((fpcr & FPCR.Fz) != 0 && double.IsSubnormal(result)) + { + context.Fpsr |= FPSR.Ufc; + + result = FPZero(result < 0d); + } } } else |
