s.insertBefore(MIR_Move.create(IA32_MOV, R(th), R(xh))); s.insertBefore(MIR_BinaryAcc.create(IA32_XOR, R(th), yh)); s.insertBefore(MIR_BinaryAcc.create(IA32_OR, R(th), R(xl)));
s.insertBefore(MIR_Move.create(IA32_MOV, new OPT_RegisterOperand(th, VM_TypeReference.Int), new OPT_RegisterOperand(xh, VM_TypeReference.Int))); s.insertBefore(MIR_BinaryAcc.create(IA32_XOR, new OPT_RegisterOperand(th, VM_TypeReference.Int), yh)); s.insertBefore(MIR_BinaryAcc.create(IA32_OR, new OPT_RegisterOperand(th, VM_TypeReference.Int), new OPT_RegisterOperand(xl, VM_TypeReference.Int)));
  private static OPT_Instruction long_ifcmp_imm(OPT_Instruction s, OPT_IR ir) {    OPT_Instruction nextInstr = s.nextInstructionInCodeOrder();    OPT_ConditionOperand cond = IfCmp.getCond(s);    OPT_Register xh = ((OPT_RegisterOperand)IfCmp.getVal1(s)).register;    OPT_Register xl = ir.regpool.getSecondReg(xh);    OPT_LongConstantOperand rhs = (OPT_LongConstantOperand)IfCmp.getVal2(s);    int low = rhs.lower32();    int high = rhs.upper32();    OPT_IntConstantOperand yh = IC(high);    OPT_IntConstantOperand yl = IC(low);        if (cond.isEQUAL() || cond.isNOT_EQUAL()) {      // tricky... ((xh^yh)|(xl^yl) == 0) <==> (lhll == rhrl)!!      OPT_Register th = ir.regpool.getInteger();      OPT_Register tl = ir.regpool.getInteger();      if (high == 0) {        if (low == 0) { // 0,0          s.insertBefore(MIR_Move.create(IA32_MOV, R(th), R(xh)));          s.insertBefore(MIR_BinaryAcc.create(IA32_OR, R(th), R(xl)));        } else if (low == -1) { // 0,-1          s.insertBefore(MIR_Move.create(IA32_MOV, R(tl), R(xl)));          s.insertBefore(MIR_UnaryAcc.create(IA32_NOT, R(tl)));          s.insertBefore(MIR_BinaryAcc.create(IA32_OR, R(tl), R(xh)));        } else { // 0,*          s.insertBefore(MIR_Move.create(IA32_MOV, R(tl), R(xl)));          s.insertBefore(MIR_BinaryAcc.create(IA32_XOR, R(tl), yl));          s.insertBefore(MIR_BinaryAcc.create(IA32_OR, R(tl), R(xh)));        }      } else if (high == -1) {        if (low == 0) { // -1,0          s.insertBefore(MIR_Move.create(IA32_MOV, R(th), R(xh)));          s.insertBefore(MIR_UnaryAcc.create(IA32_NOT, R(th)));          s.insertBefore(MIR_BinaryAcc.create(IA32_OR, R(th), R(xl)));        } else if (low == -1) { // -1,-1          s.insertBefore(MIR_Move.create(IA32_MOV, R(th), R(xh)));          s.insertBefore(MIR_UnaryAcc.create(IA32_NOT, R(th)));          s.insertBefore(MIR_Move.create(IA32_MOV, R(tl), R(xl)));          s.insertBefore(MIR_UnaryAcc.create(IA32_NOT, R(tl)));          s.insertBefore(MIR_BinaryAcc.create(IA32_OR, R(th), R(tl)));        } else { // -1,*          s.insertBefore(MIR_Move.create(IA32_MOV, R(th), R(xh)));          s.insertBefore(MIR_UnaryAcc.create(IA32_NOT, R(th)));          s.insertBefore(MIR_Move.create(IA32_MOV, R(tl), R(xl)));          s.insertBefore(MIR_BinaryAcc.create(IA32_XOR, R(tl), yl));          s.insertBefore(MIR_BinaryAcc.create(IA32_OR, R(th), R(tl)));        }      } else {         if (low == 0) { // *,0          s.insertBefore(MIR_Move.create(IA32_MOV, R(th), R(xh)));          s.insertBefore(MIR_BinaryAcc.create(IA32_XOR, R(th), yh));          s.insertBefore(MIR_BinaryAcc.create(IA32_OR, R(th), R(xl)));        } else if (low == -1) { // *,-1          s.insertBefore(MIR_Move.create(IA32_MOV, R(th), R(xh)));          s.insertBefore(MIR_BinaryAcc.create(IA32_XOR, R(th), yh));          s.insertBefore(MIR_Move.create(IA32_MOV, R(tl), R(xl)));          s.insertBefore(MIR_UnaryAcc.create(IA32_NOT, R(tl)));          s.insertBefore(MIR_BinaryAcc.create(IA32_OR, R(th), R(tl)));        } else { // neither high nor low is special          s.insertBefore(MIR_Move.create(IA32_MOV, R(th), R(xh)));          s.insertBefore(MIR_BinaryAcc.create(IA32_XOR, R(th), yh));          s.insertBefore(MIR_Move.create(IA32_MOV, R(tl), R(xl)));          s.insertBefore(MIR_BinaryAcc.create(IA32_XOR, R(tl), yl));          s.insertBefore(MIR_BinaryAcc.create(IA32_OR, R(th), R(tl)));        }      }      MIR_CondBranch.mutate(s, IA32_JCC,                             new OPT_IA32ConditionOperand(cond),                            IfCmp.getTarget(s),                            IfCmp.getBranchProfile(s));      return nextInstr;    } else {      // pick up a few special cases where the sign of xh is sufficient      if (rhs.value == 0L) {        if (cond.isLESS()) {          // xh < 0 implies true          s.insertBefore(MIR_Compare.create(IA32_CMP, R(xh), IC(0)));          MIR_CondBranch.mutate(s, IA32_JCC,                                OPT_IA32ConditionOperand.LT(),                                IfCmp.getTarget(s),                                IfCmp.getBranchProfile(s));          return nextInstr;        } else if (cond.isGREATER_EQUAL()) {          s.insertBefore(MIR_Compare.create(IA32_CMP, R(xh), IC(0)));          MIR_CondBranch.mutate(s, IA32_JCC,                                OPT_IA32ConditionOperand.GE(),                                IfCmp.getTarget(s),                                IfCmp.getBranchProfile(s));          return nextInstr;        }      } else if (rhs.value == -1L) {        if (cond.isLESS_EQUAL()) {          s.insertBefore(MIR_Compare.create(IA32_CMP, R(xh), IC(-1)));          MIR_CondBranch.mutate(s, IA32_JCC,                                OPT_IA32ConditionOperand.LE(),                                IfCmp.getTarget(s),                                IfCmp.getBranchProfile(s));          return nextInstr;        } else if (cond.isGREATER()) {          s.insertBefore(MIR_Compare.create(IA32_CMP, R(xh), IC(0)));          MIR_CondBranch.mutate(s, IA32_JCC,                                OPT_IA32ConditionOperand.GE(),                                IfCmp.getTarget(s),                                IfCmp.getBranchProfile(s));          return nextInstr;        }      }      basic_long_ifcmp(s, ir, cond, xh, xl, yh, yl);      return nextInstr;    }  }