diff --git a/ARMeilleure/Instructions/InstEmitFlow32.cs b/ARMeilleure/Instructions/InstEmitFlow32.cs index 058631b149..69eaea8e73 100644 --- a/ARMeilleure/Instructions/InstEmitFlow32.cs +++ b/ARMeilleure/Instructions/InstEmitFlow32.cs @@ -3,6 +3,7 @@ using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; +using static ARMeilleure.Instructions.InstEmitFlowHelper; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.IntermediateRepresentation.OperandHelper; @@ -67,7 +68,7 @@ namespace ARMeilleure.Instructions Operand addr = GetIntA32(context, op.Rm); Operand bitOne = context.BitwiseAnd(addr, Const(1)); - addr = context.BitwiseOr(addr, Const(1)); // Set call flag. + addr = context.BitwiseOr(addr, Const(CallFlag)); // Set call flag. bool isThumb = IsThumb(context.CurrOp); diff --git a/ARMeilleure/Instructions/InstEmitHelper.cs b/ARMeilleure/Instructions/InstEmitHelper.cs index dfea52a698..069e2527a4 100644 --- a/ARMeilleure/Instructions/InstEmitHelper.cs +++ b/ARMeilleure/Instructions/InstEmitHelper.cs @@ -155,11 +155,11 @@ namespace ARMeilleure.Instructions context.BranchIfTrue(lblArmMode, mode); // Make this count as a call, the translator will ignore the low bit for the address. - context.Return(context.ZeroExtend32(OperandType.I64, context.BitwiseOr(pc, Const(1)))); + context.Return(context.ZeroExtend32(OperandType.I64, context.BitwiseOr(pc, Const(InstEmitFlowHelper.CallFlag)))); context.MarkLabel(lblArmMode); - context.Return(context.ZeroExtend32(OperandType.I64, context.BitwiseOr(context.BitwiseAnd(pc, Const(~3)), Const(1)))); + context.Return(context.ZeroExtend32(OperandType.I64, context.BitwiseOr(context.BitwiseAnd(pc, Const(~3)), Const(InstEmitFlowHelper.CallFlag)))); } public static Operand GetIntOrZR(ArmEmitterContext context, int regIndex) diff --git a/ARMeilleure/Instructions/InstEmitMemoryEx.cs b/ARMeilleure/Instructions/InstEmitMemoryEx.cs index bcca7619d2..93c20cb588 100644 --- a/ARMeilleure/Instructions/InstEmitMemoryEx.cs +++ b/ARMeilleure/Instructions/InstEmitMemoryEx.cs @@ -5,6 +5,7 @@ using System; using System.Diagnostics; using static ARMeilleure.Instructions.InstEmitHelper; +using static ARMeilleure.Instructions.InstEmitMemoryExHelper; using static ARMeilleure.IntermediateRepresentation.OperandHelper; namespace ARMeilleure.Instructions @@ -66,7 +67,7 @@ namespace ARMeilleure.Instructions // method to read 128-bits atomically. if (op.Size == 2) { - Operand value = EmitLoad(context, address, exclusive, 3); + Operand value = EmitLoadExclusive(context, address, exclusive, 3); Operand valueLow = context.ConvertI64ToI32(value); @@ -79,7 +80,7 @@ namespace ARMeilleure.Instructions } else if (op.Size == 3) { - Operand value = EmitLoad(context, address, exclusive, 4); + Operand value = EmitLoadExclusive(context, address, exclusive, 4); Operand valueLow = context.VectorExtract(OperandType.I64, value, 0); Operand valueHigh = context.VectorExtract(OperandType.I64, value, 1); @@ -95,46 +96,11 @@ namespace ARMeilleure.Instructions else { // 8, 16, 32 or 64-bits (non-pairwise) load. - Operand value = EmitLoad(context, address, exclusive, op.Size); + Operand value = EmitLoadExclusive(context, address, exclusive, op.Size); SetIntOrZR(context, op.Rt, value); } } - - private static Operand EmitLoad( - ArmEmitterContext context, - Operand address, - bool exclusive, - int size) - { - Delegate fallbackMethodDlg = 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; - } - } - 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; - } - } - - return context.Call(fallbackMethodDlg, address); - } - public static void Pfrm(ArmEmitterContext context) { // Memory Prefetch, execute as no-op. @@ -192,11 +158,11 @@ namespace ARMeilleure.Instructions value = context.VectorInsert(value, t2, 1); } - s = EmitStore(context, address, value, exclusive, op.Size + 1); + s = EmitStoreExclusive(context, address, value, exclusive, op.Size + 1); } else { - s = EmitStore(context, address, t, exclusive, op.Size); + s = EmitStoreExclusive(context, address, t, exclusive, op.Size); } if (s != null) @@ -207,50 +173,6 @@ namespace ARMeilleure.Instructions } } - private static Operand EmitStore( - ArmEmitterContext context, - Operand address, - Operand value, - bool exclusive, - int size) - { - if (size < 3) - { - value = context.ConvertI64ToI32(value); - } - - Delegate fallbackMethodDlg = 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; - } - - return context.Call(fallbackMethodDlg, 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; - } - - context.Call(fallbackMethodDlg, address, value); - - return null; - } - } - private static void EmitBarrier(ArmEmitterContext context) { // Note: This barrier is most likely not necessary, and probably diff --git a/ARMeilleure/Instructions/InstEmitMemoryEx32.cs b/ARMeilleure/Instructions/InstEmitMemoryEx32.cs index 004c06f093..0ab990f872 100644 --- a/ARMeilleure/Instructions/InstEmitMemoryEx32.cs +++ b/ARMeilleure/Instructions/InstEmitMemoryEx32.cs @@ -2,9 +2,9 @@ using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; -using System; using static ARMeilleure.Instructions.InstEmitHelper; +using static ARMeilleure.Instructions.InstEmitMemoryExHelper; using static ARMeilleure.IntermediateRepresentation.OperandHelper; namespace ARMeilleure.Instructions @@ -153,7 +153,7 @@ namespace ARMeilleure.Instructions // Keep loads atomic - make the call to get the whole region and then decompose it into parts // for the registers. - Operand value = EmitExLoad(context, address, exclusive, size); + Operand value = EmitLoadExclusive(context, address, exclusive, size); Operand valueLow = context.ConvertI64ToI32(value); @@ -180,7 +180,7 @@ namespace ARMeilleure.Instructions } else { - SetIntA32(context, op.Rt, EmitExLoad(context, address, exclusive, size)); + SetIntA32(context, op.Rt, EmitLoadExclusive(context, address, exclusive, size)); } } else @@ -198,7 +198,7 @@ namespace ARMeilleure.Instructions context.BranchIfTrue(lblBigEndian, GetFlag(PState.EFlag)); Operand leResult = context.BitwiseOr(lo, context.ShiftLeft(hi, Const(32))); - Operand leS = EmitExStore(context, address, leResult, exclusive, size); + Operand leS = EmitStoreExclusive(context, address, leResult, exclusive, size); if (exclusive) { SetIntA32(context, op.Rd, leS); @@ -209,7 +209,7 @@ namespace ARMeilleure.Instructions context.MarkLabel(lblBigEndian); Operand beResult = context.BitwiseOr(hi, context.ShiftLeft(lo, Const(32))); - Operand beS = EmitExStore(context, address, beResult, exclusive, size); + Operand beS = EmitStoreExclusive(context, address, beResult, exclusive, size); if (exclusive) { SetIntA32(context, op.Rd, beS); @@ -219,7 +219,7 @@ namespace ARMeilleure.Instructions } else { - Operand s = EmitExStore(context, address, context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rt)), exclusive, size); + Operand s = EmitStoreExclusive(context, address, context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rt)), exclusive, size); // This is only needed for exclusive stores. The function returns 0 // when the store is successful, and 1 otherwise. if (exclusive) @@ -230,84 +230,6 @@ namespace ARMeilleure.Instructions } } - private static Operand EmitExLoad( - ArmEmitterContext context, - Operand address, - bool exclusive, - int size) - { - Delegate fallbackMethodDlg = 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; - } - } - 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; - } - } - - return context.Call(fallbackMethodDlg, address); - } - - private static Operand EmitExStore( - ArmEmitterContext context, - Operand address, - Operand value, - bool exclusive, - int size) - { - if (size < 3) - { - value = context.ConvertI64ToI32(value); - } - - Delegate fallbackMethodDlg = 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; - } - - return context.Call(fallbackMethodDlg, 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; - } - - context.Call(fallbackMethodDlg, address, value); - - return null; - } - } - private static void EmitBarrier(ArmEmitterContext context) { // Note: This barrier is most likely not necessary, and probably diff --git a/ARMeilleure/Instructions/InstEmitMemoryExHelper.cs b/ARMeilleure/Instructions/InstEmitMemoryExHelper.cs new file mode 100644 index 0000000000..00a5385bdf --- /dev/null +++ b/ARMeilleure/Instructions/InstEmitMemoryExHelper.cs @@ -0,0 +1,87 @@ +using ARMeilleure.IntermediateRepresentation; +using ARMeilleure.Translation; +using System; + +namespace ARMeilleure.Instructions +{ + static class InstEmitMemoryExHelper + { + public static Operand EmitLoadExclusive( + ArmEmitterContext context, + Operand address, + bool exclusive, + int size) + { + Delegate fallbackMethodDlg = 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; + } + } + 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; + } + } + + return context.Call(fallbackMethodDlg, address); + } + + public static Operand EmitStoreExclusive( + ArmEmitterContext context, + Operand address, + Operand value, + bool exclusive, + int size) + { + if (size < 3) + { + value = context.ConvertI64ToI32(value); + } + + Delegate fallbackMethodDlg = 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; + } + + return context.Call(fallbackMethodDlg, 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; + } + + context.Call(fallbackMethodDlg, address, value); + + return null; + } + } + } +}