use of soot.toDex.instructions.Insn21s in project soot by Sable.
the class RegisterAssigner method findFittingInsn.
private Insn findFittingInsn(Insn insn) {
if (!insn.hasIncompatibleRegs()) {
// no incompatible regs -> no fitting needed
return null;
}
// we expect the dex specification to rarely change, so we hard-code the
// mapping "unfitting -> fitting"
Opcode opc = insn.getOpcode();
if (insn instanceof Insn11n && opc.equals(Opcode.CONST_4)) {
// const-4 (11n, byteReg) -> const-16 (21s, shortReg)
Insn11n unfittingInsn = (Insn11n) insn;
if (unfittingInsn.getRegA().fitsShort()) {
return new Insn21s(Opcode.CONST_16, unfittingInsn.getRegA(), unfittingInsn.getLitB());
}
} else if (insn instanceof TwoRegInsn && opc.name.endsWith("_2ADDR")) {
// */2addr (12x, byteReg,byteReg) -> * (23x,
// shortReg,shortReg,shortReg)
Register regA = ((TwoRegInsn) insn).getRegA();
Register regB = ((TwoRegInsn) insn).getRegB();
if (regA.fitsShort() && regB.fitsShort()) {
// use new opcode without the "/2addr"
int oldOpcLength = opc.name.length();
String newOpcName = opc.name.substring(0, oldOpcLength - 6);
Opcode newOpc = Opcode.valueOf(newOpcName);
Register regAClone = regA.clone();
return new Insn23x(newOpc, regA, regAClone, regB);
}
} else if (insn instanceof TwoRegInsn && SootToDexUtils.isNormalMove(opc)) {
/*
* move+ (12x, byteReg,byteReg) -> move+/from16 (22x,
* shortReg,unconstReg) -> move+/16 (32x, unconstReg,unconstReg)
* where "+" is "", "-object" or "-wide"
*/
Register regA = ((TwoRegInsn) insn).getRegA();
Register regB = ((TwoRegInsn) insn).getRegB();
if (regA.getNumber() != regB.getNumber()) {
return StmtVisitor.buildMoveInsn(regA, regB);
}
}
// no fitting insn found
return null;
}
Aggregations