public static void Vminnm_V(ArmEmitterContext context) { EmitVectorBinaryOpSx32(context, (op1, op2) => EmitSoftFloatCallDefaultFpscr(context, SoftFloat32.FPMinNumFpscr, SoftFloat64.FPMinNumFpscr, op1, op2)); }
public static void EmitNZFlagsCheck(ArmEmitterContext context, Operand d) { SetFlag(context, PState.NFlag, context.ICompareLess(d, Const(d.Type, 0))); SetFlag(context, PState.ZFlag, context.ICompareEqual(d, Const(d.Type, 0))); }
private static void SetCarryMLsb(ArmEmitterContext context, Operand m) { SetFlag(context, PState.CFlag, context.BitwiseAnd(m, Const(1))); }
public static void Vmls_I(ArmEmitterContext context) { EmitVectorTernaryOpZx32(context, (op1, op2, op3) => context.Subtract(op1, context.Multiply(op2, op3))); }
public static void Vmull_1(ArmEmitterContext context) { OpCode32SimdRegElem op = (OpCode32SimdRegElem)context.CurrOp; EmitVectorByScalarLongOpI32(context, (op1, op2) => context.Multiply(op1, op2), !op.U); }
public static void Svc(ArmEmitterContext context) { EmitExceptionCall(context, nameof(NativeInterface.SupervisorCall)); }
public static void Vmovn(ArmEmitterContext context) { EmitVectorUnaryNarrowOp32(context, (op1) => op1); }
public static void Cmlt_S(ArmEmitterContext context) { EmitCmpOp(context, (op1, op2) => context.ICompareLess(op1, op2), scalar: true); }
public static void Cmtst_S(ArmEmitterContext context) { EmitCmtstOp(context, scalar: true); }
public static void Vsub_I(ArmEmitterContext context) { EmitVectorBinaryOpZx32(context, (op1, op2) => context.Subtract(op1, op2)); }
public static void Vadd_I(ArmEmitterContext context) { EmitVectorBinaryOpZx32(context, (op1, op2) => context.Add(op1, op2)); }
public static void Vsub_S(ArmEmitterContext context) { EmitScalarBinaryOpF32(context, (op1, op2) => context.Subtract(op1, op2)); }
public static void Vpadd_I(ArmEmitterContext context) { OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp; EmitVectorPairwiseOpI32(context, (op1, op2) => context.Add(op1, op2), !op.U); }
public static void Vpadd_V(ArmEmitterContext context) { EmitVectorPairwiseOpF32(context, (op1, op2) => context.Add(op1, op2)); }
public static void EmitVectorTernaryOpZx32(ArmEmitterContext context, Func3I emit) { EmitVectorTernaryOpI32(context, emit, false); }
public static void Cmtst_V(ArmEmitterContext context) { EmitCmtstOp(context, scalar: false); }
public static Operand ExtractElement(ArmEmitterContext context, int reg, int size, bool signed) { return(EmitVectorExtract32(context, reg >> (4 - size), reg & ((16 >> size) - 1), size, signed)); }
public static void Fccmp_S(ArmEmitterContext context) { EmitFccmpOrFccmpe(context, signalNaNs: false); }
public static void Trap(ArmEmitterContext context) { EmitExceptionCall(context, nameof(NativeInterface.Break)); }
public static void Fcmpe_S(ArmEmitterContext context) { EmitFcmpOrFcmpe(context, signalNaNs: true); }
private static Operand EmitAbs(ArmEmitterContext context, Operand value) { Operand isPositive = context.ICompareGreaterOrEqual(value, Const(value.Type, 0)); return(context.ConditionalSelect(isPositive, value, context.Negate(value))); }
private static void EmitFcmpOrFcmpe(ArmEmitterContext context, bool signalNaNs) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; const int cmpOrdered = 7; bool cmpWithZero = !(op is OpCodeSimdFcond) ? op.Bit3 : false; if (Optimizations.FastFP && Optimizations.UseSse2) { Operand n = GetVec(op.Rn); Operand m = cmpWithZero ? context.VectorZero() : GetVec(op.Rm); Operand lblNaN = Label(); Operand lblEnd = Label(); if (op.Size == 0) { Operand ordMask = context.AddIntrinsic(Intrinsic.X86Cmpss, n, m, Const(cmpOrdered)); Operand isOrdered = context.VectorExtract16(ordMask, 0); context.BranchIfFalse(lblNaN, isOrdered); Operand cf = context.AddIntrinsicInt(Intrinsic.X86Comissge, n, m); Operand zf = context.AddIntrinsicInt(Intrinsic.X86Comisseq, n, m); Operand nf = context.AddIntrinsicInt(Intrinsic.X86Comisslt, n, m); SetFlag(context, PState.VFlag, Const(0)); SetFlag(context, PState.CFlag, cf); SetFlag(context, PState.ZFlag, zf); SetFlag(context, PState.NFlag, nf); } else /* if (op.Size == 1) */ { Operand ordMask = context.AddIntrinsic(Intrinsic.X86Cmpsd, n, m, Const(cmpOrdered)); Operand isOrdered = context.VectorExtract16(ordMask, 0); context.BranchIfFalse(lblNaN, isOrdered); Operand cf = context.AddIntrinsicInt(Intrinsic.X86Comisdge, n, m); Operand zf = context.AddIntrinsicInt(Intrinsic.X86Comisdeq, n, m); Operand nf = context.AddIntrinsicInt(Intrinsic.X86Comisdlt, n, m); SetFlag(context, PState.VFlag, Const(0)); SetFlag(context, PState.CFlag, cf); SetFlag(context, PState.ZFlag, zf); SetFlag(context, PState.NFlag, nf); } context.Branch(lblEnd); context.MarkLabel(lblNaN); SetFlag(context, PState.VFlag, Const(1)); SetFlag(context, PState.CFlag, Const(1)); SetFlag(context, PState.ZFlag, Const(0)); SetFlag(context, PState.NFlag, Const(0)); context.MarkLabel(lblEnd); } else { OperandType type = op.Size != 0 ? OperandType.FP64 : OperandType.FP32; Operand ne = context.VectorExtract(type, GetVec(op.Rn), 0); Operand me; if (cmpWithZero) { me = op.Size == 0 ? ConstF(0f) : ConstF(0d); } else { 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)); EmitSetNzcv(context, nzcv); } }
public static void Vmlsl_I(ArmEmitterContext context) { OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp; EmitVectorTernaryLongOpI32(context, (opD, op1, op2) => context.Subtract(opD, context.Multiply(op1, op2)), !op.U); }
public static void Cmge_S(ArmEmitterContext context) { EmitCmpOp(context, (op1, op2) => context.ICompareGreaterOrEqual(op1, op2), scalar: true); }
public static Operand GetAluM(ArmEmitterContext context, bool setCarry = true) { switch (context.CurrOp) { // ARM32. case OpCode32AluImm op: { if (op.SetFlags && op.IsRotated) { SetFlag(context, PState.CFlag, Const((uint)op.Immediate >> 31)); } return(Const(op.Immediate)); } case OpCode32AluRsImm op: return(GetMShiftedByImmediate(context, op, setCarry)); case OpCodeT16AluImm8 op: return(Const(op.Immediate)); // ARM64. case IOpCodeAluImm op: { if (op.GetOperandType() == OperandType.I32) { return(Const((int)op.Immediate)); } else { return(Const(op.Immediate)); } } case IOpCodeAluRs op: { Operand value = GetIntOrZR(context, op.Rm); switch (op.ShiftType) { case ShiftType.Lsl: value = context.ShiftLeft(value, Const(op.Shift)); break; case ShiftType.Lsr: value = context.ShiftRightUI(value, Const(op.Shift)); break; case ShiftType.Asr: value = context.ShiftRightSI(value, Const(op.Shift)); break; case ShiftType.Ror: value = context.RotateRight(value, Const(op.Shift)); break; } return(value); } case IOpCodeAluRx op: { Operand value = GetExtendedM(context, op.Rm, op.IntType); value = context.ShiftLeft(value, Const(op.Shift)); return(value); } default: throw InvalidOpCodeType(context.CurrOp); } }
public static Operand EmitVectorExtractZx32(ArmEmitterContext context, int reg, int index, int size) { return(EmitVectorExtract32(context, reg, index, size, false)); }
public static void EmitAddsCCheck(ArmEmitterContext context, Operand n, Operand d) { // C = Rd < Rn SetFlag(context, PState.CFlag, context.ICompareLessUI(d, n)); }
public static void EmitVectorBinaryOpSx32(ArmEmitterContext context, Func2I emit) { EmitVectorBinaryOpI32(context, emit, true); }
private static void SetCarryMMsb(ArmEmitterContext context, Operand m) { SetFlag(context, PState.CFlag, context.ShiftRightUI(m, Const(31))); }
public static void Vminnm_S(ArmEmitterContext context) { EmitScalarBinaryOpF32(context, (op1, op2) => EmitSoftFloatCall(context, SoftFloat32.FPMinNum, SoftFloat64.FPMinNum, op1, op2)); }