public static void Icmp(EmitterContext context) { OpCode op = context.CurrOp; bool isSigned = op.RawOpCode.Extract(48); IntegerCondition cmpOp = (IntegerCondition)op.RawOpCode.Extract(49, 3); Operand srcA = GetSrcA(context); Operand srcB = GetSrcB(context); Operand srcC = GetSrcC(context); Operand cmpRes = GetIntComparison(context, cmpOp, srcC, Const(0), isSigned); Operand res = context.ConditionalSelect(cmpRes, srcA, srcB); context.Copy(GetDest(context), res); }
public static void Isetp(EmitterContext context) { OpCodeSet op = (OpCodeSet)context.CurrOp; bool isSigned = op.RawOpCode.Extract(48); IntegerCondition cmpOp = (IntegerCondition)op.RawOpCode.Extract(49, 3); Operand srcA = GetSrcA(context); Operand srcB = GetSrcB(context); Operand p0Res = GetIntComparison(context, cmpOp, srcA, srcB, isSigned, op.Extended); Operand p1Res = context.BitwiseNot(p0Res); Operand pred = GetPredicate39(context); p0Res = GetPredLogicalOp(context, op.LogicalOp, p0Res, pred); p1Res = GetPredLogicalOp(context, op.LogicalOp, p1Res, pred); context.Copy(Register(op.Predicate3), p0Res); context.Copy(Register(op.Predicate0), p1Res); }
public static void Iset(EmitterContext context) { OpCodeSet op = (OpCodeSet)context.CurrOp; bool boolFloat = op.RawOpCode.Extract(44); bool isSigned = op.RawOpCode.Extract(48); IntegerCondition cmpOp = (IntegerCondition)op.RawOpCode.Extract(49, 3); Operand srcA = GetSrcA(context); Operand srcB = GetSrcB(context); Operand res = GetIntComparison(context, cmpOp, srcA, srcB, isSigned); Operand pred = GetPredicate39(context); res = GetPredLogicalOp(context, op.LogicalOp, res, pred); Operand dest = GetDest(context); if (boolFloat) { res = context.ConditionalSelect(res, ConstF(1), Const(0)); context.Copy(dest, res); SetFPZnFlags(context, res, op.SetCondCode); } else { context.Copy(dest, res); SetZnFlags(context, res, op.SetCondCode, op.Extended); } // TODO: X }
private static Operand GetIntComparisonExtended( EmitterContext context, IntegerCondition cond, Operand srcA, Operand srcB, bool isSigned) { Operand res; if (cond == IntegerCondition.Always) { res = Const(IrConsts.True); } else if (cond == IntegerCondition.Never) { res = Const(IrConsts.False); } else { res = context.ISubtract(srcA, srcB); res = context.IAdd(res, context.BitwiseNot(GetCF())); switch (cond) { case Decoders.IntegerCondition.Equal: // r = xh == yh && xl == yl res = context.BitwiseAnd(context.ICompareEqual(srcA, srcB), GetZF()); break; case Decoders.IntegerCondition.Less: // r = xh < yh || (xh == yh && xl < yl) Operand notC = context.BitwiseNot(GetCF()); Operand prevLt = context.BitwiseAnd(context.ICompareEqual(srcA, srcB), notC); res = isSigned ? context.BitwiseOr(context.ICompareLess(srcA, srcB), prevLt) : context.BitwiseOr(context.ICompareLessUnsigned(srcA, srcB), prevLt); break; case Decoders.IntegerCondition.LessOrEqual: // r = xh < yh || (xh == yh && xl <= yl) Operand zOrNotC = context.BitwiseOr(GetZF(), context.BitwiseNot(GetCF())); Operand prevLe = context.BitwiseAnd(context.ICompareEqual(srcA, srcB), zOrNotC); res = isSigned ? context.BitwiseOr(context.ICompareLess(srcA, srcB), prevLe) : context.BitwiseOr(context.ICompareLessUnsigned(srcA, srcB), prevLe); break; case Decoders.IntegerCondition.Greater: // r = xh > yh || (xh == yh && xl > yl) Operand notZAndC = context.BitwiseAnd(context.BitwiseNot(GetZF()), GetCF()); Operand prevGt = context.BitwiseAnd(context.ICompareEqual(srcA, srcB), notZAndC); res = isSigned ? context.BitwiseOr(context.ICompareGreater(srcA, srcB), prevGt) : context.BitwiseOr(context.ICompareGreaterUnsigned(srcA, srcB), prevGt); break; case Decoders.IntegerCondition.GreaterOrEqual: // r = xh > yh || (xh == yh && xl >= yl) Operand prevGe = context.BitwiseAnd(context.ICompareEqual(srcA, srcB), GetCF()); res = isSigned ? context.BitwiseOr(context.ICompareGreater(srcA, srcB), prevGe) : context.BitwiseOr(context.ICompareGreaterUnsigned(srcA, srcB), prevGe); break; case Decoders.IntegerCondition.NotEqual: // r = xh != yh || xl != yl context.BitwiseOr(context.ICompareNotEqual(srcA, srcB), context.BitwiseNot(GetZF())); break; default: throw new InvalidOperationException($"Unexpected condition \"{cond}\"."); } } return(res); }