private static void EmitSat(ArmEmitterContext context, int intMin, int intMax) { OpCode32Sat op = (OpCode32Sat)context.CurrOp; Operand n = GetIntA32(context, op.Rn); int shift = DecodeImmShift(op.ShiftType, op.Imm5); switch (op.ShiftType) { case ShiftType.Lsl: if (shift == 32) { n = Const(0); } else { n = context.ShiftLeft(n, Const(shift)); } break; case ShiftType.Asr: if (shift == 32) { n = context.ShiftRightSI(n, Const(31)); } else { n = context.ShiftRightSI(n, Const(shift)); } break; } Operand lblCheckLtIntMin = Label(); Operand lblNoSat = Label(); Operand lblEnd = Label(); context.BranchIfFalse(lblCheckLtIntMin, context.ICompareGreater(n, Const(intMax))); SetFlag(context, PState.QFlag, Const(1)); SetIntA32(context, op.Rd, Const(intMax)); context.Branch(lblEnd); context.MarkLabel(lblCheckLtIntMin); context.BranchIfFalse(lblNoSat, context.ICompareLess(n, Const(intMin))); SetFlag(context, PState.QFlag, Const(1)); SetIntA32(context, op.Rd, Const(intMin)); context.Branch(lblEnd); context.MarkLabel(lblNoSat); SetIntA32(context, op.Rd, n); context.MarkLabel(lblEnd); }
public static void Usat(ArmEmitterContext context) { OpCode32Sat op = (OpCode32Sat)context.CurrOp; EmitSat(context, 0, op.SatImm == 32 ? (int)(~0) : (1 << op.SatImm) - 1); }
public static void Ssat(ArmEmitterContext context) { OpCode32Sat op = (OpCode32Sat)context.CurrOp; EmitSat(context, -(1 << op.SatImm), (1 << op.SatImm) - 1); }