public int getMinimumRegsNeeded() { BitSet incompatRegs = getIncompatibleRegs(); int resultNeed = 0; int miscRegsNeed = 0; boolean hasResult = opc.setsRegister(); if (hasResult && incompatRegs.get(0)) { resultNeed = SootToDexUtils.getDexWords(regs.get(0).getType()); } for (int i = hasResult ? 1 : 0; i < regs.size(); i++) { if (incompatRegs.get(i)) { miscRegsNeed += SootToDexUtils.getDexWords(regs.get(i).getType()); } } // The /2addr instruction format takes two operands and overwrites the // first operand register with the result. The result register is thus // not free to overlap as we still need to provide input data in it. // add-long/2addr r0 r0 -> 2 registers // add-int r0 r0 r2 -> 2 registers, re-use result register if (opc.name.endsWith("/2addr")) { return resultNeed + miscRegsNeed; } else { return Math.max(resultNeed, miscRegsNeed); } }
private void fixIncompatRegs(Insn insn, InstructionIterator allInsns) { List<Register> regs = insn.getRegs(); BitSet incompatRegs = insn.getIncompatibleRegs(); Register resultReg = regs.get(0); // do we have an incompatible result reg? boolean hasResultReg = insn.getOpcode().setsRegister() || insn.getOpcode().setsWideRegister(); boolean isResultRegIncompat = incompatRegs.get(0); // is there an incompat result reg which is not also used as a source // (like in /2addr)? if (hasResultReg && isResultRegIncompat && !insn.getOpcode().name.endsWith("/2addr") && !insn.getOpcode().name.equals("check-cast")) { // yes, so pretend result reg is compatible, since it will get a // special move incompatRegs.clear(0); } // handle normal incompatible regs, if any: add moves if (incompatRegs.cardinality() > 0) { addMovesForIncompatRegs(insn, allInsns, regs, incompatRegs); } // handle incompatible result reg. This is for three-operand // instructions // in which the result register is out of scope. For /2addr // instructions, // we need to coherently move source and result, so this is already done // in addMovesForIncompatRegs. if (hasResultReg && isResultRegIncompat) { Register resultRegClone = resultReg.clone(); addMoveForIncompatResultReg(allInsns, resultRegClone, resultReg, insn); } }
Register newRegister = null; final Register resultReg = regs.get(0); final boolean hasResultReg = curInsn.getOpcode().setsRegister() || curInsn.getOpcode().setsWideRegister(); Insn moveResultInsn = null;
public boolean setsRegister() { return instruction.getOpcode().setsRegister(); }
@Nonnull static Opcode getAndCheckDeodexedOpcodeForOdexedOpcode(@Nonnull String fieldType, @Nonnull Opcode odexedOpcode,MethodAnalyzer ma) { int opcodeType = odexedOpcode.setsRegister()?0:1; int opcodeSubType = getOpcodeSubtype(odexedOpcode); int typeIndex = getTypeIndex(fieldType.charAt(0)); Opcode correctOdexedOpcode, deodexedOpcode; correctOdexedOpcode = opcodeMap[opcodeType][opcodeSubType][0][typeIndex]; deodexedOpcode = opcodeMap[opcodeType][opcodeSubType][1][typeIndex]; if (correctOdexedOpcode != odexedOpcode) { throw new AnalysisException(String.format("Incorrect field type \"%s\" for %s", fieldType, odexedOpcode.name)); } return deodexedOpcode; } }
public int getDestinationRegister() { if (!this.instruction.getOpcode().setsRegister()) { throw new ExceptionWithContext("Cannot call getDestinationRegister() for an instruction that doesn't " + "store a value"); } return ((OneRegisterInstruction)instruction).getRegisterA(); }
public int getDestinationRegister() { if (!this.instruction.getOpcode().setsRegister()) { throw new ExceptionWithContext("Cannot call getDestinationRegister() for an instruction that doesn't " + "store a value"); } return ((OneRegisterInstruction)instruction).getRegisterA(); }
public int getDestinationRegister() { if (!this.instruction.getOpcode().setsRegister()) { throw new ExceptionWithContext("Cannot call getDestinationRegister() for an instruction that doesn't " + "store a value"); } return ((OneRegisterInstruction)instruction).getRegisterA(); }
public List<Integer> getSetRegisters() { List<Integer> setRegisters = Lists.newArrayList(); if (instruction.getOpcode().setsRegister()) { setRegisters.add(getDestinationRegister());
public List<Integer> getSetRegisters() { List<Integer> setRegisters = Lists.newArrayList(); if (instruction.getOpcode().setsRegister()) { setRegisters.add(getDestinationRegister());
if (!instruction.getOpcode().setsRegister()) { return false;
if (!instruction.getOpcode().setsRegister()) { return false;