public static void generate( long baseOffset, final ITranslationEnvironment environment, final IInstruction instruction, final List<ReilInstruction> instructions, final String mnemonic, final boolean isSimplified, final boolean setCr) throws InternalTranslationException { TranslationHelpers.checkTranslationArguments(environment, instruction, instructions, mnemonic); final IOperandTreeNode registerOperand1 = instruction.getOperands().get(0).getRootNode().getChildren().get(0); final IOperandTreeNode registerOperand2 = instruction.getOperands().get(1).getRootNode().getChildren().get(0); final IOperandTreeNode integerOperand1 = instruction.getOperands().get(2).getRootNode().getChildren().get(0); final IOperandTreeNode integerOperand2 = (instruction.getOperands().size() >= 4) ? instruction.getOperands().get(3).getRootNode().getChildren().get(0) : null; final IOperandTreeNode integerOperand3 = (instruction.getOperands().size() == 5) ? instruction.getOperands().get(4).getRootNode().getChildren().get(0) : null; final String targetRegister = registerOperand1.getValue(); final String sourceRegister = registerOperand2.getValue(); String SH = ""; String MB = ""; String ME = ""; final String crTemp = environment.getNextVariableString(); final String rotateVar1 = environment.getNextVariableString(); final String rotateVar2 = environment.getNextVariableString(); final String rotateVar3 = environment.getNextVariableString(); final String rotateVar4 = environment.getNextVariableString(); /** * possible workaround for ida exporter issues with powerpc * * <p>try { int intOp1 = Integer.decode(integerOperand1.getValue()); } * * <p>catch (final NumberFormatException e) { final String [] foo = * integerOperand1.getValue().split(","); int intOp1 = Integer.decode(foo[2]); } */ if (isSimplified) { if (instruction.getMnemonic().equals("extlwi") || instruction.getMnemonic().equals("extlwi.")) { // extlwi rA,rS,n,b (n > 0) equivalent to rlwinm rA,rS,b,0,n - 1 SH = integerOperand2.getValue(); MB = String.valueOf(0L); ME = String.valueOf(Integer.decode(integerOperand1.getValue()) - 1); } else if (instruction.getMnemonic().equals("extrwi") || instruction.getMnemonic().equals("extrwi.")) { // extrwi rA,rS,n,b (n > 0) equivalent to rlwinm rA,rS,b + n,32 - n,31 SH = String.valueOf( Integer.decode(integerOperand2.getValue()) + Integer.decode(integerOperand1.getValue())); MB = String.valueOf(32 - Integer.decode(integerOperand1.getValue())); ME = String.valueOf(31L); } else if (instruction.getMnemonic().equals("rotlwi") || instruction.getMnemonic().equals("rotlwi.")) { // rotlwi rA,rS,n equivalent to rlwinm rA,rS,n,0,31 SH = integerOperand1.getValue(); MB = String.valueOf(0L); ME = String.valueOf(31L); } else if (instruction.getMnemonic().equals("rotrwi") || instruction.getMnemonic().equals("rotrwi.")) { // rotrwi rA,rS,n equivalent to rlwinm rA,rS,32 - n,0,31 SH = String.valueOf(32 - Integer.decode(integerOperand1.getValue())); MB = String.valueOf(0L); ME = String.valueOf(31L); } else if (instruction.getMnemonic().equals("slwi") || instruction.getMnemonic().equals("slwi.")) { // slwi rA,rS,n (n < 32) equivalent to rlwinm rA,rS,n,0,31 - n SH = integerOperand1.getValue(); MB = String.valueOf(0L); ME = String.valueOf(31 - Integer.decode(integerOperand1.getValue())); } else if (instruction.getMnemonic().equals("srwi") || instruction.getMnemonic().equals("srwi.")) { // srwi rA,rS,n (n < 32) equivalent to rlwinm rA,rS,32 - n,n,31 SH = String.valueOf(32 - Integer.decode(integerOperand1.getValue())); MB = integerOperand1.getValue(); ME = String.valueOf(31L); } else if (instruction.getMnemonic().equals("clrlwi") || instruction.getMnemonic().equals("clrlwi.")) { // clrlwi rA,rS,n (n < 32) equivalent to rlwinm rA,rS,0,n,31 SH = String.valueOf(0L); MB = integerOperand1.getValue(); ME = String.valueOf(31L); } else if (instruction.getMnemonic().equals("clrrwi") || instruction.getMnemonic().equals("clrrwi.")) { // clrrwi rA,rS,n (n < 32) equivalent to rlwinm rA,rS,0,0,31 - n SH = String.valueOf(0L); MB = String.valueOf(0L); ME = String.valueOf(31 - Integer.decode(integerOperand1.getValue())); } else if (instruction.getMnemonic().equals("clrlslwi") || instruction.getMnemonic().equals("clrlslwi.")) { // clrlslwi rA,rS,b,n (n <= b < 32) equivalent to rlwinm rA,rS,n,b - n,31 - n SH = integerOperand2.getValue(); MB = String.valueOf( Integer.decode(integerOperand1.getValue()) - Integer.decode(integerOperand2.getValue())); ME = String.valueOf(31 - Integer.decode(integerOperand2.getValue())); } else { SH = integerOperand1.getValue(); MB = integerOperand2.getValue(); } } else { SH = integerOperand1.getValue(); MB = integerOperand2.getValue(); ME = integerOperand3.getValue(); } final String normalMask = (instruction.getOperands().size() == 4) && !isSimplified ? integerOperand2.getValue() : Helpers.getRotateMask(MB, ME); final OperandSize dw = OperandSize.DWORD; /** * rlwinm Rotate Left Word Immediate then AND with Mask (x'5400 0000') rlwinm rA,rS,SH,MB,ME (Rc * = 0) rlwinm. rA,rS,SH,MB,ME (Rc = 1) n <- SH r <- ROTL(rS, n) m <- MASK(MB , ME) rA <- r & m * * <p>Simplified: extlwi rA,rS,n,b (n > 0) equivalent to rlwinm rA,rS,b,0,n - 1 extrwi rA,rS,n,b * (n > 0) equivalent to rlwinm rA,rS,b + n,32 - n,31 rotlwi rA,rS,n equivalent to rlwinm * rA,rS,n,0,31 rotrwi rA,rS,n equivalent to rlwinm rA,rS,32 - n,0,31 slwi rA,rS,n (n < 32) * equivalent to rlwinm rA,rS,n,0,31 - n srwi rA,rS,n (n < 32) equivalent to rlwinm rA,rS,32 - * n,n,31 clrlwi rA,rS,n (n < 32) equivalent to rlwinm rA,rS,0,n,31 clrrwi rA,rS,n (n < 32) * equivalent to rlwinm rA,rS,0,0,31 - n clrlslwi rA,rS,b,n (n <= b < 32) equivalent to rlwinm * rA,rS,n,b - n,31 - n */ // generate rotate through shift instructions.add( ReilHelpers.createBsh(baseOffset++, dw, sourceRegister, dw, SH, dw, rotateVar1)); instructions.add( ReilHelpers.createBsh( baseOffset++, dw, sourceRegister, dw, String.valueOf(-(32 - Integer.decode(SH))), dw, rotateVar2)); instructions.add( ReilHelpers.createOr(baseOffset++, dw, rotateVar1, dw, rotateVar2, dw, rotateVar3)); instructions.add( ReilHelpers.createAnd( baseOffset++, dw, rotateVar3, dw, String.valueOf(0xFFFFFFFFL), dw, rotateVar4)); // apply normal mask instructions.add( ReilHelpers.createAnd(baseOffset++, dw, rotateVar4, dw, normalMask, dw, targetRegister)); if (setCr) { // EQ CR0 instructions.add( ReilHelpers.createBisz( baseOffset++, OperandSize.DWORD, targetRegister, OperandSize.BYTE, Helpers.CR0_EQUAL)); // LT CR0 instructions.add( ReilHelpers.createBsh( baseOffset++, OperandSize.DWORD, targetRegister, OperandSize.WORD, "-31", OperandSize.BYTE, Helpers.CR0_LESS_THEN)); // GT CR0 instructions.add( ReilHelpers.createOr( baseOffset++, OperandSize.BYTE, Helpers.CR0_EQUAL, OperandSize.BYTE, Helpers.CR0_LESS_THEN, OperandSize.BYTE, crTemp)); instructions.add( ReilHelpers.createBisz( baseOffset++, OperandSize.BYTE, crTemp, OperandSize.BYTE, Helpers.CR0_GREATER_THEN)); // SO CR0 instructions.add( ReilHelpers.createStr( baseOffset, OperandSize.BYTE, Helpers.XER_SUMMARY_OVERFLOW, OperandSize.BYTE, Helpers.CRO_SUMMARY_OVERFLOW)); } }