public static void Mcr(ArmEmitterContext context) { OpCode32System op = (OpCode32System)context.CurrOp; if (op.Coproc != 15) { InstEmit.Und(context); return; } if (op.Opc1 != 0) { throw new NotImplementedException($"Unknown MRC Opc1 0x{op.Opc1:X16} at 0x{op.Address:X16}."); } MethodInfo info; switch (op.CRn) { case 13: // Process and Thread Info. if (op.CRm != 0) { throw new NotImplementedException($"Unknown MRC CRm 0x{op.CRm:X16} at 0x{op.Address:X16}."); } switch (op.Opc2) { case 2: 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: switch (op.CRm) // Cache and Memory barrier. { case 10: switch (op.Opc2) { 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: throw new NotImplementedException($"Unknown MRC 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); } context.Call(info, GetIntA32(context, op.Rt)); }
public static void Mrc(ArmEmitterContext context) { OpCode32System op = (OpCode32System)context.CurrOp; if (op.Coproc != 15) { InstEmit.Und(context); return; } if (op.Opc1 != 0) { throw new NotImplementedException($"Unknown MRC Opc1 0x{op.Opc1:X16} at 0x{op.Address:X16}."); } MethodInfo info; switch (op.CRn) { case 13: // Process and Thread Info. if (op.CRm != 0) { throw new NotImplementedException($"Unknown MRC CRm 0x{op.CRm:X16} at 0x{op.Address:X16}."); } switch (op.Opc2) { case 2: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidrEl032)); break; case 3: 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: 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(info)); return; } else { SetIntA32(context, op.Rt, context.Call(info)); } }
public static void Mrrc(ArmEmitterContext context) { OpCode32System op = (OpCode32System)context.CurrOp; if (op.Coproc != 15) { InstEmit.Und(context); return; } int opc = op.MrrcOp; MethodInfo info; switch (op.CRm) { case 14: // Timer. switch (opc) { case 0: 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: throw new NotImplementedException($"Unknown MRRC 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); } Operand result = context.Call(info); SetIntA32(context, op.Rt, context.ConvertI64ToI32(result)); SetIntA32(context, op.CRn, context.ConvertI64ToI32(context.ShiftRightUI(result, Const(32)))); }
private static void EmitSse41ConvertVector32(ArmEmitterContext context, FPRoundingMode roundMode, bool signed) { OpCode32Simd op = (OpCode32Simd)context.CurrOp; EmitVectorUnaryOpSimd32(context, (n) => { int sizeF = op.Size & 1; if (sizeF == 0) { Operand nRes = context.AddIntrinsic(Intrinsic.X86Cmpps, n, n, Const((int)CmpCondition.OrderedQ)); nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n); nRes = context.AddIntrinsic(Intrinsic.X86Roundps, nRes, Const(X86GetRoundControl(roundMode))); Operand zero = context.VectorZero(); Operand nCmp; if (!signed) { nCmp = context.AddIntrinsic(Intrinsic.X86Cmpps, nRes, zero, Const((int)CmpCondition.NotLessThanOrEqual)); nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, nCmp); } Operand fpMaxValMask = X86GetAllElements(context, 0x4F000000); // 2.14748365E9f (2147483648) Operand nInt = context.AddIntrinsic(Intrinsic.X86Cvtps2dq, nRes); Operand nInt2 = default; if (!signed) { nRes = context.AddIntrinsic(Intrinsic.X86Subps, nRes, fpMaxValMask); nCmp = context.AddIntrinsic(Intrinsic.X86Cmpps, nRes, zero, Const((int)CmpCondition.NotLessThanOrEqual)); nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, nCmp); nInt2 = context.AddIntrinsic(Intrinsic.X86Cvtps2dq, nRes); } nRes = context.AddIntrinsic(Intrinsic.X86Cmpps, nRes, fpMaxValMask, Const((int)CmpCondition.NotLessThan)); if (signed) { return(context.AddIntrinsic(Intrinsic.X86Pxor, nInt, nRes)); } else { Operand dRes = context.AddIntrinsic(Intrinsic.X86Pxor, nInt2, nRes); return(context.AddIntrinsic(Intrinsic.X86Paddd, dRes, nInt)); } } else /* if (sizeF == 1) */ { Operand nRes = context.AddIntrinsic(Intrinsic.X86Cmppd, n, n, Const((int)CmpCondition.OrderedQ)); nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n); nRes = context.AddIntrinsic(Intrinsic.X86Roundpd, nRes, Const(X86GetRoundControl(roundMode))); Operand zero = context.VectorZero(); Operand nCmp; if (!signed) { nCmp = context.AddIntrinsic(Intrinsic.X86Cmppd, nRes, zero, Const((int)CmpCondition.NotLessThanOrEqual)); nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, nCmp); } Operand fpMaxValMask = X86GetAllElements(context, 0x43E0000000000000L); // 9.2233720368547760E18d (9223372036854775808) Operand nLong = InstEmit.EmitSse2CvtDoubleToInt64OpF(context, nRes, false); Operand nLong2 = default; if (!signed) { nRes = context.AddIntrinsic(Intrinsic.X86Subpd, nRes, fpMaxValMask); nCmp = context.AddIntrinsic(Intrinsic.X86Cmppd, nRes, zero, Const((int)CmpCondition.NotLessThanOrEqual)); nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, nCmp); nLong2 = InstEmit.EmitSse2CvtDoubleToInt64OpF(context, nRes, false); } nRes = context.AddIntrinsic(Intrinsic.X86Cmppd, nRes, fpMaxValMask, Const((int)CmpCondition.NotLessThan)); if (signed) { return(context.AddIntrinsic(Intrinsic.X86Pxor, nLong, nRes)); } else { Operand dRes = context.AddIntrinsic(Intrinsic.X86Pxor, nLong2, nRes); return(context.AddIntrinsic(Intrinsic.X86Paddq, dRes, nLong)); } } }); }