Program: 150066
Project: 150066
Buggy source:
/** 
 * Given an instruction, attempt to simplify it. The instruction will be mutated in place. <p> We don't deal with branching operations here --  doing peephole optimizations of branches is the job of a separate module.
 * @param regpool register pool in case simplification requires a temporary register
 * @param s the instruction to simplify
 * @return one of UNCHANGED, MOVE_FOLDED, MOVE_REDUCED, TRAP_REDUCED, REDUCED
 */
public static byte simplify(OPT_AbstractRegisterPool regpool,OPT_Instruction s){
switch (s.getOpcode()) {
case GUARD_COMBINE_opcode:
{
      OPT_Operand op2=Binary.getVal2(s);
      if (op2 instanceof OPT_TrueGuardOperand) {
        OPT_Operand op1=Binary.getVal1(s);
        if (op1 instanceof OPT_TrueGuardOperand) {
          Move.mutate(s,GUARD_MOVE,Binary.getClearResult(s),op1);
          return MOVE_FOLDED;
        }
 else {
          Move.mutate(s,GUARD_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
          return MOVE_REDUCED;
        }
      }
    }
  return UNCHANGED;
case TRAP_IF_opcode:
{
  OPT_Operand op1=TrapIf.getVal1(s);
  OPT_Operand op2=TrapIf.getVal2(s);
  if (op1.isConstant()) {
    if (op2.isConstant()) {
      int willTrap=TrapIf.getCond(s).evaluate(op1,op2);
      if (willTrap == OPT_ConditionOperand.TRUE) {
        Trap.mutate(s,TRAP,TrapIf.getClearGuardResult(s),TrapIf.getClearTCode(s));
        return TRAP_REDUCED;
      }
 else       if (willTrap == OPT_ConditionOperand.FALSE) {
        Move.mutate(s,GUARD_MOVE,TrapIf.getClearGuardResult(s),TG());
        return MOVE_FOLDED;
      }
    }
 else {
      TrapIf.mutate(s,TRAP_IF,TrapIf.getClearGuardResult(s),TrapIf.getClearVal2(s),TrapIf.getClearVal1(s),TrapIf.getClearCond(s).flipOperands(),TrapIf.getClearTCode(s));
    }
  }
}
return UNCHANGED;
case NULL_CHECK_opcode:
{
OPT_Operand ref=NullCheck.getRef(s);
if (ref.isNullConstant()) {
Trap.mutate(s,TRAP,NullCheck.getClearGuardResult(s),OPT_TrapCodeOperand.NullPtr());
return TRAP_REDUCED;
}
 else if (ref.isStringConstant()) {
Move.mutate(s,GUARD_MOVE,NullCheck.getClearGuardResult(s),TG());
return MOVE_FOLDED;
}
 else if (ref.isAddressConstant()) {
if (ref.asAddressConstant().value.isZero()) {
  Trap.mutate(s,TRAP,NullCheck.getClearGuardResult(s),OPT_TrapCodeOperand.NullPtr());
  return TRAP_REDUCED;
}
 else {
  Move.mutate(s,GUARD_MOVE,NullCheck.getClearGuardResult(s),TG());
  return MOVE_FOLDED;
}
}
return UNCHANGED;
}
case INT_ZERO_CHECK_opcode:
{
OPT_Operand op=ZeroCheck.getValue(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
if (val == 0) {
Trap.mutate(s,TRAP,ZeroCheck.getClearGuardResult(s),OPT_TrapCodeOperand.DivByZero());
return TRAP_REDUCED;
}
 else {
Move.mutate(s,GUARD_MOVE,ZeroCheck.getClearGuardResult(s),TG());
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case LONG_ZERO_CHECK_opcode:
{
OPT_Operand op=ZeroCheck.getValue(s);
if (op.isLongConstant()) {
long val=op.asLongConstant().value;
if (val == 0L) {
Trap.mutate(s,TRAP,ZeroCheck.getClearGuardResult(s),OPT_TrapCodeOperand.DivByZero());
return TRAP_REDUCED;
}
 else {
Move.mutate(s,GUARD_MOVE,ZeroCheck.getClearGuardResult(s),TG());
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case CHECKCAST_opcode:
{
OPT_Operand ref=TypeCheck.getRef(s);
if (ref.isNullConstant()) {
Empty.mutate(s,NOP);
return REDUCED;
}
 else if (ref.isStringConstant()) {
s.operator=CHECKCAST_NOTNULL;
return simplify(regpool,s);
}
 else {
VM_TypeReference lhsType=TypeCheck.getType(s).getTypeRef();
VM_TypeReference rhsType=ref.getType();
byte ans=OPT_ClassLoaderProxy.includesType(lhsType,rhsType);
if (ans == OPT_Constants.YES) {
Empty.mutate(s,NOP);
return REDUCED;
}
}
}
return UNCHANGED;
case CHECKCAST_NOTNULL_opcode:
{
OPT_Operand ref=TypeCheck.getRef(s);
VM_TypeReference lhsType=TypeCheck.getType(s).getTypeRef();
VM_TypeReference rhsType=ref.getType();
byte ans=OPT_ClassLoaderProxy.includesType(lhsType,rhsType);
if (ans == OPT_Constants.YES) {
Empty.mutate(s,NOP);
return REDUCED;
}
 else if (ans == OPT_Constants.NO) {
VM_Type rType=rhsType.peekResolvedType();
if (rType != null && rType.isClassType() && rType.asClass().isFinal()) {
Trap.mutate(s,TRAP,null,OPT_TrapCodeOperand.CheckCast());
return TRAP_REDUCED;
}
}
}
return UNCHANGED;
case INSTANCEOF_opcode:
{
OPT_Operand ref=InstanceOf.getRef(s);
if (ref.isNullConstant()) {
Move.mutate(s,INT_MOVE,InstanceOf.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
 else if (ref.isStringConstant()) {
s.operator=INSTANCEOF_NOTNULL;
return simplify(regpool,s);
}
VM_TypeReference lhsType=InstanceOf.getType(s).getTypeRef();
VM_TypeReference rhsType=ref.getType();
byte ans=OPT_ClassLoaderProxy.includesType(lhsType,rhsType);
if (ans == OPT_Constants.NO) {
VM_Type rType=rhsType.peekResolvedType();
if (rType != null && rType.isClassType() && rType.asClass().isFinal()) {
Move.mutate(s,INT_MOVE,InstanceOf.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case INSTANCEOF_NOTNULL_opcode:
{
OPT_Operand ref=InstanceOf.getRef(s);
VM_TypeReference lhsType=InstanceOf.getType(s).getTypeRef();
VM_TypeReference rhsType=ref.getType();
byte ans=OPT_ClassLoaderProxy.includesType(lhsType,rhsType);
if (ans == OPT_Constants.YES) {
Move.mutate(s,INT_MOVE,InstanceOf.getClearResult(s),IC(1));
return MOVE_FOLDED;
}
 else if (ans == OPT_Constants.NO) {
VM_Type rType=rhsType.peekResolvedType();
if (rType != null && rType.isClassType() && rType.asClass().isFinal()) {
Move.mutate(s,INT_MOVE,InstanceOf.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case INT_COND_MOVE_opcode:
{
OPT_Operand val1=CondMove.getVal1(s);
OPT_Operand val2=CondMove.getVal2(s);
int cond=CondMove.getCond(s).evaluate(val1,val2);
if (cond != OPT_ConditionOperand.UNKNOWN) {
OPT_Operand val=(cond == OPT_ConditionOperand.TRUE) ? CondMove.getClearTrueValue(s) : CondMove.getClearFalseValue(s);
Move.mutate(s,INT_MOVE,CondMove.getClearResult(s),val);
return val.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (val1.isConstant() && !val2.isConstant()) {
OPT_Operand tmp=CondMove.getClearVal1(s);
CondMove.setVal1(s,CondMove.getClearVal2(s));
CondMove.setVal2(s,tmp);
CondMove.getCond(s).flipOperands();
}
OPT_Operand tv=CondMove.getTrueValue(s);
OPT_Operand fv=CondMove.getFalseValue(s);
if (tv.similar(fv)) {
Move.mutate(s,INT_MOVE,CondMove.getClearResult(s),tv);
return tv.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (tv.isIntConstant() && fv.isIntConstant() && !CondMove.getCond(s).isFLOATINGPOINT()) {
int itv=tv.asIntConstant().value;
int ifv=fv.asIntConstant().value;
OPT_Operator op=null;
if (val1.isLong()) {
op=BOOLEAN_CMP_LONG;
}
 else if (val1.isFloat()) {
op=BOOLEAN_CMP_FLOAT;
}
 else if (val1.isDouble()) {
op=BOOLEAN_CMP_DOUBLE;
}
 else {
op=BOOLEAN_CMP_INT;
}
if (itv == 1 && ifv == 0) {
BooleanCmp.mutate(s,op,CondMove.getClearResult(s),CondMove.getClearVal1(s),CondMove.getClearVal2(s),CondMove.getClearCond(s),new OPT_BranchProfileOperand());
return REDUCED;
}
if (itv == 0 && ifv == 1) {
BooleanCmp.mutate(s,op,CondMove.getClearResult(s),CondMove.getClearVal1(s),CondMove.getClearVal2(s),CondMove.getClearCond(s).flipCode(),new OPT_BranchProfileOperand());
return REDUCED;
}
}
}
return UNCHANGED;
case LONG_COND_MOVE_opcode:
{
OPT_Operand val1=CondMove.getVal1(s);
OPT_Operand val2=CondMove.getVal2(s);
int cond=CondMove.getCond(s).evaluate(val1,val2);
if (cond != OPT_ConditionOperand.UNKNOWN) {
OPT_Operand val=(cond == OPT_ConditionOperand.TRUE) ? CondMove.getClearTrueValue(s) : CondMove.getClearFalseValue(s);
Move.mutate(s,LONG_MOVE,CondMove.getClearResult(s),val);
return val.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (val1.isConstant() && !val2.isConstant()) {
OPT_Operand tmp=CondMove.getClearVal1(s);
CondMove.setVal1(s,CondMove.getClearVal2(s));
CondMove.setVal2(s,tmp);
CondMove.getCond(s).flipOperands();
}
OPT_Operand tv=CondMove.getTrueValue(s);
OPT_Operand fv=CondMove.getFalseValue(s);
if (tv.similar(fv)) {
Move.mutate(s,LONG_MOVE,CondMove.getClearResult(s),tv);
return tv.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (tv.isLongConstant() && fv.isLongConstant() && !CondMove.getCond(s).isFLOATINGPOINT()) {
long itv=tv.asLongConstant().value;
long ifv=fv.asLongConstant().value;
OPT_Operator op=null;
if (val1.isLong()) {
op=BOOLEAN_CMP_LONG;
}
 else if (val1.isFloat()) {
op=BOOLEAN_CMP_FLOAT;
}
 else if (val1.isDouble()) {
op=BOOLEAN_CMP_DOUBLE;
}
 else {
op=BOOLEAN_CMP_INT;
}
if (itv == 1 && ifv == 0) {
BooleanCmp.mutate(s,op,CondMove.getClearResult(s),CondMove.getClearVal1(s),CondMove.getClearVal2(s),CondMove.getClearCond(s),new OPT_BranchProfileOperand());
return REDUCED;
}
if (itv == 0 && ifv == 1) {
BooleanCmp.mutate(s,op,CondMove.getClearResult(s),CondMove.getClearVal1(s),CondMove.getClearVal2(s),CondMove.getClearCond(s).flipCode(),new OPT_BranchProfileOperand());
return REDUCED;
}
}
}
return UNCHANGED;
case FLOAT_COND_MOVE_opcode:
{
OPT_Operand val1=CondMove.getVal1(s);
OPT_Operand val2=CondMove.getVal2(s);
int cond=CondMove.getCond(s).evaluate(val1,val2);
if (cond != OPT_ConditionOperand.UNKNOWN) {
OPT_Operand val=(cond == OPT_ConditionOperand.TRUE) ? CondMove.getClearTrueValue(s) : CondMove.getClearFalseValue(s);
Move.mutate(s,FLOAT_MOVE,CondMove.getClearResult(s),val);
return val.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (val1.isConstant() && !val2.isConstant()) {
OPT_Operand tmp=CondMove.getClearVal1(s);
CondMove.setVal1(s,CondMove.getClearVal2(s));
CondMove.setVal2(s,tmp);
CondMove.getCond(s).flipOperands();
}
OPT_Operand tv=CondMove.getTrueValue(s);
OPT_Operand fv=CondMove.getFalseValue(s);
if (tv.similar(fv)) {
Move.mutate(s,FLOAT_MOVE,CondMove.getClearResult(s),tv);
return tv.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
}
return UNCHANGED;
case DOUBLE_COND_MOVE_opcode:
{
OPT_Operand val1=CondMove.getVal1(s);
OPT_Operand val2=CondMove.getVal2(s);
int cond=CondMove.getCond(s).evaluate(val1,val2);
if (cond != OPT_ConditionOperand.UNKNOWN) {
OPT_Operand val=(cond == OPT_ConditionOperand.TRUE) ? CondMove.getClearTrueValue(s) : CondMove.getClearFalseValue(s);
Move.mutate(s,DOUBLE_MOVE,CondMove.getClearResult(s),val);
return val.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (val1.isConstant() && !val2.isConstant()) {
OPT_Operand tmp=CondMove.getClearVal1(s);
CondMove.setVal1(s,CondMove.getClearVal2(s));
CondMove.setVal2(s,tmp);
CondMove.getCond(s).flipOperands();
}
OPT_Operand tv=CondMove.getTrueValue(s);
OPT_Operand fv=CondMove.getFalseValue(s);
if (tv.similar(fv)) {
Move.mutate(s,DOUBLE_MOVE,CondMove.getClearResult(s),tv);
return tv.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
}
return UNCHANGED;
case REF_COND_MOVE_opcode:
{
OPT_Operand val1=CondMove.getVal1(s);
if (val1.isConstant()) {
OPT_Operand val2=CondMove.getVal2(s);
if (val2.isConstant()) {
int cond=CondMove.getCond(s).evaluate(val1,val2);
if (cond != OPT_ConditionOperand.UNKNOWN) {
OPT_Operand val=(cond == OPT_ConditionOperand.TRUE) ? CondMove.getClearTrueValue(s) : CondMove.getClearFalseValue(s);
Move.mutate(s,REF_MOVE,CondMove.getClearResult(s),val);
return val.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
}
 else {
OPT_Operand tmp=CondMove.getClearVal1(s);
CondMove.setVal1(s,CondMove.getClearVal2(s));
CondMove.setVal2(s,tmp);
CondMove.getCond(s).flipOperands();
}
}
if (CondMove.getTrueValue(s).similar(CondMove.getFalseValue(s))) {
OPT_Operand val=CondMove.getClearTrueValue(s);
Move.mutate(s,REF_MOVE,CondMove.getClearResult(s),val);
return val.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
}
return UNCHANGED;
case GUARD_COND_MOVE_opcode:
{
OPT_Operand val1=CondMove.getVal1(s);
if (val1.isConstant()) {
OPT_Operand val2=CondMove.getVal2(s);
if (val2.isConstant()) {
int cond=CondMove.getCond(s).evaluate(val1,val2);
if (cond == OPT_ConditionOperand.UNKNOWN) {
OPT_Operand val=(cond == OPT_ConditionOperand.TRUE) ? CondMove.getClearTrueValue(s) : CondMove.getClearFalseValue(s);
Move.mutate(s,GUARD_MOVE,CondMove.getClearResult(s),val);
return val.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
}
 else {
OPT_Operand tmp=CondMove.getClearVal1(s);
CondMove.setVal1(s,CondMove.getClearVal2(s));
CondMove.setVal2(s,tmp);
CondMove.getCond(s).flipOperands();
}
}
if (CondMove.getTrueValue(s).similar(CondMove.getFalseValue(s))) {
OPT_Operand val=CondMove.getClearTrueValue(s);
Move.mutate(s,GUARD_MOVE,CondMove.getClearResult(s),val);
return val.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
}
return UNCHANGED;
case BOOLEAN_NOT_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
if (val == 0) {
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC(1));
}
 else {
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC(0));
}
return MOVE_FOLDED;
}
}
return UNCHANGED;
case BOOLEAN_CMP_INT_opcode:
if (CF_INT) {
OPT_Operand op1=BooleanCmp.getVal1(s);
OPT_Operand op2=BooleanCmp.getVal2(s);
if (op1.isConstant()) {
if (op2.isConstant()) {
int cond=BooleanCmp.getCond(s).evaluate(op1,op2);
if (cond != OPT_ConditionOperand.UNKNOWN) {
Move.mutate(s,INT_MOVE,BooleanCmp.getResult(s),(cond == OPT_ConditionOperand.TRUE) ? IC(1) : IC(0));
return MOVE_FOLDED;
}
}
 else {
OPT_Operand tmp=BooleanCmp.getClearVal1(s);
BooleanCmp.setVal1(s,BooleanCmp.getClearVal2(s));
BooleanCmp.setVal2(s,tmp);
BooleanCmp.getCond(s).flipOperands();
}
}
}
return UNCHANGED;
case BOOLEAN_CMP_ADDR_opcode:
if (CF_ADDR) {
OPT_Operand op1=BooleanCmp.getVal1(s);
OPT_Operand op2=BooleanCmp.getVal2(s);
if (op1.isConstant()) {
if (op2.isConstant()) {
int cond=BooleanCmp.getCond(s).evaluate(op1,op2);
if (cond != OPT_ConditionOperand.UNKNOWN) {
Move.mutate(s,REF_MOVE,BooleanCmp.getResult(s),(cond == OPT_ConditionOperand.TRUE) ? IC(1) : IC(0));
return MOVE_FOLDED;
}
}
 else {
OPT_Operand tmp=BooleanCmp.getClearVal1(s);
BooleanCmp.setVal1(s,BooleanCmp.getClearVal2(s));
BooleanCmp.setVal2(s,tmp);
BooleanCmp.getCond(s).flipOperands();
}
}
}
return UNCHANGED;
case INT_ADD_opcode:
if (CF_INT) {
canonicalizeCommutativeOperator(s);
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(val1 + val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case INT_AND_opcode:
if (CF_INT) {
canonicalizeCommutativeOperator(s);
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return op1.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(val1 & val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
if (val2 == -1) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case INT_DIV_opcode:
if (CF_INT) {
OPT_Operand op1=GuardedBinary.getVal1(s);
OPT_Operand op2=GuardedBinary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,INT_MOVE,GuardedBinary.getClearResult(s),IC(1));
return MOVE_FOLDED;
}
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
if (val2 == 0) {
return UNCHANGED;
}
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,GuardedBinary.getClearResult(s),IC(val1 / val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 1) {
Move.mutate(s,INT_MOVE,GuardedBinary.getClearResult(s),GuardedBinary.getClearVal1(s));
return MOVE_REDUCED;
}
int power=PowerOf2(val2);
if (power != -1) {
Binary.mutate(s,INT_SHR,GuardedBinary.getClearResult(s),GuardedBinary.getClearVal1(s),IC(power));
return REDUCED;
}
}
}
}
return UNCHANGED;
case INT_MUL_opcode:
if (CF_INT) {
canonicalizeCommutativeOperator(s);
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(val1 * val2));
return MOVE_FOLDED;
}
 else {
if (val2 == -1) {
Unary.mutate(s,INT_NEG,Binary.getClearResult(s),Binary.getClearVal1(s));
return REDUCED;
}
if (val2 == 0) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
if (val2 == 1) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
if (s.getPrev() != null) {
int cost=0;
for (int i=1; i < 32; i++) {
if ((val2 & (1 << i)) != 0) {
cost++;
}
}
if (cost < 5) {
OPT_RegisterOperand val1Operand=Binary.getClearVal1(s).asRegister();
OPT_RegisterOperand resultOperand=regpool.makeTempInt();
OPT_Instruction move;
if ((val2 & 1) == 1) {
move=Move.create(INT_MOVE,resultOperand,val1Operand);
}
 else {
move=Move.create(INT_MOVE,resultOperand,IC(0));
}
move.copyPosition(s);
s.insertBefore(move);
for (int i=1; i < 32; i++) {
if ((val2 & (1 << i)) != 0) {
OPT_RegisterOperand tempInt=regpool.makeTempInt();
OPT_Instruction shift=Binary.create(INT_SHL,tempInt,val1Operand.copyRO(),IC(i));
shift.copyPosition(s);
s.insertBefore(shift);
OPT_Instruction add=Binary.create(INT_ADD,resultOperand.copyRO(),resultOperand.copyRO(),tempInt.copyRO());
add.copyPosition(s);
s.insertBefore(add);
}
}
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),resultOperand.copyRO());
return REDUCED;
}
}
}
}
}
return UNCHANGED;
case INT_NEG_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC(-val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_NOT_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC(~val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_OR_opcode:
if (CF_INT) {
canonicalizeCommutativeOperator(s);
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return op1.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(val1 | val2));
return MOVE_FOLDED;
}
 else {
if (val2 == -1) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(-1));
return MOVE_FOLDED;
}
if (val2 == 0) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case INT_REM_opcode:
if (CF_INT) {
OPT_Operand op1=GuardedBinary.getVal1(s);
OPT_Operand op2=GuardedBinary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,INT_MOVE,GuardedBinary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
if (val2 == 0) {
return UNCHANGED;
}
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,GuardedBinary.getClearResult(s),IC(val1 % val2));
return MOVE_FOLDED;
}
 else {
if ((val2 == 1) || (val2 == -1)) {
Move.mutate(s,INT_MOVE,GuardedBinary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
int power=PowerOf2(val2);
if (power != -1) {
Binary.mutate(s,INT_AND,GuardedBinary.getClearResult(s),GuardedBinary.getClearVal1(s),IC(val2 - 1));
return REDUCED;
}
}
}
}
return UNCHANGED;
case INT_SHL_opcode:
if (CF_INT) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(val1 << val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
if (val2 >= 32) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
}
}
}
return UNCHANGED;
case INT_SHR_opcode:
if (CF_INT) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(val1 >> val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case INT_SUB_opcode:
if (CF_INT) {
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(val1 - val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
Binary.mutate(s,INT_ADD,Binary.getClearResult(s),Binary.getClearVal1(s),IC(-val2));
return REDUCED;
}
}
}
return UNCHANGED;
case INT_USHR_opcode:
if (CF_INT) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(val1 >>> val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
if (val2 >= 32) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
}
}
}
return UNCHANGED;
case INT_XOR_opcode:
if (CF_INT) {
canonicalizeCommutativeOperator(s);
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(val1 ^ val2));
return MOVE_FOLDED;
}
 else {
if (val2 == -1) {
Unary.mutate(s,INT_NOT,Binary.getClearResult(s),Binary.getClearVal1(s));
return REDUCED;
}
if (val2 == 0) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case REF_ADD_opcode:
if (CF_ADDR) {
canonicalizeCommutativeOperator(s);
OPT_Operand op2=Binary.getVal2(s);
if (op2.isConstant()) {
Address val2=getAddressValue(op2);
OPT_Operand op1=Binary.getVal1(s);
if (op1.isConstant()) {
Address val1=getAddressValue(op1);
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),AC(val1.add(val2.toWord().toOffset())));
return MOVE_FOLDED;
}
 else {
if (val2.isZero()) {
if (op1.isIntLike()) {
Unary.mutate(s,INT_2ADDRSigExt,Binary.getClearResult(s),Binary.getClearVal1(s));
}
 else {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
}
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case REF_AND_opcode:
if (CF_ADDR) {
canonicalizeCommutativeOperator(s);
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return op1.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (op2.isAddressConstant()) {
Word val2=op2.asAddressConstant().value.toWord();
if (op1.isAddressConstant()) {
Word val1=op1.asAddressConstant().value.toWord();
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),AC(val1.and(val2).toAddress()));
return MOVE_FOLDED;
}
 else {
if (val2.isZero()) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),AC(Address.zero()));
return MOVE_FOLDED;
}
if (val2.isMax()) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case REF_SHL_opcode:
if (CF_ADDR) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isAddressConstant()) {
Word val1=op1.asAddressConstant().value.toWord();
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),AC(val1.lsh(val2).toAddress()));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
if (val2 >= 32) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
}
}
}
return UNCHANGED;
case REF_SHR_opcode:
if (CF_ADDR) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isAddressConstant()) {
Word val1=op1.asAddressConstant().value.toWord();
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),AC(val1.rsha(val2).toAddress()));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case REF_NOT_opcode:
if (CF_ADDR) {
OPT_Operand op=Unary.getVal(s);
if (op.isAddressConstant()) {
Word val=op.asAddressConstant().value.toWord();
Move.mutate(s,REF_MOVE,Unary.getClearResult(s),AC(val.not().toAddress()));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case REF_OR_opcode:
if (CF_ADDR) {
canonicalizeCommutativeOperator(s);
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return op1.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (op2.isAddressConstant()) {
Word val2=op2.asAddressConstant().value.toWord();
if (op1.isAddressConstant()) {
Word val1=op1.asAddressConstant().value.toWord();
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),AC(val1.or(val2).toAddress()));
return MOVE_FOLDED;
}
 else {
if (val2.isMax()) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),AC(Address.max()));
return MOVE_FOLDED;
}
if (val2.isZero()) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case REF_SUB_opcode:
if (CF_ADDR) {
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
if (op2.isConstant()) {
Address val2=getAddressValue(op2);
if (op1.isConstant()) {
Address val1=getAddressValue(op1);
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),AC(val1.sub(val2.toWord().toOffset())));
return MOVE_FOLDED;
}
 else {
if (val2.isZero()) {
if (op1.isIntLike()) {
Unary.mutate(s,INT_2ADDRSigExt,Binary.getClearResult(s),Binary.getClearVal1(s));
}
 else {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
}
return MOVE_REDUCED;
}
Binary.mutate(s,REF_ADD,Binary.getClearResult(s),Binary.getClearVal1(s),AC(Address.zero().sub(val2.toWord().toOffset())));
return REDUCED;
}
}
}
return UNCHANGED;
case REF_USHR_opcode:
if (CF_ADDR) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isAddressConstant()) {
Word val1=op1.asAddressConstant().value.toWord();
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),AC(val1.rshl(val2).toAddress()));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
if (val2 >= 32) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
}
}
}
return UNCHANGED;
case REF_XOR_opcode:
if (CF_ADDR) {
canonicalizeCommutativeOperator(s);
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
if (op2.isAddressConstant()) {
Word val2=op2.asAddressConstant().value.toWord();
if (op1.isAddressConstant()) {
Word val1=op1.asAddressConstant().value.toWord();
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),AC(val1.xor(val2).toAddress()));
return MOVE_FOLDED;
}
 else {
if (val2.isMax()) {
Unary.mutate(s,REF_NOT,Binary.getClearResult(s),Binary.getClearVal1(s));
return REDUCED;
}
if (val2.isZero()) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case LONG_ADD_opcode:
if (CF_LONG) {
canonicalizeCommutativeOperator(s);
OPT_Operand op2=Binary.getVal2(s);
if (op2.isLongConstant()) {
long val2=op2.asLongConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(val1 + val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0L) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case LONG_AND_opcode:
if (CF_LONG) {
canonicalizeCommutativeOperator(s);
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return op1.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (op2.isLongConstant()) {
long val2=op2.asLongConstant().value;
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(val1 & val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0L) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(0L));
return MOVE_FOLDED;
}
if (val2 == -1) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case LONG_CMP_opcode:
if (CF_LONG) {
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
if (op2.isLongConstant()) {
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
long val2=op2.asLongConstant().value;
int result=(val1 > val2) ? 1 : ((val1 == val2) ? 0 : -1);
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(result));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case LONG_DIV_opcode:
if (CF_LONG) {
OPT_Operand op1=GuardedBinary.getVal1(s);
OPT_Operand op2=GuardedBinary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,LONG_MOVE,GuardedBinary.getClearResult(s),LC(1));
return MOVE_FOLDED;
}
if (op2.isLongConstant()) {
long val2=op2.asLongConstant().value;
if (val2 == 0L) {
return UNCHANGED;
}
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,GuardedBinary.getClearResult(s),LC(val1 / val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 1L) {
Move.mutate(s,LONG_MOVE,GuardedBinary.getClearResult(s),GuardedBinary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case LONG_MUL_opcode:
if (CF_LONG) {
canonicalizeCommutativeOperator(s);
OPT_Operand op2=Binary.getVal2(s);
if (op2.isLongConstant()) {
long val2=op2.asLongConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(val1 * val2));
return MOVE_FOLDED;
}
 else {
if (val2 == -1L) {
Move.mutate(s,LONG_NEG,Binary.getClearResult(s),Binary.getClearVal1(s));
return REDUCED;
}
if (val2 == 0L) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(0L));
return MOVE_FOLDED;
}
if (val2 == 1L) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case LONG_NEG_opcode:
if (CF_LONG) {
OPT_Operand op=Unary.getVal(s);
if (op.isLongConstant()) {
long val=op.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Unary.getClearResult(s),LC(-val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case LONG_NOT_opcode:
if (CF_LONG) {
OPT_Operand op=Unary.getVal(s);
if (op.isLongConstant()) {
long val=op.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(~val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case LONG_OR_opcode:
if (CF_LONG) {
canonicalizeCommutativeOperator(s);
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return op1.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (op2.isLongConstant()) {
long val2=op2.asLongConstant().value;
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(val1 | val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0L) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
if (val2 == -1L) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(-1L));
return MOVE_FOLDED;
}
}
}
}
return UNCHANGED;
case LONG_REM_opcode:
if (CF_LONG) {
OPT_Operand op1=GuardedBinary.getVal1(s);
OPT_Operand op2=GuardedBinary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,LONG_MOVE,GuardedBinary.getClearResult(s),LC(0));
return MOVE_FOLDED;
}
if (op2.isLongConstant()) {
long val2=op2.asLongConstant().value;
if (val2 == 0L) {
return UNCHANGED;
}
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,GuardedBinary.getClearResult(s),LC(val1 % val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 1L) {
Move.mutate(s,LONG_MOVE,GuardedBinary.getClearResult(s),LC(0));
return MOVE_FOLDED;
}
}
}
}
return UNCHANGED;
case LONG_SHL_opcode:
if (CF_LONG) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(val1 << val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
if (val2 >= 64) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),LC(0));
return MOVE_FOLDED;
}
}
}
}
return UNCHANGED;
case LONG_SHR_opcode:
if (CF_LONG) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(val1 >> val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case LONG_SUB_opcode:
if (CF_LONG) {
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(0));
return MOVE_FOLDED;
}
if (op2.isLongConstant()) {
long val2=op2.asLongConstant().value;
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(val1 - val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0L) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
Binary.mutate(s,LONG_ADD,Binary.getClearResult(s),Binary.getClearVal1(s),LC(-val2));
return REDUCED;
}
}
}
return UNCHANGED;
case LONG_USHR_opcode:
if (CF_LONG) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(val1 >>> val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
if (val2 >= 64) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(0));
return MOVE_FOLDED;
}
}
}
}
return UNCHANGED;
case LONG_XOR_opcode:
if (CF_LONG) {
canonicalizeCommutativeOperator(s);
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(0));
return MOVE_FOLDED;
}
if (op2.isLongConstant()) {
long val2=op2.asLongConstant().value;
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(val1 ^ val2));
return MOVE_FOLDED;
}
 else {
if (val2 == -1L) {
Unary.mutate(s,LONG_NOT,Binary.getClearResult(s),Binary.getClearVal1(s));
return REDUCED;
}
if (val2 == 0L) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case FLOAT_ADD_opcode:
if (CF_FLOAT) {
canonicalizeCommutativeOperator(s);
OPT_Operand op2=Binary.getVal2(s);
if (op2.isFloatConstant()) {
float val2=op2.asFloatConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isFloatConstant()) {
float val1=op1.asFloatConstant().value;
Move.mutate(s,FLOAT_MOVE,Binary.getClearResult(s),FC(val1 + val2));
return MOVE_FOLDED;
}
if (val2 == 0.0f) {
Move.mutate(s,FLOAT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
return UNCHANGED;
case FLOAT_CMPG_opcode:
if (CF_INT) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isFloatConstant()) {
OPT_Operand op1=Binary.getVal1(s);
if (op1.isFloatConstant()) {
float val1=op1.asFloatConstant().value;
float val2=op2.asFloatConstant().value;
int result=(val1 < val2) ? -1 : ((val1 == val2) ? 0 : 1);
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(result));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case FLOAT_CMPL_opcode:
if (CF_INT) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isFloatConstant()) {
OPT_Operand op1=Binary.getVal1(s);
if (op1.isFloatConstant()) {
float val1=op1.asFloatConstant().value;
float val2=op2.asFloatConstant().value;
int result=(val1 > val2) ? 1 : ((val1 == val2) ? 0 : -1);
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(result));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case FLOAT_DIV_opcode:
if (CF_FLOAT) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isFloatConstant()) {
OPT_Operand op1=Binary.getVal1(s);
if (op1.isFloatConstant()) {
float val1=op1.asFloatConstant().value;
float val2=op2.asFloatConstant().value;
Move.mutate(s,FLOAT_MOVE,Binary.getClearResult(s),FC(val1 / val2));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case FLOAT_MUL_opcode:
if (CF_FLOAT) {
canonicalizeCommutativeOperator(s);
OPT_Operand op2=Binary.getVal2(s);
if (op2.isFloatConstant()) {
float val2=op2.asFloatConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isFloatConstant()) {
float val1=op1.asFloatConstant().value;
Move.mutate(s,FLOAT_MOVE,Binary.getClearResult(s),FC(val1 * val2));
return MOVE_FOLDED;
}
if (val2 == 1.0f) {
Move.mutate(s,FLOAT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
return UNCHANGED;
case FLOAT_NEG_opcode:
if (CF_FLOAT) {
OPT_Operand op=Unary.getVal(s);
if (op.isFloatConstant()) {
float val=op.asFloatConstant().value;
Move.mutate(s,FLOAT_MOVE,Unary.getClearResult(s),FC(-val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case FLOAT_REM_opcode:
if (CF_FLOAT) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isFloatConstant()) {
OPT_Operand op1=Binary.getVal1(s);
if (op1.isFloatConstant()) {
float val1=op1.asFloatConstant().value;
float val2=op2.asFloatConstant().value;
Move.mutate(s,FLOAT_MOVE,Binary.getClearResult(s),FC(val1 % val2));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case FLOAT_SUB_opcode:
if (CF_FLOAT) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isFloatConstant()) {
float val2=op2.asFloatConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isFloatConstant()) {
float val1=op1.asFloatConstant().value;
Move.mutate(s,FLOAT_MOVE,Binary.getClearResult(s),FC(val1 - val2));
return MOVE_FOLDED;
}
if (val2 == 0.0f) {
Move.mutate(s,FLOAT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
return UNCHANGED;
case DOUBLE_ADD_opcode:
if (CF_DOUBLE) {
canonicalizeCommutativeOperator(s);
OPT_Operand op2=Binary.getVal2(s);
if (op2.isDoubleConstant()) {
double val2=op2.asDoubleConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isDoubleConstant()) {
double val1=op1.asDoubleConstant().value;
Move.mutate(s,DOUBLE_MOVE,Binary.getClearResult(s),DC(val1 + val2));
return MOVE_FOLDED;
}
if (val2 == 0.0) {
Move.mutate(s,DOUBLE_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
return UNCHANGED;
case DOUBLE_CMPG_opcode:
if (CF_INT) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isDoubleConstant()) {
OPT_Operand op1=Binary.getVal1(s);
if (op1.isDoubleConstant()) {
double val1=op1.asDoubleConstant().value;
double val2=op2.asDoubleConstant().value;
int result=(val1 < val2) ? -1 : ((val1 == val2) ? 0 : 1);
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(result));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case DOUBLE_CMPL_opcode:
if (CF_INT) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isDoubleConstant()) {
OPT_Operand op1=Binary.getVal1(s);
if (op1.isDoubleConstant()) {
double val1=op1.asDoubleConstant().value;
double val2=op2.asDoubleConstant().value;
int result=(val1 > val2) ? 1 : ((val1 == val2) ? 0 : -1);
Move.mutate(s,DOUBLE_MOVE,Binary.getClearResult(s),IC(result));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case DOUBLE_DIV_opcode:
if (CF_DOUBLE) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isDoubleConstant()) {
OPT_Operand op1=Binary.getVal1(s);
if (op1.isDoubleConstant()) {
double val1=op1.asDoubleConstant().value;
double val2=op2.asDoubleConstant().value;
Move.mutate(s,DOUBLE_MOVE,Binary.getClearResult(s),DC(val1 / val2));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case DOUBLE_MUL_opcode:
if (CF_DOUBLE) {
canonicalizeCommutativeOperator(s);
OPT_Operand op2=Binary.getVal2(s);
if (op2.isDoubleConstant()) {
double val2=op2.asDoubleConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isDoubleConstant()) {
double val1=op1.asDoubleConstant().value;
Move.mutate(s,DOUBLE_MOVE,Binary.getClearResult(s),DC(val1 * val2));
return MOVE_FOLDED;
}
if (val2 == 1.0) {
Move.mutate(s,DOUBLE_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
return UNCHANGED;
case DOUBLE_NEG_opcode:
if (CF_DOUBLE) {
OPT_Operand op=Unary.getVal(s);
if (op.isDoubleConstant()) {
double val=op.asDoubleConstant().value;
Move.mutate(s,DOUBLE_MOVE,Unary.getClearResult(s),DC(-val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case DOUBLE_REM_opcode:
if (CF_DOUBLE) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isDoubleConstant()) {
OPT_Operand op1=Binary.getVal1(s);
if (op1.isDoubleConstant()) {
double val1=op1.asDoubleConstant().value;
double val2=op2.asDoubleConstant().value;
Move.mutate(s,DOUBLE_MOVE,Binary.getClearResult(s),DC(val1 % val2));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case DOUBLE_SUB_opcode:
if (CF_DOUBLE) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isDoubleConstant()) {
double val2=op2.asDoubleConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isDoubleConstant()) {
double val1=op1.asDoubleConstant().value;
Move.mutate(s,DOUBLE_MOVE,Binary.getClearResult(s),DC(val1 - val2));
return MOVE_FOLDED;
}
if (val2 == 0.0) {
Move.mutate(s,DOUBLE_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
return UNCHANGED;
case DOUBLE_2FLOAT_opcode:
if (CF_FLOAT) {
OPT_Operand op=Unary.getVal(s);
if (op.isDoubleConstant()) {
double val=op.asDoubleConstant().value;
Move.mutate(s,FLOAT_MOVE,Unary.getClearResult(s),FC((float)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case DOUBLE_2INT_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isDoubleConstant()) {
double val=op.asDoubleConstant().value;
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC((int)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case DOUBLE_2LONG_opcode:
if (CF_LONG) {
OPT_Operand op=Unary.getVal(s);
if (op.isDoubleConstant()) {
double val=op.asDoubleConstant().value;
Move.mutate(s,LONG_MOVE,Unary.getClearResult(s),LC((long)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case DOUBLE_AS_LONG_BITS_opcode:
if (CF_LONG) {
OPT_Operand op=Unary.getVal(s);
if (op.isDoubleConstant()) {
double val=op.asDoubleConstant().value;
Move.mutate(s,LONG_MOVE,Unary.getClearResult(s),LC(Double.doubleToLongBits(val)));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_2DOUBLE_opcode:
if (CF_DOUBLE) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,DOUBLE_MOVE,Unary.getClearResult(s),DC((double)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_2BYTE_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC((byte)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_2USHORT_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC((char)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_2FLOAT_opcode:
if (CF_FLOAT) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,FLOAT_MOVE,Unary.getClearResult(s),FC((float)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_2LONG_opcode:
if (CF_LONG) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,LONG_MOVE,Unary.getClearResult(s),LC((long)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_2ADDRSigExt_opcode:
if (CF_ADDR) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,REF_MOVE,Unary.getClearResult(s),AC(Address.fromIntSignExtend(val)));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_2ADDRZerExt_opcode:
if (CF_ADDR) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,REF_MOVE,Unary.getClearResult(s),AC(Address.fromIntZeroExtend(val)));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case LONG_2ADDR_opcode:
if (CF_ADDR) {
OPT_Operand op=Unary.getVal(s);
if (op.isLongConstant()) {
long val=op.asLongConstant().value;
Move.mutate(s,REF_MOVE,Unary.getClearResult(s),AC(Address.fromLong(val)));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_2SHORT_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC((short)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_BITS_AS_FLOAT_opcode:
if (CF_FLOAT) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,FLOAT_MOVE,Unary.getClearResult(s),FC(Float.intBitsToFloat(val)));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case ADDR_2INT_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isAddressConstant()) {
Address val=op.asAddressConstant().value;
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC(val.toInt()));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case ADDR_2LONG_opcode:
if (CF_LONG) {
OPT_Operand op=Unary.getVal(s);
if (op.isAddressConstant()) {
Address val=op.asAddressConstant().value;
Move.mutate(s,LONG_MOVE,Unary.getClearResult(s),LC(val.toLong()));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case FLOAT_2DOUBLE_opcode:
if (CF_DOUBLE) {
OPT_Operand op=Unary.getVal(s);
if (op.isFloatConstant()) {
float val=op.asFloatConstant().value;
Move.mutate(s,DOUBLE_MOVE,Unary.getClearResult(s),DC((double)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case FLOAT_2INT_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isFloatConstant()) {
float val=op.asFloatConstant().value;
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC((int)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case FLOAT_2LONG_opcode:
if (CF_LONG) {
OPT_Operand op=Unary.getVal(s);
if (op.isFloatConstant()) {
float val=op.asFloatConstant().value;
Move.mutate(s,LONG_MOVE,Unary.getClearResult(s),LC((long)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case FLOAT_AS_INT_BITS_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isFloatConstant()) {
float val=op.asFloatConstant().value;
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC(Float.floatToIntBits(val)));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case LONG_2FLOAT_opcode:
if (CF_FLOAT) {
OPT_Operand op=Unary.getVal(s);
if (op.isLongConstant()) {
long val=op.asLongConstant().value;
Move.mutate(s,FLOAT_MOVE,Unary.getClearResult(s),FC((float)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case LONG_2INT_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isLongConstant()) {
long val=op.asLongConstant().value;
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC((int)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case LONG_2DOUBLE_opcode:
if (CF_DOUBLE) {
OPT_Operand op=Unary.getVal(s);
if (op.isLongConstant()) {
long val=op.asLongConstant().value;
Move.mutate(s,DOUBLE_MOVE,Unary.getClearResult(s),DC((double)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case LONG_BITS_AS_DOUBLE_opcode:
if (CF_DOUBLE) {
OPT_Operand op=Unary.getVal(s);
if (op.isLongConstant()) {
long val=op.asLongConstant().value;
Move.mutate(s,DOUBLE_MOVE,Unary.getClearResult(s),DC(Double.longBitsToDouble(val)));
return MOVE_FOLDED;
}
}
return UNCHANGED;
default :
return UNCHANGED;
}
}

Fixed version (ground truth):
/** 
 * Given an instruction, attempt to simplify it. The instruction will be mutated in place. <p> We don't deal with branching operations here --  doing peephole optimizations of branches is the job of a separate module.
 * @param regpool register pool in case simplification requires a temporary register
 * @param s the instruction to simplify
 * @return one of UNCHANGED, MOVE_FOLDED, MOVE_REDUCED, TRAP_REDUCED, REDUCED
 */
public static byte simplify(OPT_AbstractRegisterPool regpool,OPT_Instruction s){
switch (s.getOpcode()) {
case GUARD_COMBINE_opcode:
{
      OPT_Operand op2=Binary.getVal2(s);
      if (op2 instanceof OPT_TrueGuardOperand) {
        OPT_Operand op1=Binary.getVal1(s);
        if (op1 instanceof OPT_TrueGuardOperand) {
          Move.mutate(s,GUARD_MOVE,Binary.getClearResult(s),op1);
          return MOVE_FOLDED;
        }
 else {
          Move.mutate(s,GUARD_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
          return MOVE_REDUCED;
        }
      }
    }
  return UNCHANGED;
case TRAP_IF_opcode:
{
  OPT_Operand op1=TrapIf.getVal1(s);
  OPT_Operand op2=TrapIf.getVal2(s);
  if (op1.isConstant()) {
    if (op2.isConstant()) {
      int willTrap=TrapIf.getCond(s).evaluate(op1,op2);
      if (willTrap == OPT_ConditionOperand.TRUE) {
        Trap.mutate(s,TRAP,TrapIf.getClearGuardResult(s),TrapIf.getClearTCode(s));
        return TRAP_REDUCED;
      }
 else       if (willTrap == OPT_ConditionOperand.FALSE) {
        Move.mutate(s,GUARD_MOVE,TrapIf.getClearGuardResult(s),TG());
        return MOVE_FOLDED;
      }
    }
 else {
      TrapIf.mutate(s,TRAP_IF,TrapIf.getClearGuardResult(s),TrapIf.getClearVal2(s),TrapIf.getClearVal1(s),TrapIf.getClearCond(s).flipOperands(),TrapIf.getClearTCode(s));
    }
  }
}
return UNCHANGED;
case NULL_CHECK_opcode:
{
OPT_Operand ref=NullCheck.getRef(s);
if (ref.isNullConstant()) {
Trap.mutate(s,TRAP,NullCheck.getClearGuardResult(s),OPT_TrapCodeOperand.NullPtr());
return TRAP_REDUCED;
}
 else if (ref.isStringConstant()) {
Move.mutate(s,GUARD_MOVE,NullCheck.getClearGuardResult(s),TG());
return MOVE_FOLDED;
}
 else if (ref.isAddressConstant()) {
if (ref.asAddressConstant().value.isZero()) {
  Trap.mutate(s,TRAP,NullCheck.getClearGuardResult(s),OPT_TrapCodeOperand.NullPtr());
  return TRAP_REDUCED;
}
 else {
  Move.mutate(s,GUARD_MOVE,NullCheck.getClearGuardResult(s),TG());
  return MOVE_FOLDED;
}
}
return UNCHANGED;
}
case INT_ZERO_CHECK_opcode:
{
OPT_Operand op=ZeroCheck.getValue(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
if (val == 0) {
Trap.mutate(s,TRAP,ZeroCheck.getClearGuardResult(s),OPT_TrapCodeOperand.DivByZero());
return TRAP_REDUCED;
}
 else {
Move.mutate(s,GUARD_MOVE,ZeroCheck.getClearGuardResult(s),TG());
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case LONG_ZERO_CHECK_opcode:
{
OPT_Operand op=ZeroCheck.getValue(s);
if (op.isLongConstant()) {
long val=op.asLongConstant().value;
if (val == 0L) {
Trap.mutate(s,TRAP,ZeroCheck.getClearGuardResult(s),OPT_TrapCodeOperand.DivByZero());
return TRAP_REDUCED;
}
 else {
Move.mutate(s,GUARD_MOVE,ZeroCheck.getClearGuardResult(s),TG());
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case CHECKCAST_opcode:
{
OPT_Operand ref=TypeCheck.getRef(s);
if (ref.isNullConstant()) {
Empty.mutate(s,NOP);
return REDUCED;
}
 else if (ref.isStringConstant()) {
s.operator=CHECKCAST_NOTNULL;
return simplify(regpool,s);
}
 else {
VM_TypeReference lhsType=TypeCheck.getType(s).getTypeRef();
VM_TypeReference rhsType=ref.getType();
byte ans=OPT_ClassLoaderProxy.includesType(lhsType,rhsType);
if (ans == OPT_Constants.YES) {
Empty.mutate(s,NOP);
return REDUCED;
}
}
}
return UNCHANGED;
case CHECKCAST_NOTNULL_opcode:
{
OPT_Operand ref=TypeCheck.getRef(s);
VM_TypeReference lhsType=TypeCheck.getType(s).getTypeRef();
VM_TypeReference rhsType=ref.getType();
byte ans=OPT_ClassLoaderProxy.includesType(lhsType,rhsType);
if (ans == OPT_Constants.YES) {
Empty.mutate(s,NOP);
return REDUCED;
}
 else if (ans == OPT_Constants.NO) {
VM_Type rType=rhsType.peekResolvedType();
if (rType != null && rType.isClassType() && rType.asClass().isFinal()) {
Trap.mutate(s,TRAP,null,OPT_TrapCodeOperand.CheckCast());
return TRAP_REDUCED;
}
}
}
return UNCHANGED;
case INSTANCEOF_opcode:
{
OPT_Operand ref=InstanceOf.getRef(s);
if (ref.isNullConstant()) {
Move.mutate(s,INT_MOVE,InstanceOf.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
 else if (ref.isStringConstant()) {
s.operator=INSTANCEOF_NOTNULL;
return simplify(regpool,s);
}
VM_TypeReference lhsType=InstanceOf.getType(s).getTypeRef();
VM_TypeReference rhsType=ref.getType();
byte ans=OPT_ClassLoaderProxy.includesType(lhsType,rhsType);
if (ans == OPT_Constants.NO) {
VM_Type rType=rhsType.peekResolvedType();
if (rType != null && rType.isClassType() && rType.asClass().isFinal()) {
Move.mutate(s,INT_MOVE,InstanceOf.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case INSTANCEOF_NOTNULL_opcode:
{
OPT_Operand ref=InstanceOf.getRef(s);
VM_TypeReference lhsType=InstanceOf.getType(s).getTypeRef();
VM_TypeReference rhsType=ref.getType();
byte ans=OPT_ClassLoaderProxy.includesType(lhsType,rhsType);
if (ans == OPT_Constants.YES) {
Move.mutate(s,INT_MOVE,InstanceOf.getClearResult(s),IC(1));
return MOVE_FOLDED;
}
 else if (ans == OPT_Constants.NO) {
VM_Type rType=rhsType.peekResolvedType();
if (rType != null && rType.isClassType() && rType.asClass().isFinal()) {
Move.mutate(s,INT_MOVE,InstanceOf.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case INT_COND_MOVE_opcode:
{
OPT_Operand val1=CondMove.getVal1(s);
OPT_Operand val2=CondMove.getVal2(s);
int cond=CondMove.getCond(s).evaluate(val1,val2);
if (cond != OPT_ConditionOperand.UNKNOWN) {
OPT_Operand val=(cond == OPT_ConditionOperand.TRUE) ? CondMove.getClearTrueValue(s) : CondMove.getClearFalseValue(s);
Move.mutate(s,INT_MOVE,CondMove.getClearResult(s),val);
return val.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (val1.isConstant() && !val2.isConstant()) {
OPT_Operand tmp=CondMove.getClearVal1(s);
CondMove.setVal1(s,CondMove.getClearVal2(s));
CondMove.setVal2(s,tmp);
CondMove.getCond(s).flipOperands();
}
OPT_Operand tv=CondMove.getTrueValue(s);
OPT_Operand fv=CondMove.getFalseValue(s);
if (tv.similar(fv)) {
Move.mutate(s,INT_MOVE,CondMove.getClearResult(s),tv);
return tv.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (tv.isIntConstant() && fv.isIntConstant() && !CondMove.getCond(s).isFLOATINGPOINT()) {
int itv=tv.asIntConstant().value;
int ifv=fv.asIntConstant().value;
OPT_Operator op=null;
if (val1.isLong()) {
op=BOOLEAN_CMP_LONG;
}
 else if (val1.isFloat()) {
op=BOOLEAN_CMP_FLOAT;
}
 else if (val1.isDouble()) {
op=BOOLEAN_CMP_DOUBLE;
}
 else {
op=BOOLEAN_CMP_INT;
}
if (itv == 1 && ifv == 0) {
BooleanCmp.mutate(s,op,CondMove.getClearResult(s),CondMove.getClearVal1(s),CondMove.getClearVal2(s),CondMove.getClearCond(s),new OPT_BranchProfileOperand());
return REDUCED;
}
if (itv == 0 && ifv == 1) {
BooleanCmp.mutate(s,op,CondMove.getClearResult(s),CondMove.getClearVal1(s),CondMove.getClearVal2(s),CondMove.getClearCond(s).flipCode(),new OPT_BranchProfileOperand());
return REDUCED;
}
}
}
return UNCHANGED;
case LONG_COND_MOVE_opcode:
{
OPT_Operand val1=CondMove.getVal1(s);
OPT_Operand val2=CondMove.getVal2(s);
int cond=CondMove.getCond(s).evaluate(val1,val2);
if (cond != OPT_ConditionOperand.UNKNOWN) {
OPT_Operand val=(cond == OPT_ConditionOperand.TRUE) ? CondMove.getClearTrueValue(s) : CondMove.getClearFalseValue(s);
Move.mutate(s,LONG_MOVE,CondMove.getClearResult(s),val);
return val.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (val1.isConstant() && !val2.isConstant()) {
OPT_Operand tmp=CondMove.getClearVal1(s);
CondMove.setVal1(s,CondMove.getClearVal2(s));
CondMove.setVal2(s,tmp);
CondMove.getCond(s).flipOperands();
}
OPT_Operand tv=CondMove.getTrueValue(s);
OPT_Operand fv=CondMove.getFalseValue(s);
if (tv.similar(fv)) {
Move.mutate(s,LONG_MOVE,CondMove.getClearResult(s),tv);
return tv.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (tv.isLongConstant() && fv.isLongConstant() && !CondMove.getCond(s).isFLOATINGPOINT()) {
long itv=tv.asLongConstant().value;
long ifv=fv.asLongConstant().value;
OPT_Operator op=null;
if (val1.isLong()) {
op=BOOLEAN_CMP_LONG;
}
 else if (val1.isFloat()) {
op=BOOLEAN_CMP_FLOAT;
}
 else if (val1.isDouble()) {
op=BOOLEAN_CMP_DOUBLE;
}
 else {
op=BOOLEAN_CMP_INT;
}
if (itv == 1 && ifv == 0) {
BooleanCmp.mutate(s,op,CondMove.getClearResult(s),CondMove.getClearVal1(s),CondMove.getClearVal2(s),CondMove.getClearCond(s),new OPT_BranchProfileOperand());
return REDUCED;
}
if (itv == 0 && ifv == 1) {
BooleanCmp.mutate(s,op,CondMove.getClearResult(s),CondMove.getClearVal1(s),CondMove.getClearVal2(s),CondMove.getClearCond(s).flipCode(),new OPT_BranchProfileOperand());
return REDUCED;
}
}
}
return UNCHANGED;
case FLOAT_COND_MOVE_opcode:
{
OPT_Operand val1=CondMove.getVal1(s);
OPT_Operand val2=CondMove.getVal2(s);
int cond=CondMove.getCond(s).evaluate(val1,val2);
if (cond != OPT_ConditionOperand.UNKNOWN) {
OPT_Operand val=(cond == OPT_ConditionOperand.TRUE) ? CondMove.getClearTrueValue(s) : CondMove.getClearFalseValue(s);
Move.mutate(s,FLOAT_MOVE,CondMove.getClearResult(s),val);
return val.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (val1.isConstant() && !val2.isConstant()) {
OPT_Operand tmp=CondMove.getClearVal1(s);
CondMove.setVal1(s,CondMove.getClearVal2(s));
CondMove.setVal2(s,tmp);
CondMove.getCond(s).flipOperands();
}
OPT_Operand tv=CondMove.getTrueValue(s);
OPT_Operand fv=CondMove.getFalseValue(s);
if (tv.similar(fv)) {
Move.mutate(s,FLOAT_MOVE,CondMove.getClearResult(s),tv);
return tv.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
}
return UNCHANGED;
case DOUBLE_COND_MOVE_opcode:
{
OPT_Operand val1=CondMove.getVal1(s);
OPT_Operand val2=CondMove.getVal2(s);
int cond=CondMove.getCond(s).evaluate(val1,val2);
if (cond != OPT_ConditionOperand.UNKNOWN) {
OPT_Operand val=(cond == OPT_ConditionOperand.TRUE) ? CondMove.getClearTrueValue(s) : CondMove.getClearFalseValue(s);
Move.mutate(s,DOUBLE_MOVE,CondMove.getClearResult(s),val);
return val.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (val1.isConstant() && !val2.isConstant()) {
OPT_Operand tmp=CondMove.getClearVal1(s);
CondMove.setVal1(s,CondMove.getClearVal2(s));
CondMove.setVal2(s,tmp);
CondMove.getCond(s).flipOperands();
}
OPT_Operand tv=CondMove.getTrueValue(s);
OPT_Operand fv=CondMove.getFalseValue(s);
if (tv.similar(fv)) {
Move.mutate(s,DOUBLE_MOVE,CondMove.getClearResult(s),tv);
return tv.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
}
return UNCHANGED;
case REF_COND_MOVE_opcode:
{
OPT_Operand val1=CondMove.getVal1(s);
if (val1.isConstant()) {
OPT_Operand val2=CondMove.getVal2(s);
if (val2.isConstant()) {
int cond=CondMove.getCond(s).evaluate(val1,val2);
if (cond != OPT_ConditionOperand.UNKNOWN) {
OPT_Operand val=(cond == OPT_ConditionOperand.TRUE) ? CondMove.getClearTrueValue(s) : CondMove.getClearFalseValue(s);
Move.mutate(s,REF_MOVE,CondMove.getClearResult(s),val);
return val.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
}
 else {
OPT_Operand tmp=CondMove.getClearVal1(s);
CondMove.setVal1(s,CondMove.getClearVal2(s));
CondMove.setVal2(s,tmp);
CondMove.getCond(s).flipOperands();
}
}
if (CondMove.getTrueValue(s).similar(CondMove.getFalseValue(s))) {
OPT_Operand val=CondMove.getClearTrueValue(s);
Move.mutate(s,REF_MOVE,CondMove.getClearResult(s),val);
return val.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
}
return UNCHANGED;
case GUARD_COND_MOVE_opcode:
{
OPT_Operand val1=CondMove.getVal1(s);
if (val1.isConstant()) {
OPT_Operand val2=CondMove.getVal2(s);
if (val2.isConstant()) {
int cond=CondMove.getCond(s).evaluate(val1,val2);
if (cond == OPT_ConditionOperand.UNKNOWN) {
OPT_Operand val=(cond == OPT_ConditionOperand.TRUE) ? CondMove.getClearTrueValue(s) : CondMove.getClearFalseValue(s);
Move.mutate(s,GUARD_MOVE,CondMove.getClearResult(s),val);
return val.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
}
 else {
OPT_Operand tmp=CondMove.getClearVal1(s);
CondMove.setVal1(s,CondMove.getClearVal2(s));
CondMove.setVal2(s,tmp);
CondMove.getCond(s).flipOperands();
}
}
if (CondMove.getTrueValue(s).similar(CondMove.getFalseValue(s))) {
OPT_Operand val=CondMove.getClearTrueValue(s);
Move.mutate(s,GUARD_MOVE,CondMove.getClearResult(s),val);
return val.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
}
return UNCHANGED;
case BOOLEAN_NOT_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
if (val == 0) {
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC(1));
}
 else {
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC(0));
}
return MOVE_FOLDED;
}
}
return UNCHANGED;
case BOOLEAN_CMP_INT_opcode:
if (CF_INT) {
OPT_Operand op1=BooleanCmp.getVal1(s);
OPT_Operand op2=BooleanCmp.getVal2(s);
if (op1.isConstant()) {
if (op2.isConstant()) {
int cond=BooleanCmp.getCond(s).evaluate(op1,op2);
if (cond != OPT_ConditionOperand.UNKNOWN) {
Move.mutate(s,INT_MOVE,BooleanCmp.getResult(s),(cond == OPT_ConditionOperand.TRUE) ? IC(1) : IC(0));
return MOVE_FOLDED;
}
}
 else {
OPT_Operand tmp=BooleanCmp.getClearVal1(s);
BooleanCmp.setVal1(s,BooleanCmp.getClearVal2(s));
BooleanCmp.setVal2(s,tmp);
BooleanCmp.getCond(s).flipOperands();
}
}
}
return UNCHANGED;
case BOOLEAN_CMP_ADDR_opcode:
if (CF_ADDR) {
OPT_Operand op1=BooleanCmp.getVal1(s);
OPT_Operand op2=BooleanCmp.getVal2(s);
if (op1.isConstant()) {
if (op2.isConstant()) {
int cond=BooleanCmp.getCond(s).evaluate(op1,op2);
if (cond != OPT_ConditionOperand.UNKNOWN) {
Move.mutate(s,REF_MOVE,BooleanCmp.getResult(s),(cond == OPT_ConditionOperand.TRUE) ? IC(1) : IC(0));
return MOVE_FOLDED;
}
}
 else {
OPT_Operand tmp=BooleanCmp.getClearVal1(s);
BooleanCmp.setVal1(s,BooleanCmp.getClearVal2(s));
BooleanCmp.setVal2(s,tmp);
BooleanCmp.getCond(s).flipOperands();
}
}
}
return UNCHANGED;
case INT_ADD_opcode:
if (CF_INT) {
canonicalizeCommutativeOperator(s);
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(val1 + val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case INT_AND_opcode:
if (CF_INT) {
canonicalizeCommutativeOperator(s);
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return op1.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(val1 & val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
if (val2 == -1) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case INT_DIV_opcode:
if (CF_INT) {
OPT_Operand op1=GuardedBinary.getVal1(s);
OPT_Operand op2=GuardedBinary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,INT_MOVE,GuardedBinary.getClearResult(s),IC(1));
return MOVE_FOLDED;
}
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
if (val2 == 0) {
return UNCHANGED;
}
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,GuardedBinary.getClearResult(s),IC(val1 / val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 1) {
Move.mutate(s,INT_MOVE,GuardedBinary.getClearResult(s),GuardedBinary.getClearVal1(s));
return MOVE_REDUCED;
}
int power=PowerOf2(val2);
if (power != -1) {
Binary.mutate(s,INT_SHR,GuardedBinary.getClearResult(s),GuardedBinary.getClearVal1(s),IC(power));
return REDUCED;
}
}
}
}
return UNCHANGED;
case INT_MUL_opcode:
if (CF_INT) {
canonicalizeCommutativeOperator(s);
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(val1 * val2));
return MOVE_FOLDED;
}
 else {
if (val2 == -1) {
Unary.mutate(s,INT_NEG,Binary.getClearResult(s),Binary.getClearVal1(s));
return REDUCED;
}
if (val2 == 0) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
if (val2 == 1) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
if (s.getPrev() != null) {
int cost=0;
for (int i=1; i < BITS_IN_INT; i++) {
if ((val2 & (1 << i)) != 0) {
cost++;
}
}
if (cost < 5) {
OPT_RegisterOperand val1Operand=Binary.getClearVal1(s).asRegister();
OPT_RegisterOperand resultOperand=regpool.makeTempInt();
OPT_Instruction move;
if ((val2 & 1) == 1) {
move=Move.create(INT_MOVE,resultOperand,val1Operand);
}
 else {
move=Move.create(INT_MOVE,resultOperand,IC(0));
}
move.copyPosition(s);
s.insertBefore(move);
for (int i=1; i < BITS_IN_INT; i++) {
if ((val2 & (1 << i)) != 0) {
OPT_RegisterOperand tempInt=regpool.makeTempInt();
OPT_Instruction shift=Binary.create(INT_SHL,tempInt,val1Operand.copyRO(),IC(i));
shift.copyPosition(s);
s.insertBefore(shift);
OPT_Instruction add=Binary.create(INT_ADD,resultOperand.copyRO(),resultOperand.copyRO(),tempInt.copyRO());
add.copyPosition(s);
s.insertBefore(add);
}
}
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),resultOperand.copyRO());
return REDUCED;
}
}
}
}
}
return UNCHANGED;
case INT_NEG_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC(-val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_NOT_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC(~val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_OR_opcode:
if (CF_INT) {
canonicalizeCommutativeOperator(s);
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return op1.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(val1 | val2));
return MOVE_FOLDED;
}
 else {
if (val2 == -1) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(-1));
return MOVE_FOLDED;
}
if (val2 == 0) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case INT_REM_opcode:
if (CF_INT) {
OPT_Operand op1=GuardedBinary.getVal1(s);
OPT_Operand op2=GuardedBinary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,INT_MOVE,GuardedBinary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
if (val2 == 0) {
return UNCHANGED;
}
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,GuardedBinary.getClearResult(s),IC(val1 % val2));
return MOVE_FOLDED;
}
 else {
if ((val2 == 1) || (val2 == -1)) {
Move.mutate(s,INT_MOVE,GuardedBinary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
int power=PowerOf2(val2);
if (power != -1) {
Binary.mutate(s,INT_AND,GuardedBinary.getClearResult(s),GuardedBinary.getClearVal1(s),IC(val2 - 1));
return REDUCED;
}
}
}
}
return UNCHANGED;
case INT_SHL_opcode:
if (CF_INT) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(val1 << val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
if (val2 >= BITS_IN_INT) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
}
}
}
return UNCHANGED;
case INT_SHR_opcode:
if (CF_INT) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(val1 >> val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case INT_SUB_opcode:
if (CF_INT) {
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(val1 - val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
Binary.mutate(s,INT_ADD,Binary.getClearResult(s),Binary.getClearVal1(s),IC(-val2));
return REDUCED;
}
}
}
return UNCHANGED;
case INT_USHR_opcode:
if (CF_INT) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(val1 >>> val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
if (val2 >= BITS_IN_INT) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
}
}
}
return UNCHANGED;
case INT_XOR_opcode:
if (CF_INT) {
canonicalizeCommutativeOperator(s);
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
if (op1.isIntConstant()) {
int val1=op1.asIntConstant().value;
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(val1 ^ val2));
return MOVE_FOLDED;
}
 else {
if (val2 == -1) {
Unary.mutate(s,INT_NOT,Binary.getClearResult(s),Binary.getClearVal1(s));
return REDUCED;
}
if (val2 == 0) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case REF_ADD_opcode:
if (CF_ADDR) {
canonicalizeCommutativeOperator(s);
OPT_Operand op2=Binary.getVal2(s);
if (op2.isConstant()) {
Address val2=getAddressValue(op2);
OPT_Operand op1=Binary.getVal1(s);
if (op1.isConstant()) {
Address val1=getAddressValue(op1);
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),AC(val1.add(val2.toWord().toOffset())));
return MOVE_FOLDED;
}
 else {
if (val2.isZero()) {
if (op1.isIntLike()) {
Unary.mutate(s,INT_2ADDRSigExt,Binary.getClearResult(s),Binary.getClearVal1(s));
}
 else {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
}
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case REF_AND_opcode:
if (CF_ADDR) {
canonicalizeCommutativeOperator(s);
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return op1.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (op2.isAddressConstant()) {
Word val2=op2.asAddressConstant().value.toWord();
if (op1.isAddressConstant()) {
Word val1=op1.asAddressConstant().value.toWord();
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),AC(val1.and(val2).toAddress()));
return MOVE_FOLDED;
}
 else {
if (val2.isZero()) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),AC(Address.zero()));
return MOVE_FOLDED;
}
if (val2.isMax()) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case REF_SHL_opcode:
if (CF_ADDR) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isAddressConstant()) {
Word val1=op1.asAddressConstant().value.toWord();
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),AC(val1.lsh(val2).toAddress()));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
if (val2 >= BITS_IN_ADDRESS) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
}
}
}
return UNCHANGED;
case REF_SHR_opcode:
if (CF_ADDR) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isAddressConstant()) {
Word val1=op1.asAddressConstant().value.toWord();
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),AC(val1.rsha(val2).toAddress()));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case REF_NOT_opcode:
if (CF_ADDR) {
OPT_Operand op=Unary.getVal(s);
if (op.isAddressConstant()) {
Word val=op.asAddressConstant().value.toWord();
Move.mutate(s,REF_MOVE,Unary.getClearResult(s),AC(val.not().toAddress()));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case REF_OR_opcode:
if (CF_ADDR) {
canonicalizeCommutativeOperator(s);
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return op1.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (op2.isAddressConstant()) {
Word val2=op2.asAddressConstant().value.toWord();
if (op1.isAddressConstant()) {
Word val1=op1.asAddressConstant().value.toWord();
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),AC(val1.or(val2).toAddress()));
return MOVE_FOLDED;
}
 else {
if (val2.isMax()) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),AC(Address.max()));
return MOVE_FOLDED;
}
if (val2.isZero()) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case REF_SUB_opcode:
if (CF_ADDR) {
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
if (op2.isConstant()) {
Address val2=getAddressValue(op2);
if (op1.isConstant()) {
Address val1=getAddressValue(op1);
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),AC(val1.sub(val2.toWord().toOffset())));
return MOVE_FOLDED;
}
 else {
if (val2.isZero()) {
if (op1.isIntLike()) {
Unary.mutate(s,INT_2ADDRSigExt,Binary.getClearResult(s),Binary.getClearVal1(s));
}
 else {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
}
return MOVE_REDUCED;
}
Binary.mutate(s,REF_ADD,Binary.getClearResult(s),Binary.getClearVal1(s),AC(Address.zero().sub(val2.toWord().toOffset())));
return REDUCED;
}
}
}
return UNCHANGED;
case REF_USHR_opcode:
if (CF_ADDR) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isAddressConstant()) {
Word val1=op1.asAddressConstant().value.toWord();
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),AC(val1.rshl(val2).toAddress()));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
if (val2 >= BITS_IN_ADDRESS) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
}
}
}
return UNCHANGED;
case REF_XOR_opcode:
if (CF_ADDR) {
canonicalizeCommutativeOperator(s);
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
if (op2.isAddressConstant()) {
Word val2=op2.asAddressConstant().value.toWord();
if (op1.isAddressConstant()) {
Word val1=op1.asAddressConstant().value.toWord();
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),AC(val1.xor(val2).toAddress()));
return MOVE_FOLDED;
}
 else {
if (val2.isMax()) {
Unary.mutate(s,REF_NOT,Binary.getClearResult(s),Binary.getClearVal1(s));
return REDUCED;
}
if (val2.isZero()) {
Move.mutate(s,REF_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case LONG_ADD_opcode:
if (CF_LONG) {
canonicalizeCommutativeOperator(s);
OPT_Operand op2=Binary.getVal2(s);
if (op2.isLongConstant()) {
long val2=op2.asLongConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(val1 + val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0L) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case LONG_AND_opcode:
if (CF_LONG) {
canonicalizeCommutativeOperator(s);
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return op1.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (op2.isLongConstant()) {
long val2=op2.asLongConstant().value;
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(val1 & val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0L) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(0L));
return MOVE_FOLDED;
}
if (val2 == -1) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case LONG_CMP_opcode:
if (CF_LONG) {
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(0));
return MOVE_FOLDED;
}
if (op2.isLongConstant()) {
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
long val2=op2.asLongConstant().value;
int result=(val1 > val2) ? 1 : ((val1 == val2) ? 0 : -1);
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(result));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case LONG_DIV_opcode:
if (CF_LONG) {
OPT_Operand op1=GuardedBinary.getVal1(s);
OPT_Operand op2=GuardedBinary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,LONG_MOVE,GuardedBinary.getClearResult(s),LC(1));
return MOVE_FOLDED;
}
if (op2.isLongConstant()) {
long val2=op2.asLongConstant().value;
if (val2 == 0L) {
return UNCHANGED;
}
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,GuardedBinary.getClearResult(s),LC(val1 / val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 1L) {
Move.mutate(s,LONG_MOVE,GuardedBinary.getClearResult(s),GuardedBinary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case LONG_MUL_opcode:
if (CF_LONG) {
canonicalizeCommutativeOperator(s);
OPT_Operand op2=Binary.getVal2(s);
if (op2.isLongConstant()) {
long val2=op2.asLongConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(val1 * val2));
return MOVE_FOLDED;
}
 else {
if (val2 == -1L) {
Move.mutate(s,LONG_NEG,Binary.getClearResult(s),Binary.getClearVal1(s));
return REDUCED;
}
if (val2 == 0L) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(0L));
return MOVE_FOLDED;
}
if (val2 == 1L) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case LONG_NEG_opcode:
if (CF_LONG) {
OPT_Operand op=Unary.getVal(s);
if (op.isLongConstant()) {
long val=op.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Unary.getClearResult(s),LC(-val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case LONG_NOT_opcode:
if (CF_LONG) {
OPT_Operand op=Unary.getVal(s);
if (op.isLongConstant()) {
long val=op.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(~val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case LONG_OR_opcode:
if (CF_LONG) {
canonicalizeCommutativeOperator(s);
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return op1.isConstant() ? MOVE_FOLDED : MOVE_REDUCED;
}
if (op2.isLongConstant()) {
long val2=op2.asLongConstant().value;
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(val1 | val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0L) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
if (val2 == -1L) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(-1L));
return MOVE_FOLDED;
}
}
}
}
return UNCHANGED;
case LONG_REM_opcode:
if (CF_LONG) {
OPT_Operand op1=GuardedBinary.getVal1(s);
OPT_Operand op2=GuardedBinary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,LONG_MOVE,GuardedBinary.getClearResult(s),LC(0));
return MOVE_FOLDED;
}
if (op2.isLongConstant()) {
long val2=op2.asLongConstant().value;
if (val2 == 0L) {
return UNCHANGED;
}
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,GuardedBinary.getClearResult(s),LC(val1 % val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 1L) {
Move.mutate(s,LONG_MOVE,GuardedBinary.getClearResult(s),LC(0));
return MOVE_FOLDED;
}
}
}
}
return UNCHANGED;
case LONG_SHL_opcode:
if (CF_LONG) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(val1 << val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
if (val2 >= BITS_IN_LONG) {
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),LC(0));
return MOVE_FOLDED;
}
}
}
}
return UNCHANGED;
case LONG_SHR_opcode:
if (CF_LONG) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(val1 >> val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case LONG_SUB_opcode:
if (CF_LONG) {
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(0));
return MOVE_FOLDED;
}
if (op2.isLongConstant()) {
long val2=op2.asLongConstant().value;
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(val1 - val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0L) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
Binary.mutate(s,LONG_ADD,Binary.getClearResult(s),Binary.getClearVal1(s),LC(-val2));
return REDUCED;
}
}
}
return UNCHANGED;
case LONG_USHR_opcode:
if (CF_LONG) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isIntConstant()) {
int val2=op2.asIntConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(val1 >>> val2));
return MOVE_FOLDED;
}
 else {
if (val2 == 0) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
if (val2 >= BITS_IN_LONG) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(0));
return MOVE_FOLDED;
}
}
}
}
return UNCHANGED;
case LONG_XOR_opcode:
if (CF_LONG) {
canonicalizeCommutativeOperator(s);
OPT_Operand op1=Binary.getVal1(s);
OPT_Operand op2=Binary.getVal2(s);
if (op1.similar(op2)) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(0));
return MOVE_FOLDED;
}
if (op2.isLongConstant()) {
long val2=op2.asLongConstant().value;
if (op1.isLongConstant()) {
long val1=op1.asLongConstant().value;
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),LC(val1 ^ val2));
return MOVE_FOLDED;
}
 else {
if (val2 == -1L) {
Unary.mutate(s,LONG_NOT,Binary.getClearResult(s),Binary.getClearVal1(s));
return REDUCED;
}
if (val2 == 0L) {
Move.mutate(s,LONG_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
}
return UNCHANGED;
case FLOAT_ADD_opcode:
if (CF_FLOAT) {
canonicalizeCommutativeOperator(s);
OPT_Operand op2=Binary.getVal2(s);
if (op2.isFloatConstant()) {
float val2=op2.asFloatConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isFloatConstant()) {
float val1=op1.asFloatConstant().value;
Move.mutate(s,FLOAT_MOVE,Binary.getClearResult(s),FC(val1 + val2));
return MOVE_FOLDED;
}
if (val2 == 0.0f) {
Move.mutate(s,FLOAT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
return UNCHANGED;
case FLOAT_CMPG_opcode:
if (CF_INT) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isFloatConstant()) {
OPT_Operand op1=Binary.getVal1(s);
if (op1.isFloatConstant()) {
float val1=op1.asFloatConstant().value;
float val2=op2.asFloatConstant().value;
int result=(val1 < val2) ? -1 : ((val1 == val2) ? 0 : 1);
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(result));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case FLOAT_CMPL_opcode:
if (CF_INT) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isFloatConstant()) {
OPT_Operand op1=Binary.getVal1(s);
if (op1.isFloatConstant()) {
float val1=op1.asFloatConstant().value;
float val2=op2.asFloatConstant().value;
int result=(val1 > val2) ? 1 : ((val1 == val2) ? 0 : -1);
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(result));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case FLOAT_DIV_opcode:
if (CF_FLOAT) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isFloatConstant()) {
OPT_Operand op1=Binary.getVal1(s);
if (op1.isFloatConstant()) {
float val1=op1.asFloatConstant().value;
float val2=op2.asFloatConstant().value;
Move.mutate(s,FLOAT_MOVE,Binary.getClearResult(s),FC(val1 / val2));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case FLOAT_MUL_opcode:
if (CF_FLOAT) {
canonicalizeCommutativeOperator(s);
OPT_Operand op2=Binary.getVal2(s);
if (op2.isFloatConstant()) {
float val2=op2.asFloatConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isFloatConstant()) {
float val1=op1.asFloatConstant().value;
Move.mutate(s,FLOAT_MOVE,Binary.getClearResult(s),FC(val1 * val2));
return MOVE_FOLDED;
}
if (val2 == 1.0f) {
Move.mutate(s,FLOAT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
return UNCHANGED;
case FLOAT_NEG_opcode:
if (CF_FLOAT) {
OPT_Operand op=Unary.getVal(s);
if (op.isFloatConstant()) {
float val=op.asFloatConstant().value;
Move.mutate(s,FLOAT_MOVE,Unary.getClearResult(s),FC(-val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case FLOAT_REM_opcode:
if (CF_FLOAT) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isFloatConstant()) {
OPT_Operand op1=Binary.getVal1(s);
if (op1.isFloatConstant()) {
float val1=op1.asFloatConstant().value;
float val2=op2.asFloatConstant().value;
Move.mutate(s,FLOAT_MOVE,Binary.getClearResult(s),FC(val1 % val2));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case FLOAT_SUB_opcode:
if (CF_FLOAT) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isFloatConstant()) {
float val2=op2.asFloatConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isFloatConstant()) {
float val1=op1.asFloatConstant().value;
Move.mutate(s,FLOAT_MOVE,Binary.getClearResult(s),FC(val1 - val2));
return MOVE_FOLDED;
}
if (val2 == 0.0f) {
Move.mutate(s,FLOAT_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
return UNCHANGED;
case DOUBLE_ADD_opcode:
if (CF_DOUBLE) {
canonicalizeCommutativeOperator(s);
OPT_Operand op2=Binary.getVal2(s);
if (op2.isDoubleConstant()) {
double val2=op2.asDoubleConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isDoubleConstant()) {
double val1=op1.asDoubleConstant().value;
Move.mutate(s,DOUBLE_MOVE,Binary.getClearResult(s),DC(val1 + val2));
return MOVE_FOLDED;
}
if (val2 == 0.0) {
Move.mutate(s,DOUBLE_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
return UNCHANGED;
case DOUBLE_CMPG_opcode:
if (CF_INT) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isDoubleConstant()) {
OPT_Operand op1=Binary.getVal1(s);
if (op1.isDoubleConstant()) {
double val1=op1.asDoubleConstant().value;
double val2=op2.asDoubleConstant().value;
int result=(val1 < val2) ? -1 : ((val1 == val2) ? 0 : 1);
Move.mutate(s,INT_MOVE,Binary.getClearResult(s),IC(result));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case DOUBLE_CMPL_opcode:
if (CF_INT) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isDoubleConstant()) {
OPT_Operand op1=Binary.getVal1(s);
if (op1.isDoubleConstant()) {
double val1=op1.asDoubleConstant().value;
double val2=op2.asDoubleConstant().value;
int result=(val1 > val2) ? 1 : ((val1 == val2) ? 0 : -1);
Move.mutate(s,DOUBLE_MOVE,Binary.getClearResult(s),IC(result));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case DOUBLE_DIV_opcode:
if (CF_DOUBLE) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isDoubleConstant()) {
OPT_Operand op1=Binary.getVal1(s);
if (op1.isDoubleConstant()) {
double val1=op1.asDoubleConstant().value;
double val2=op2.asDoubleConstant().value;
Move.mutate(s,DOUBLE_MOVE,Binary.getClearResult(s),DC(val1 / val2));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case DOUBLE_MUL_opcode:
if (CF_DOUBLE) {
canonicalizeCommutativeOperator(s);
OPT_Operand op2=Binary.getVal2(s);
if (op2.isDoubleConstant()) {
double val2=op2.asDoubleConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isDoubleConstant()) {
double val1=op1.asDoubleConstant().value;
Move.mutate(s,DOUBLE_MOVE,Binary.getClearResult(s),DC(val1 * val2));
return MOVE_FOLDED;
}
if (val2 == 1.0) {
Move.mutate(s,DOUBLE_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
return UNCHANGED;
case DOUBLE_NEG_opcode:
if (CF_DOUBLE) {
OPT_Operand op=Unary.getVal(s);
if (op.isDoubleConstant()) {
double val=op.asDoubleConstant().value;
Move.mutate(s,DOUBLE_MOVE,Unary.getClearResult(s),DC(-val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case DOUBLE_REM_opcode:
if (CF_DOUBLE) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isDoubleConstant()) {
OPT_Operand op1=Binary.getVal1(s);
if (op1.isDoubleConstant()) {
double val1=op1.asDoubleConstant().value;
double val2=op2.asDoubleConstant().value;
Move.mutate(s,DOUBLE_MOVE,Binary.getClearResult(s),DC(val1 % val2));
return MOVE_FOLDED;
}
}
}
return UNCHANGED;
case DOUBLE_SUB_opcode:
if (CF_DOUBLE) {
OPT_Operand op2=Binary.getVal2(s);
if (op2.isDoubleConstant()) {
double val2=op2.asDoubleConstant().value;
OPT_Operand op1=Binary.getVal1(s);
if (op1.isDoubleConstant()) {
double val1=op1.asDoubleConstant().value;
Move.mutate(s,DOUBLE_MOVE,Binary.getClearResult(s),DC(val1 - val2));
return MOVE_FOLDED;
}
if (val2 == 0.0) {
Move.mutate(s,DOUBLE_MOVE,Binary.getClearResult(s),Binary.getClearVal1(s));
return MOVE_REDUCED;
}
}
}
return UNCHANGED;
case DOUBLE_2FLOAT_opcode:
if (CF_FLOAT) {
OPT_Operand op=Unary.getVal(s);
if (op.isDoubleConstant()) {
double val=op.asDoubleConstant().value;
Move.mutate(s,FLOAT_MOVE,Unary.getClearResult(s),FC((float)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case DOUBLE_2INT_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isDoubleConstant()) {
double val=op.asDoubleConstant().value;
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC((int)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case DOUBLE_2LONG_opcode:
if (CF_LONG) {
OPT_Operand op=Unary.getVal(s);
if (op.isDoubleConstant()) {
double val=op.asDoubleConstant().value;
Move.mutate(s,LONG_MOVE,Unary.getClearResult(s),LC((long)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case DOUBLE_AS_LONG_BITS_opcode:
if (CF_LONG) {
OPT_Operand op=Unary.getVal(s);
if (op.isDoubleConstant()) {
double val=op.asDoubleConstant().value;
Move.mutate(s,LONG_MOVE,Unary.getClearResult(s),LC(Double.doubleToLongBits(val)));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_2DOUBLE_opcode:
if (CF_DOUBLE) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,DOUBLE_MOVE,Unary.getClearResult(s),DC((double)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_2BYTE_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC((byte)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_2USHORT_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC((char)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_2FLOAT_opcode:
if (CF_FLOAT) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,FLOAT_MOVE,Unary.getClearResult(s),FC((float)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_2LONG_opcode:
if (CF_LONG) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,LONG_MOVE,Unary.getClearResult(s),LC((long)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_2ADDRSigExt_opcode:
if (CF_ADDR) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,REF_MOVE,Unary.getClearResult(s),AC(Address.fromIntSignExtend(val)));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_2ADDRZerExt_opcode:
if (CF_ADDR) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,REF_MOVE,Unary.getClearResult(s),AC(Address.fromIntZeroExtend(val)));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case LONG_2ADDR_opcode:
if (CF_ADDR) {
OPT_Operand op=Unary.getVal(s);
if (op.isLongConstant()) {
long val=op.asLongConstant().value;
Move.mutate(s,REF_MOVE,Unary.getClearResult(s),AC(Address.fromLong(val)));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_2SHORT_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC((short)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case INT_BITS_AS_FLOAT_opcode:
if (CF_FLOAT) {
OPT_Operand op=Unary.getVal(s);
if (op.isIntConstant()) {
int val=op.asIntConstant().value;
Move.mutate(s,FLOAT_MOVE,Unary.getClearResult(s),FC(Float.intBitsToFloat(val)));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case ADDR_2INT_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isAddressConstant()) {
Address val=op.asAddressConstant().value;
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC(val.toInt()));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case ADDR_2LONG_opcode:
if (CF_LONG) {
OPT_Operand op=Unary.getVal(s);
if (op.isAddressConstant()) {
Address val=op.asAddressConstant().value;
Move.mutate(s,LONG_MOVE,Unary.getClearResult(s),LC(val.toLong()));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case FLOAT_2DOUBLE_opcode:
if (CF_DOUBLE) {
OPT_Operand op=Unary.getVal(s);
if (op.isFloatConstant()) {
float val=op.asFloatConstant().value;
Move.mutate(s,DOUBLE_MOVE,Unary.getClearResult(s),DC((double)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case FLOAT_2INT_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isFloatConstant()) {
float val=op.asFloatConstant().value;
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC((int)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case FLOAT_2LONG_opcode:
if (CF_LONG) {
OPT_Operand op=Unary.getVal(s);
if (op.isFloatConstant()) {
float val=op.asFloatConstant().value;
Move.mutate(s,LONG_MOVE,Unary.getClearResult(s),LC((long)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case FLOAT_AS_INT_BITS_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isFloatConstant()) {
float val=op.asFloatConstant().value;
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC(Float.floatToIntBits(val)));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case LONG_2FLOAT_opcode:
if (CF_FLOAT) {
OPT_Operand op=Unary.getVal(s);
if (op.isLongConstant()) {
long val=op.asLongConstant().value;
Move.mutate(s,FLOAT_MOVE,Unary.getClearResult(s),FC((float)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case LONG_2INT_opcode:
if (CF_INT) {
OPT_Operand op=Unary.getVal(s);
if (op.isLongConstant()) {
long val=op.asLongConstant().value;
Move.mutate(s,INT_MOVE,Unary.getClearResult(s),IC((int)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case LONG_2DOUBLE_opcode:
if (CF_DOUBLE) {
OPT_Operand op=Unary.getVal(s);
if (op.isLongConstant()) {
long val=op.asLongConstant().value;
Move.mutate(s,DOUBLE_MOVE,Unary.getClearResult(s),DC((double)val));
return MOVE_FOLDED;
}
}
return UNCHANGED;
case LONG_BITS_AS_DOUBLE_opcode:
if (CF_DOUBLE) {
OPT_Operand op=Unary.getVal(s);
if (op.isLongConstant()) {
long val=op.asLongConstant().value;
Move.mutate(s,DOUBLE_MOVE,Unary.getClearResult(s),DC(Double.longBitsToDouble(val)));
return MOVE_FOLDED;
}
}
return UNCHANGED;
default :
return UNCHANGED;
}
}