private Insn buildLit8BinaryInsn(String binaryOperation, Register firstOpReg, byte secondOpLiteral) { Opcode opc = Opcode.valueOf(binaryOperation + "_INT_LIT8"); return new Insn22b(opc, destinationReg, firstOpReg, secondOpLiteral); }
private Insn buildLit16BinaryInsn(String binaryOperation, Register firstOpReg, short secondOpLieteral) { Opcode opc = Opcode.valueOf(binaryOperation + "_INT_LIT16"); return new Insn22s(opc, destinationReg, firstOpReg, secondOpLieteral); }
private Opcode getCastOpc(PrimitiveType sourceType, PrimitiveType castType) { Opcode opc = Opcode.valueOf(sourceType.getName().toUpperCase() + "_TO_" + castType.getName().toUpperCase()); if (opc == null) { throw new RuntimeException("unsupported cast from " + sourceType + " to " + castType); } return opc; }
private Insn build2AddrBinaryInsn(final String binaryOperation, Register secondOpReg) { String localTypeString = destinationReg.getTypeString(); localTypeString = fixIntTypeString(localTypeString); Opcode opc = Opcode.valueOf(binaryOperation + "_" + localTypeString.toUpperCase() + "_2ADDR"); return new Insn12x(opc, destinationReg, secondOpReg); }
private Insn buildNormalBinaryInsn(String binaryOperation, Register firstOpReg, Register secondOpReg) { String localTypeString = firstOpReg.getTypeString(); localTypeString = fixIntTypeString(localTypeString); Opcode opc = Opcode.valueOf(binaryOperation + "_" + localTypeString.toUpperCase()); return new Insn23x(opc, destinationReg, firstOpReg, secondOpReg); }
private Insn buildInvokeInsn(String invokeOpcode, MethodReference method, List<Register> argumentRegs) { Insn invokeInsn; int regCountForArguments = SootToDexUtils.getRealRegCount(argumentRegs); if (regCountForArguments <= 5) { Register[] paddedArray = pad35cRegs(argumentRegs); Opcode opc = Opcode.valueOf(invokeOpcode); invokeInsn = new Insn35c(opc, regCountForArguments, paddedArray[0], paddedArray[1], paddedArray[2], paddedArray[3], paddedArray[4], method); } else if (regCountForArguments <= 255) { Opcode opc = Opcode.valueOf(invokeOpcode + "_RANGE"); invokeInsn = new Insn3rc(opc, argumentRegs, (short) regCountForArguments, method); } else { throw new Error( "too many parameter registers for invoke-* (> 255): " + regCountForArguments + " or registers too big (> 4 bits)"); } // save the return type for the move-result insn stmtV.setLastReturnTypeDescriptor(method.getReturnType()); return invokeInsn; }
private Insn buildCmpInsn(String opcodePrefix, Value firstOperand, Value secondOperand) { constantV.setOrigStmt(origStmt); Register firstReg = regAlloc.asImmediate(firstOperand, constantV); Register secondReg = regAlloc.asImmediate(secondOperand, constantV); // select fitting opcode according to the prefix and the type of the // operands Opcode opc = null; // we assume that the type of the operands are equal and use only the // first one if (opcodePrefix.equals("CMP_LONG")) { opc = Opcode.CMP_LONG; } else if (firstReg.isFloat()) { opc = Opcode.valueOf(opcodePrefix + "_FLOAT"); } else if (firstReg.isDouble()) { opc = Opcode.valueOf(opcodePrefix + "_DOUBLE"); } else { throw new RuntimeException("unsupported type of operands for cmp* opcode: " + firstOperand.getType()); } return new Insn23x(opc, destinationReg, firstReg, secondReg); }
private Insn buildComparingBinaryInsn(String binaryOperation, Value firstOperand, Value secondOperand) { constantV.setOrigStmt(origStmt); Value realFirstOperand = fixNullConstant(firstOperand); Value realSecondOperand = fixNullConstant(secondOperand); Register firstOpReg = regAlloc.asImmediate(realFirstOperand, constantV); // select fitting opcode ("if" or "if-zero") InsnWithOffset comparingBinaryInsn; String opcodeName = "IF_" + binaryOperation; boolean secondOpIsInt = realSecondOperand instanceof IntConstant; boolean secondOpIsZero = secondOpIsInt && ((IntConstant) realSecondOperand).value == 0; if (secondOpIsZero) { Opcode opc = Opcode.valueOf(opcodeName.concat("Z")); comparingBinaryInsn = new Insn21t(opc, firstOpReg); comparingBinaryInsn.setTarget(targetForOffset); } else { Opcode opc = Opcode.valueOf(opcodeName); Register secondOpReg = regAlloc.asImmediate(realSecondOperand, constantV); comparingBinaryInsn = new Insn22t(opc, firstOpReg, secondOpReg); comparingBinaryInsn.setTarget(targetForOffset); } return comparingBinaryInsn; }
Opcode newOpc = Opcode.valueOf(newOpcName); Register regAClone = regA.clone(); return new Insn23x(newOpc, regA, regAClone, regB);