Search in sources :

Example 1 with BranchOperand

use of org.jikesrvm.compilers.opt.ir.operand.BranchOperand in project JikesRVM by JikesRVM.

the class AssemblerOpt method genCode.

protected final int genCode(IR ir, boolean shouldPrint) {
    int mi = 0;
    CodeArray machinecodes = ir.MIRInfo.machinecode;
    PhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet().asPPC();
    int labelCountEstimate = ir.cfg.numberOfNodes();
    branchBackPatching = new BranchInformationForBackPatching(labelCountEstimate);
    boolean unsafeCondDispl = machinecodes.length() > MAX_COND_DISPL;
    // boolean unsafeDispl = machinecodes.length() > MAX_DISPL;
    MachineCodeOffsets mcOffsets = ir.MIRInfo.mcOffsets;
    for (Instruction p = ir.firstInstructionInCodeOrder(); p != null; p = p.nextInstructionInCodeOrder()) {
        int inst = p.operator().instTemplate();
        switch(p.getOpcode()) {
            case LABEL_opcode:
                backpatchForwardBranches(p, machinecodes, mi, mcOffsets);
                break;
            case BBEND_opcode:
            case UNINT_BEGIN_opcode:
            case UNINT_END_opcode:
            case GUARD_MOVE_opcode:
            case GUARD_COMBINE_opcode:
                mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                break;
            case PPC_DATA_INT_opcode:
                {
                    int value = MIR_DataInt.getValue(p).value;
                    machinecodes.set(mi++, value);
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_DATA_LABEL_opcode:
                {
                    Instruction target = MIR_DataLabel.getTarget(p).target;
                    int targetOffset = resolveBranch(p, target, mi, mcOffsets);
                    machinecodes.set(mi++, targetOffset);
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_CRAND_opcode:
            case PPC_CRANDC_opcode:
            case PPC_CROR_opcode:
            case PPC_CRORC_opcode:
                {
                    int op0 = MIR_Condition.getResultBit(p).value & REG_MASK;
                    int op1 = MIR_Condition.getValue1Bit(p).value & REG_MASK;
                    int op2 = MIR_Condition.getValue2Bit(p).value & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 16) | (op2 << 11)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_ADD_opcode:
            case PPC_ADDr_opcode:
            case PPC_ADDC_opcode:
            case PPC_ADDE_opcode:
            case PPC_SUBF_opcode:
            case PPC_SUBFr_opcode:
            case PPC_SUBFC_opcode:
            case PPC_SUBFCr_opcode:
            case PPC_SUBFE_opcode:
            case PPC_FADD_opcode:
            case PPC_FADDS_opcode:
            case PPC_FDIV_opcode:
            case PPC_FDIVS_opcode:
            case PPC_DIVW_opcode:
            case PPC_DIVWU_opcode:
            case PPC_MULLW_opcode:
            case PPC_MULHW_opcode:
            case PPC_MULHWU_opcode:
            case PPC_FSUB_opcode:
            case PPC_FSUBS_opcode:
                {
                    int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Binary.getValue2(p).asRegister().getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 16) | (op2 << 11)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC64_MULLD_opcode:
            case PPC64_DIVD_opcode:
                {
                    if (VM.VerifyAssertions)
                        VM._assert(VM.BuildFor64Addr);
                    int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Binary.getValue2(p).asRegister().getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 16) | (op2 << 11)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_LWZX_opcode:
            case PPC_LWARX_opcode:
            case PPC_LBZX_opcode:
            case PPC_LHAX_opcode:
            case PPC_LHZX_opcode:
            case PPC_LFDX_opcode:
            case PPC_LFSX_opcode:
            case PPC_LIntX_opcode:
            case PPC_LAddrARX_opcode:
            case PPC_LAddrX_opcode:
                {
                    int op0 = MIR_Load.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Load.getAddress(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Load.getOffset(p).asRegister().getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 16) | (op2 << 11)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC64_LDX_opcode:
                {
                    if (VM.VerifyAssertions)
                        VM._assert(VM.BuildFor64Addr);
                    int op0 = MIR_Load.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Load.getAddress(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Load.getOffset(p).asRegister().getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 16) | (op2 << 11)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_STWX_opcode:
            case PPC_STWCXr_opcode:
            case PPC_STBX_opcode:
            case PPC_STHX_opcode:
            case PPC_STFDX_opcode:
            case PPC_STFSX_opcode:
            case PPC_STAddrCXr_opcode:
            case PPC_STAddrX_opcode:
            case PPC_STAddrUX_opcode:
                {
                    int op0 = MIR_Store.getValue(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Store.getAddress(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Store.getOffset(p).asRegister().getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 16) | (op2 << 11)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_LWZUX_opcode:
            case PPC_LBZUX_opcode:
            case PPC_LIntUX_opcode:
            case PPC_LAddrUX_opcode:
                {
                    int op0 = MIR_LoadUpdate.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_LoadUpdate.getAddress(p).getRegister().number & REG_MASK;
                    int op2 = MIR_LoadUpdate.getOffset(p).asRegister().getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 16) | (op2 << 11)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_LWZU_opcode:
                {
                    int op0 = MIR_LoadUpdate.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_LoadUpdate.getAddress(p).getRegister().number & REG_MASK;
                    int op2 = MIR_LoadUpdate.getOffset(p).asIntConstant().value & SHORT_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 16) | op2));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_TW_opcode:
            case PPC_TAddr_opcode:
                {
                    int op0 = MIR_Trap.getCond(p).value;
                    int op1 = MIR_Trap.getValue1(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Trap.getValue2(p).asRegister().getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 16) | (op2 << 11)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC64_TD_opcode:
                {
                    if (VM.VerifyAssertions)
                        VM._assert(VM.BuildFor64Addr);
                    int op0 = MIR_Trap.getCond(p).value;
                    int op1 = MIR_Trap.getValue1(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Trap.getValue2(p).asRegister().getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 16) | (op2 << 11)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_TWI_opcode:
                {
                    int op0 = MIR_Trap.getCond(p).value;
                    int op1 = MIR_Trap.getValue1(p).getRegister().number & REG_MASK;
                    int op2;
                    if (VM.BuildFor64Addr && MIR_Trap.getValue2(p).isLongConstant()) {
                        op2 = ((int) MIR_Trap.getValue2(p).asLongConstant().value) & SHORT_MASK;
                    } else {
                        op2 = MIR_Trap.getValue2(p).asIntConstant().value & SHORT_MASK;
                    }
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 16) | op2));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC64_TDI_opcode:
                {
                    if (VM.VerifyAssertions)
                        VM._assert(VM.BuildFor64Addr);
                    int op0 = MIR_Trap.getCond(p).value;
                    int op1 = MIR_Trap.getValue1(p).getRegister().number & REG_MASK;
                    int op2;
                    if (MIR_Trap.getValue2(p).isLongConstant()) {
                        op2 = ((int) MIR_Trap.getValue2(p).asLongConstant().value) & SHORT_MASK;
                    } else {
                        op2 = MIR_Trap.getValue2(p).asIntConstant().value & SHORT_MASK;
                    }
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 16) | op2));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case NULL_CHECK_opcode:
                /* Just a nicer name for a twi <ref> lessthan 1 */
                {
                    int op0 = PowerPCTrapOperand.LOWER;
                    int op1 = ((RegisterOperand) NullCheck.getRef(p)).getRegister().number & REG_MASK;
                    int op2 = 1;
                    inst = VM.BuildFor64Addr ? PPC64_TDI.instTemplate() : PPC_TWI.instTemplate();
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 16) | op2));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_LDI_opcode:
            case PPC_LDIS_opcode:
                // D_Form. pseudo instructions derived from PPC_ADDI and PPC_ADDIS
                {
                    int op0 = MIR_Unary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Unary.getValue(p).asIntConstant().value & SHORT_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | op1));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_ADDIC_opcode:
            case PPC_ADDICr_opcode:
            case PPC_SUBFIC_opcode:
            case PPC_MULLI_opcode:
            case PPC_ADDI_opcode:
            case PPC_ADDIS_opcode:
                {
                    int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Binary.getValue2(p).asIntConstant().value & SHORT_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 16) | op2));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_CNTLZW_opcode:
            case PPC_CNTLZAddr_opcode:
            case PPC_EXTSB_opcode:
            case PPC_EXTSBr_opcode:
            case PPC_EXTSH_opcode:
            case PPC_EXTSHr_opcode:
                {
                    int op0 = MIR_Unary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Unary.getValue(p).asRegister().getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC64_EXTSW_opcode:
            case PPC64_EXTSWr_opcode:
                {
                    if (VM.VerifyAssertions)
                        VM._assert(VM.BuildFor64Addr);
                    int op0 = MIR_Unary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Unary.getValue(p).asRegister().getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC64_EXTZW_opcode:
                {
                    if (VM.VerifyAssertions)
                        VM._assert(VM.BuildFor64Addr);
                    int op0 = MIR_Unary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Unary.getValue(p).asRegister().getRegister().number & REG_MASK;
                    // op3low = 0, so op3 == 32
                    int op3high = 1;
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21) | (op3high << 5)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_ADDZE_opcode:
            case PPC_SUBFZE_opcode:
            case PPC_NEG_opcode:
            case PPC_NEGr_opcode:
            case PPC_ADDME_opcode:
                {
                    int op0 = MIR_Unary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Unary.getValue(p).asRegister().getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 16)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            // Bit positions of op1 and op2 are reversed.
            case PPC_XORI_opcode:
            case PPC_XORIS_opcode:
                {
                    int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Binary.getValue2(p).asIntConstant().value & SHORT_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21) | op2));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            // Bit positions of op1 and op2 are reversed.
            case PPC_AND_opcode:
            case PPC_ANDr_opcode:
            case PPC_NAND_opcode:
            case PPC_NANDr_opcode:
            case PPC_ANDC_opcode:
            case PPC_ANDCr_opcode:
            case PPC_OR_opcode:
            case PPC_ORr_opcode:
            case PPC_NOR_opcode:
            case PPC_NORr_opcode:
            case PPC_ORC_opcode:
            case PPC_ORCr_opcode:
            case PPC_XOR_opcode:
            case PPC_XORr_opcode:
            case PPC_EQV_opcode:
            case PPC_EQVr_opcode:
            case PPC_SLW_opcode:
            case PPC_SLWr_opcode:
            case PPC_SRW_opcode:
            case PPC_SRWr_opcode:
            case PPC_SRAW_opcode:
            case PPC_SRAWr_opcode:
                {
                    int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Binary.getValue2(p).asRegister().getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21) | (op2 << 11)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC64_SLD_opcode:
            case PPC64_SLDr_opcode:
            case PPC64_SRD_opcode:
            case PPC64_SRDr_opcode:
            case PPC64_SRAD_opcode:
            case PPC64_SRADr_opcode:
                {
                    if (VM.VerifyAssertions)
                        VM._assert(VM.BuildFor64Addr);
                    int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Binary.getValue2(p).asRegister().getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21) | (op2 << 11)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_MOVE_opcode:
                /* pseudo opcode, equal to PPC_ORI with 0 */
                {
                    int op0 = MIR_Move.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Move.getValue(p).getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_SRWI_opcode:
            /* pseudo opcode, equal to rlwinm Rx,Ry,32-n,n,31 */
            case PPC_SRWIr_opcode:
                {
                    int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                    int shift = MIR_Binary.getValue2(p).asIntConstant().value & REG_MASK;
                    int op2 = (32 - shift);
                    int op3 = shift;
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21) | (op2 << 11) | (op3 << 6)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            // Bit positions of op1 and op2 are reversed.
            case PPC_SLWI_opcode:
            case PPC_SLWIr_opcode:
                {
                    int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                    int shift = MIR_Binary.getValue2(p).asIntConstant().value & REG_MASK;
                    int op2 = shift;
                    int op3 = (31 - shift);
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21) | (op2 << 11) | (op3 << 1)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_SRAWI_opcode:
            case PPC_SRAWIr_opcode:
                {
                    int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Binary.getValue2(p).asIntConstant().value & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21) | (op2 << 11)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_SRAddrI_opcode:
                {
                    if (VM.BuildFor32Addr) {
                        int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                        int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                        int shift = MIR_Binary.getValue2(p).asIntConstant().value & REG_MASK;
                        int op2 = (32 - shift);
                        int op3 = shift;
                        machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21) | (op2 << 11) | (op3 << 6)));
                        mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                    } else {
                        int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                        int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                        int op3 = MIR_Binary.getValue2(p).asIntConstant().value & SIXBIT_MASK;
                        int op2 = 64 - op3;
                        int op2low = op2 & 0x1F;
                        int op2high = (op2 & 0x20) >>> 5;
                        int op3low = op3 & 0x1F;
                        int op3high = (op3 & 0x20) >>> 5;
                        machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21) | (op2low << 11) | (op2high << 1) | (op3low << 6) | (op3high << 5)));
                        mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                    }
                }
                break;
            case PPC_SRAAddrI_opcode:
                {
                    if (VM.BuildFor32Addr) {
                        int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                        int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                        int op2 = MIR_Binary.getValue2(p).asIntConstant().value & REG_MASK;
                        machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21) | (op2 << 11)));
                        mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                    } else {
                        int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                        int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                        int op2 = MIR_Binary.getValue2(p).asIntConstant().value & SIXBIT_MASK;
                        int op2low = op2 & 0x1F;
                        int op2high = (op2 & 0x20) >>> 5;
                        machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21) | (op2low << 11) | (op2high << 1)));
                        mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                    }
                }
                break;
            case PPC64_SRADI_opcode:
                {
                    if (VM.VerifyAssertions)
                        VM._assert(VM.BuildFor64Addr);
                    int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Binary.getValue2(p).asIntConstant().value & SIXBIT_MASK;
                    int op2low = op2 & 0x1F;
                    int op2high = (op2 & 0x20) >>> 5;
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21) | (op2low << 11) | (op2high << 1)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC64_SRDI_opcode:
                {
                    if (VM.VerifyAssertions)
                        VM._assert(VM.BuildFor64Addr);
                    int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                    int op3 = MIR_Binary.getValue2(p).asIntConstant().value & SIXBIT_MASK;
                    int op2 = 64 - op3;
                    int op2low = op2 & 0x1F;
                    int op2high = (op2 & 0x20) >>> 5;
                    int op3low = op3 & 0x1F;
                    int op3high = (op3 & 0x20) >>> 5;
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21) | (op2low << 11) | (op2high << 1) | (op3low << 6) | (op3high << 5)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case // shorthand via RLDICR
            PPC64_SLDI_opcode:
                {
                    if (VM.VerifyAssertions)
                        VM._assert(VM.BuildFor64Addr);
                    int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                    int shift = MIR_Binary.getValue2(p).asIntConstant().value & SIXBIT_MASK;
                    int op2 = shift;
                    int op2low = op2 & 0x1F;
                    int op2high = (op2 & 0x20) >>> 5;
                    int op3 = 63 - shift;
                    int op3low = op3 & 0x1F;
                    int op3high = (op3 & 0x20) >>> 5;
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21) | (op2low << 11) | (op2high << 1) | (op3low << 6) | (op3high << 5)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC64_RLDICR_opcode:
                {
                    if (VM.VerifyAssertions)
                        VM._assert(VM.BuildFor64Addr);
                    int op0 = MIR_RotateAndMask.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_RotateAndMask.getValue(p).getRegister().number & REG_MASK;
                    // shift
                    int op2 = MIR_RotateAndMask.getShift(p).asIntConstant().value & SIXBIT_MASK;
                    int op2low = op2 & 0x1F;
                    int op2high = (op2 & 0x20) >>> 5;
                    // mask
                    int op3 = MIR_RotateAndMask.getMaskEnd(p).value & SIXBIT_MASK;
                    int op3low = op3 & 0x1F;
                    int op3high = (op3 & 0x20) >>> 5;
                    if (VM.VerifyAssertions) {
                        int op4 = MIR_RotateAndMask.getMaskBegin(p).value & SIXBIT_MASK;
                        VM._assert(op4 == 0);
                    }
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21) | (op2low << 11) | (op2high << 1) | (op3low << 6) | (op3high << 5)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC64_RLDICL_opcode:
                {
                    if (VM.VerifyAssertions)
                        VM._assert(VM.BuildFor64Addr);
                    int op0 = MIR_RotateAndMask.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_RotateAndMask.getValue(p).getRegister().number & REG_MASK;
                    // shift
                    int op2 = MIR_RotateAndMask.getShift(p).asIntConstant().value & SIXBIT_MASK;
                    int op2low = op2 & 0x1F;
                    int op2high = (op2 & 0x20) >>> 5;
                    // mask
                    int op3 = MIR_RotateAndMask.getMaskBegin(p).value & SIXBIT_MASK;
                    int op3low = op3 & 0x1F;
                    int op3high = (op3 & 0x20) >>> 5;
                    if (VM.VerifyAssertions) {
                        int op4 = MIR_RotateAndMask.getMaskEnd(p).value & SIXBIT_MASK;
                        VM._assert(op4 == 63);
                    }
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21) | (op2low << 11) | (op2high << 1) | (op3low << 6) | (op3high << 5)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            // Bit positions of op1 and op2 are reversed.
            case PPC_ANDIr_opcode:
            case PPC_ANDISr_opcode:
            case PPC_ORI_opcode:
            case PPC_ORIS_opcode:
                {
                    int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Binary.getValue2(p).asIntConstant().value & SHORT_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21) | op2));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_RLWINM_opcode:
            case PPC_RLWINMr_opcode:
                {
                    int op0 = MIR_RotateAndMask.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_RotateAndMask.getValue(p).getRegister().number & REG_MASK;
                    int op2 = MIR_RotateAndMask.getShift(p).asIntConstant().value & REG_MASK;
                    int op3 = MIR_RotateAndMask.getMaskBegin(p).value & REG_MASK;
                    int op4 = MIR_RotateAndMask.getMaskEnd(p).value & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21) | (op2 << 11) | (op3 << 6) | (op4 << 1)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_RLWIMI_opcode:
            case PPC_RLWIMIr_opcode:
                {
                    int op0 = MIR_RotateAndMask.getResult(p).getRegister().number & REG_MASK;
                    int op0f = MIR_RotateAndMask.getSource(p).getRegister().number & REG_MASK;
                    if (op0 != op0f) {
                        throw new OptimizingCompilerException("CodeGen", "format for RLWIMI is incorrect");
                    }
                    int op1 = MIR_RotateAndMask.getValue(p).getRegister().number & REG_MASK;
                    int op2 = MIR_RotateAndMask.getShift(p).asIntConstant().value & REG_MASK;
                    int op3 = MIR_RotateAndMask.getMaskBegin(p).value & REG_MASK;
                    int op4 = MIR_RotateAndMask.getMaskEnd(p).value & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21) | (op2 << 11) | (op3 << 6) | (op4 << 1)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_RLWNM_opcode:
            case PPC_RLWNMr_opcode:
                {
                    int op0 = MIR_RotateAndMask.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_RotateAndMask.getValue(p).getRegister().number & REG_MASK;
                    int op2 = MIR_RotateAndMask.getShift(p).asRegister().getRegister().number & REG_MASK;
                    int op3 = MIR_RotateAndMask.getMaskBegin(p).value & REG_MASK;
                    int op4 = MIR_RotateAndMask.getMaskEnd(p).value & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21) | (op2 << 11) | (op3 << 6) | (op4 << 1)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_B_opcode:
                {
                    BranchOperand o = MIR_Branch.getTarget(p);
                    int targetOffset = resolveBranch(p, o.target, mi, mcOffsets);
                    machinecodes.set(mi++, inst | (targetOffset & LI_MASK));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_BLR_opcode:
            case PPC_BCTR_opcode:
                /* p   , == bcctr  0x14,BI */
                {
                    // INDIRECT BRANCH (Target == null)
                    machinecodes.set(mi++, inst);
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_BC_opcode:
            case PPC_BCOND_opcode:
            /* p 38, BO == 001zy or 011zy */
            case PPC_BCC_opcode:
                /* p 38, BO == 0000y, 0001y, 0100y or 0101y */
                {
                    // COND BRANCH
                    int op0 = MIR_CondBranch.getValue(p).getRegister().number & REG_MASK;
                    int op1 = MIR_CondBranch.getCond(p).value;
                    // Add (CR field)<<2 to make BI represent the correct
                    // condition bit (0..3) in the correct condition field (0..7).
                    // 1 <= op <= 7
                    int bo_bi = op0 << 2 | op1;
                    BranchOperand o = MIR_CondBranch.getTarget(p);
                    int targetOffset = resolveBranch(p, o.target, mi, mcOffsets);
                    if (targetOffset == 0) {
                        // unresolved branch
                        if (DEBUG)
                            VM.sysWriteln("**** Forward Cond. Branch ****");
                        machinecodes.set(mi++, inst | (bo_bi << 16));
                        mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                        if (DEBUG)
                            VM.sysWriteln(disasm(machinecodes.get(mi - 1), 0));
                        if (unsafeCondDispl) {
                            // assume we might need two words
                            // for now fill with NOP
                            machinecodes.set(mi++, NOPtemplate);
                            if (DEBUG)
                                VM.sysWriteln(disasm(machinecodes.get(mi - 1), 0));
                        }
                    } else if (targetOffset < MIN_COND_DISPL << 2) {
                        // one word is not enough
                        if (DEBUG)
                            VM.sysWriteln("**** Backward Long Cond. Branch ****");
                        // flip the condition and skip the following branch instruction
                        if (DEBUG)
                            VM.sysWriteln(disasm(machinecodes.get(mi - 1), 0));
                        machinecodes.set(mi++, inst | flipCondition(bo_bi << 16) | (2 << 2));
                        if (DEBUG)
                            VM.sysWriteln(disasm(machinecodes.get(mi - 1), 0));
                        // make a long branch to the target
                        machinecodes.set(mi++, Btemplate | ((targetOffset - 4) & LI_MASK));
                        mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                        if (DEBUG)
                            VM.sysWriteln(disasm(machinecodes.get(mi - 1), 0));
                    } else {
                        // one word is enough
                        if (DEBUG)
                            VM.sysWriteln("**** Backward Short Cond. Branch ****");
                        machinecodes.set(mi++, inst | (bo_bi << 16) | (targetOffset & BD_MASK));
                        mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                        if (DEBUG)
                            VM.sysWriteln(disasm(machinecodes.get(mi - 1), 0));
                    }
                }
                break;
            case PPC_BCLR_opcode:
            case PPC_BCCTR_opcode:
                /* p   , BO == 0z10y or 0z11y */
                {
                    // INDIRECT COND BRANCH
                    int op0 = MIR_CondBranch.getValue(p).getRegister().number & REG_MASK;
                    int op1 = MIR_CondBranch.getCond(p).value;
                    // Add (CR field)<<2 to make BI represent the correct
                    // condition bit (0..3) in the correct condition field (0..7).
                    // 1 <= op <= 7
                    int bo_bi = op0 << 2 | op1;
                    machinecodes.set(mi++, inst | (bo_bi << 16));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                    if (DEBUG)
                        VM.sysWrite(disasm(machinecodes.get(mi - 1), 0));
                }
                break;
            case PPC_BL_opcode:
            case PPC_BL_SYS_opcode:
                {
                    // CALL
                    BranchOperand o = MIR_Call.getTarget(p);
                    int targetOffset = resolveBranch(p, o.target, mi, mcOffsets);
                    machinecodes.set(mi++, inst | (targetOffset & LI_MASK));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_BLRL_opcode:
            /* p 39, == bclrl  0x14,BI */
            case PPC_BCTRL_opcode:
            /* p   , == bcctrl 0x14,BI */
            case PPC_BCTRL_SYS_opcode:
                /* p   , == bcctrl 0x14,BI */
                {
                    // INDIRECT CALL (Target == null)
                    machinecodes.set(mi++, inst);
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_BCL_opcode:
                {
                    // COND CALL
                    int op0 = MIR_CondCall.getValue(p).getRegister().number & REG_MASK;
                    int op1 = MIR_CondCall.getCond(p).value;
                    // Add (CR field)<<2 to make BI represent the correct
                    // condition bit (0..3) in the correct condition field (0..7).
                    // 1 <= op <= 7
                    int bo_bi = op0 << 2 | op1;
                    BranchOperand o = MIR_CondCall.getTarget(p);
                    int targetOffset = resolveBranch(p, o.target, mi, mcOffsets);
                    if (targetOffset == 0) {
                        // unresolved branch
                        if (DEBUG)
                            VM.sysWriteln("**** Forward Cond. Branch ****");
                        machinecodes.set(mi++, inst | (bo_bi << 16));
                        mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                        if (DEBUG)
                            VM.sysWriteln(disasm(machinecodes.get(mi - 1), 0));
                        if (unsafeCondDispl) {
                            // assume we need two words
                            // for now fill with NOP
                            machinecodes.set(mi++, NOPtemplate);
                            if (DEBUG)
                                VM.sysWriteln(disasm(machinecodes.get(mi - 1), 0));
                        }
                    } else if (targetOffset < MIN_COND_DISPL << 2) {
                        // one instruction is not enough
                        throw new OperationNotImplementedException(// --dave
                        "Support for long backwards conditional branch and link is incorrect.");
                    /*
              -- we have to branch (and not link) around an
              unconditional branch and link.
              -- the code below generates a conditional branch and
              link around an unconditional branch.
              if (DEBUG) VM.sysWriteln("**** Backward Long Cond. Branch ****");
              // flip the condition and skip the following branch instruction
              machinecodes.set(mi++, inst | flipCondition(bo_bi<<16) | (2<<2));
              if (DEBUG) printInstruction(mi-1, inst,
              flipCondition(bo_bi<<16), 2<<2);
              // make a long branch to the target
              machinecodes.set(mi++, Btemplate | ((targetOffset-4) & LI_MASK));
              mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
              if (DEBUG) printInstruction(mi-1, Btemplate, targetOffset-4);
            */
                    } else {
                        // one instruction is enough
                        if (DEBUG)
                            VM.sysWriteln("**** Backward Short Cond. Branch ****");
                        machinecodes.set(mi++, inst | (bo_bi << 16) | (targetOffset & BD_MASK));
                        mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                        if (DEBUG)
                            VM.sysWrite(disasm(machinecodes.get(mi - 1), 0));
                    }
                }
                break;
            case PPC_BCLRL_opcode:
                {
                    // INDIRECT COND CALL
                    int op0 = MIR_CondCall.getValue(p).getRegister().number & REG_MASK;
                    int op1 = MIR_CondCall.getCond(p).value;
                    // Add (CR field)<<2 to make BI represent the correct
                    // condition bit (0..3) in the correct condition field (0..7).
                    // 1 <= op <= 7
                    int bo_bi = op0 << 2 | op1;
                    machinecodes.set(mi++, inst | (bo_bi << 16));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                    if (DEBUG)
                        VM.sysWrite(disasm(machinecodes.get(mi - 1), 0));
                }
                break;
            case PPC_CMP_opcode:
            case PPC_CMPL_opcode:
                {
                    int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Binary.getValue2(p).asRegister().getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 23) | (op1 << 16) | (op2 << 11)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC64_CMP_opcode:
            case PPC64_CMPL_opcode:
                {
                    if (VM.VerifyAssertions)
                        VM._assert(VM.BuildFor64Addr);
                    int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Binary.getValue2(p).asRegister().getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 23) | (op1 << 16) | (op2 << 11)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_CMPI_opcode:
            case PPC_CMPLI_opcode:
                {
                    int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Binary.getValue2(p).asIntConstant().value & SHORT_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 23) | (op1 << 16) | op2));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC64_CMPI_opcode:
            case PPC64_CMPLI_opcode:
                {
                    if (VM.VerifyAssertions)
                        VM._assert(VM.BuildFor64Addr);
                    int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Binary.getValue2(p).asIntConstant().value & SHORT_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 23) | (op1 << 16) | op2));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_FMR_opcode:
                {
                    int op0 = MIR_Move.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Move.getValue(p).getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 11)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_FABS_opcode:
            case PPC_FNEG_opcode:
            case PPC_FSQRT_opcode:
            case PPC_FSQRTS_opcode:
            case PPC_FRSP_opcode:
            case PPC_FCTIW_opcode:
            case PPC_FCTIWZ_opcode:
                {
                    int op0 = MIR_Unary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Unary.getValue(p).asRegister().getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 11)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC64_FCFID_opcode:
            case PPC64_FCTIDZ_opcode:
                {
                    if (VM.VerifyAssertions)
                        VM._assert(VM.BuildFor64Addr);
                    int op0 = MIR_Unary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Unary.getValue(p).asRegister().getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 11)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_FCMPO_opcode:
            case PPC_FCMPU_opcode:
                {
                    int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Binary.getValue2(p).asRegister().getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 23) | (op1 << 16) | (op2 << 11)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_FMUL_opcode:
            case PPC_FMULS_opcode:
                {
                    int op0 = MIR_Binary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Binary.getValue1(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Binary.getValue2(p).asRegister().getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 16) | (op2 << 6)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_FMADD_opcode:
            case PPC_FMADDS_opcode:
            case PPC_FMSUB_opcode:
            case PPC_FMSUBS_opcode:
            case PPC_FNMADD_opcode:
            case PPC_FNMADDS_opcode:
            case PPC_FNMSUB_opcode:
            case PPC_FNMSUBS_opcode:
            case PPC_FSEL_opcode:
                {
                    int op0 = MIR_Ternary.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Ternary.getValue1(p).getRegister().number & REG_MASK;
                    int op2 = MIR_Ternary.getValue2(p).getRegister().number & REG_MASK;
                    int op3 = MIR_Ternary.getValue3(p).getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 16) | (op2 << 6) | (op3 << 11)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_LWZ_opcode:
            case PPC_LBZ_opcode:
            case PPC_LHA_opcode:
            case PPC_LHZ_opcode:
            case PPC_LFD_opcode:
            case PPC_LFS_opcode:
            case PPC_LMW_opcode:
                {
                    int op0 = MIR_Load.getResult(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Load.getOffset(p).asIntConstant().value & SHORT_MASK;
                    int op2 = MIR_Load.getAddress(p).getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | op1 | (op2 << 16)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC64_LD_opcode:
                {
                    if (VM.VerifyAssertions)
                        VM._assert(VM.BuildFor64Addr);
                    int op0 = MIR_Load.getResult(p).getRegister().number & REG_MASK;
                    int op1 = (MIR_Load.getOffset(p).asIntConstant().value >> 2) & SHORT14_MASK;
                    int op2 = MIR_Load.getAddress(p).getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 2) | (op2 << 16)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_LAddr_opcode:
            case PPC_LInt_opcode:
                {
                    if (VM.BuildFor32Addr) {
                        int op0 = MIR_Load.getResult(p).getRegister().number & REG_MASK;
                        int op1 = MIR_Load.getOffset(p).asIntConstant().value & SHORT_MASK;
                        int op2 = MIR_Load.getAddress(p).getRegister().number & REG_MASK;
                        machinecodes.set(mi++, (inst | (op0 << 21) | op1 | (op2 << 16)));
                        mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                    } else {
                        int op0 = MIR_Load.getResult(p).getRegister().number & REG_MASK;
                        int op1 = (MIR_Load.getOffset(p).asIntConstant().value >> 2) & SHORT14_MASK;
                        int op2 = MIR_Load.getAddress(p).getRegister().number & REG_MASK;
                        machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 2) | (op2 << 16)));
                        mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                    }
                }
                break;
            case PPC_STW_opcode:
            case PPC_STB_opcode:
            case PPC_STH_opcode:
            case PPC_STFD_opcode:
            case PPC_STFS_opcode:
            case PPC_STMW_opcode:
                {
                    int op0 = MIR_Store.getValue(p).getRegister().number & REG_MASK;
                    int op1 = MIR_Store.getOffset(p).asIntConstant().value & SHORT_MASK;
                    int op2 = MIR_Store.getAddress(p).getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | op1 | (op2 << 16)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_STWU_opcode:
            case PPC_STFDU_opcode:
            case PPC_STFSU_opcode:
                {
                    int op0 = MIR_StoreUpdate.getValue(p).getRegister().number & REG_MASK;
                    int op1 = MIR_StoreUpdate.getAddress(p).getRegister().number & REG_MASK;
                    int op2 = MIR_StoreUpdate.getOffset(p).asIntConstant().value & SHORT_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 16) | op2));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC64_STD_opcode:
                {
                    if (VM.VerifyAssertions)
                        VM._assert(VM.BuildFor64Addr);
                    int op0 = MIR_Store.getValue(p).getRegister().number & REG_MASK;
                    int op1 = (MIR_Store.getOffset(p).asIntConstant().value >> 2) & SHORT14_MASK;
                    int op2 = MIR_Store.getAddress(p).getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 2) | (op2 << 16)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_STAddr_opcode:
                {
                    if (VM.BuildFor32Addr) {
                        int op0 = MIR_Store.getValue(p).getRegister().number & REG_MASK;
                        int op1 = MIR_Store.getOffset(p).asIntConstant().value & SHORT_MASK;
                        int op2 = MIR_Store.getAddress(p).getRegister().number & REG_MASK;
                        machinecodes.set(mi++, (inst | (op0 << 21) | op1 | (op2 << 16)));
                        mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                    } else {
                        int op0 = MIR_Store.getValue(p).getRegister().number & REG_MASK;
                        int op1 = (MIR_Store.getOffset(p).asIntConstant().value >> 2) & SHORT14_MASK;
                        int op2 = MIR_Store.getAddress(p).getRegister().number & REG_MASK;
                        machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 2) | (op2 << 16)));
                        mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                    }
                }
                break;
            case PPC_STAddrU_opcode:
                {
                    if (VM.BuildFor32Addr) {
                        int op0 = MIR_StoreUpdate.getValue(p).getRegister().number & REG_MASK;
                        int op1 = MIR_StoreUpdate.getAddress(p).getRegister().number & REG_MASK;
                        int op2 = MIR_StoreUpdate.getOffset(p).asIntConstant().value & SHORT_MASK;
                        machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 16) | op2));
                        mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                    } else {
                        int op0 = MIR_StoreUpdate.getValue(p).getRegister().number & REG_MASK;
                        int op1 = (MIR_StoreUpdate.getOffset(p).asIntConstant().value >> 2) & SHORT14_MASK;
                        int op2 = MIR_StoreUpdate.getAddress(p).getRegister().number & REG_MASK;
                        machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 2) | (op2 << 16)));
                        mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                    }
                }
                break;
            case PPC_MFSPR_opcode:
                {
                    int op0 = MIR_Move.getResult(p).getRegister().number & REG_MASK;
                    int op1 = phys.getSPR(MIR_Move.getValue(p).getRegister());
                    machinecodes.set(mi++, (inst | (op0 << 21) | (op1 << 16)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_MTSPR_opcode:
                {
                    int op0 = phys.getSPR(MIR_Move.getResult(p).getRegister());
                    int op1 = MIR_Move.getValue(p).getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 21)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_MFTB_opcode:
            case PPC_MFTBU_opcode:
                {
                    int op0 = MIR_Move.getResult(p).getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 21)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_HWSYNC_opcode:
            case PPC_SYNC_opcode:
            case PPC_ISYNC_opcode:
                {
                    machinecodes.set(mi++, inst);
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_DCBST_opcode:
            case PPC_DCBT_opcode:
            case PPC_DCBTST_opcode:
            case PPC_DCBZ_opcode:
            case PPC_DCBZL_opcode:
            case PPC_DCBF_opcode:
            case PPC_ICBI_opcode:
                {
                    int op0 = MIR_CacheOp.getAddress(p).getRegister().number & REG_MASK;
                    int op1 = MIR_CacheOp.getOffset(p).getRegister().number & REG_MASK;
                    machinecodes.set(mi++, (inst | (op0 << 16) | (op1 << 11)));
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case PPC_ILLEGAL_INSTRUCTION_opcode:
                {
                    machinecodes.set(mi++, inst);
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                }
                break;
            case IG_PATCH_POINT_opcode:
                {
                    BranchOperand bop = InlineGuard.getTarget(p);
                    Instruction target = bop.target;
                    if (VM.VerifyAssertions) {
                        VM._assert(target.getOpcode() == LABEL_opcode);
                    }
                    // resolve the target instruction, in LABEL_opcode,
                    // add one case for IG_PATCH_POINT
                    /* int targetOffset = */
                    resolveBranch(p, target, mi, mcOffsets);
                    machinecodes.set(mi++, NOPtemplate);
                    mcOffsets.setMachineCodeOffset(p, mi << LG_INSTRUCTION_WIDTH);
                    if (DEBUG_CODE_PATCH) {
                        VM.sysWrite("to be patched at ", mi - 1);
                        VM.sysWrite(" inst ");
                        VM.sysWriteHex(machinecodes.get(mi - 1));
                        VM.sysWriteln();
                    }
                }
                break;
            default:
                throw new OptimizingCompilerException("CodeGen", "OPCODE not implemented:", p);
        }
    }
    if (unresolvedBranches != 0) {
        throw new OptimizingCompilerException("CodeGen", " !!! Unresolved Branch Targets Exist!!! \n");
    }
    if (shouldPrint) {
        OptimizingCompiler.header("Final machine code", ir.method);
        Lister lister = new Lister(null);
        lister.addLinesForCode(machinecodes);
        lister.endAndPrintListing();
    }
    return mi;
}
Also used : CodeArray(org.jikesrvm.compilers.common.CodeArray) Lister(org.jikesrvm.compilers.common.assembler.ppc.Lister) PhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet) MachineCodeOffsets(org.jikesrvm.compilers.opt.mir2mc.MachineCodeOffsets) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) OperationNotImplementedException(org.jikesrvm.compilers.opt.OperationNotImplementedException) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand)

Example 2 with BranchOperand

use of org.jikesrvm.compilers.opt.ir.operand.BranchOperand in project JikesRVM by JikesRVM.

the class ReorderingPhase method exileInfrequentBlocks.

// ///////////////////////
// Code for trivial algorithm
// ///////////////////////
/**
 * Select a new basic block ordering via a simple heuristic
 * that moves all infrequent basic blocks to the end.
 * @param ir the IR object to reorder
 */
private void exileInfrequentBlocks(IR ir) {
    // (1) Look to see if there are infrequent blocks
    // Also count how many blocks there are.
    int numBlocks = 0;
    boolean foundSome = false;
    for (Enumeration<BasicBlock> e = ir.getBasicBlocks(); e.hasMoreElements(); ) {
        BasicBlock bb = e.nextElement();
        numBlocks++;
        foundSome |= bb.getInfrequent();
    }
    // Nothing to do
    if (!foundSome)
        return;
    // Reorder the blocks to exile the infrequent blocks.
    // Relative order within the set of frequent and infrequent is unchanged.
    BasicBlock[] newOrdering = new BasicBlock[numBlocks];
    int idx = 0;
    // First append frequent blocks to newOrdering
    for (BasicBlock bb = ir.cfg.firstInCodeOrder(); bb != null; bb = bb.nextBasicBlockInCodeOrder()) {
        if (!bb.getInfrequent()) {
            newOrdering[idx++] = bb;
        }
    }
    // Next append infrequent blocks to newOrdering
    for (BasicBlock bb = ir.cfg.firstInCodeOrder(); bb != null; bb = bb.nextBasicBlockInCodeOrder()) {
        if (bb.getInfrequent()) {
            newOrdering[idx++] = bb;
        }
    }
    // don't lose blocks!
    if (VM.VerifyAssertions)
        VM._assert(idx == numBlocks);
    if (VM.VerifyAssertions)
        VM._assert(ir.cfg.entry() == newOrdering[0]);
    // Add/remove unconditional goto's as needed.
    for (int i = 0; i < newOrdering.length; i++) {
        Instruction lastInstr = newOrdering[i].lastRealInstruction();
        // Append a GOTO if needed to maintain old fallthrough semantics.
        BasicBlock fallthroughBlock = newOrdering[i].getFallThroughBlock();
        if (fallthroughBlock != null) {
            if (i == newOrdering.length - 1 || fallthroughBlock != newOrdering[i + 1]) {
                // Add unconditional goto to preserve old fallthrough semantics
                newOrdering[i].appendInstruction(fallthroughBlock.makeGOTO());
            }
        }
        // (Only possible if newOrdering[i] is not the last basic block.)
        if (i < newOrdering.length - 1 && lastInstr != null && lastInstr.operator() == GOTO) {
            BranchOperand op = Goto.getTarget(lastInstr);
            if (op.target.getBasicBlock() == newOrdering[i + 1]) {
                // unconditional goto is redundant in new ordering
                lastInstr.remove();
            }
        }
    }
    // Re-insert all basic blocks according to new ordering
    ir.cfg.clearCodeOrder();
    for (BasicBlock bb : newOrdering) {
        ir.cfg.addLastInCodeOrder(bb);
    }
}
Also used : BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand)

Example 3 with BranchOperand

use of org.jikesrvm.compilers.opt.ir.operand.BranchOperand in project JikesRVM by JikesRVM.

the class MIRBranchOptimizations method processGoto.

/**
 * Perform optimizations for an unconditonal branch.
 *
 * <p> Patterns:
 * <pre>
 *    1)      GOTO A       replaced by  GOTO B
 *         A: GOTO B
 *
 *    2)   GOTO next instruction eliminated
 *    3)      GOTO A       replaced by  GOTO B
 *         A: LABEL
 *            BBEND
 *         B:
 * </pre>
 *
 * <p> Precondition: MIR_Branch.conforms(g)
 *
 * @param ir governing IR
 * @param g the instruction to optimize
 * @param bb the basic block holding g
 * @return {@code true} if made a transformation
 */
private boolean processGoto(IR ir, Instruction g, BasicBlock bb) {
    BasicBlock targetBlock = g.getBranchTarget();
    Instruction targetLabel = targetBlock.firstInstruction();
    // get the first real instruction at the g target
    // NOTE: this instruction is not necessarily in targetBlock,
    // iff targetBlock has no real instructions
    Instruction targetInst = firstRealInstructionFollowing(targetLabel);
    if (targetInst == null || targetInst == g) {
        return false;
    }
    Instruction nextLabel = firstLabelFollowing(g);
    if (targetLabel == nextLabel) {
        // found a GOTO to the next instruction.  just remove it.
        g.remove();
        return true;
    }
    if (isMIR_Branch(targetInst)) {
        // unconditional branch to unconditional branch.
        // replace g with goto to targetInst's target
        Instruction target2 = firstRealInstructionFollowing(targetInst.getBranchTarget().firstInstruction());
        if (target2 == targetInst) {
            // This happens in jByteMark.EmFloatPnt.denormalize() due to a while(true) {}
            return false;
        }
        BranchOperand top = (BranchOperand) (MIR_Branch_getTarget(targetInst).copy());
        MIR_Branch_setTarget(g, top);
        // fix the CFG
        bb.recomputeNormalOut(ir);
        return true;
    }
    if (targetBlock.isEmpty()) {
        // GOTO an empty block.  Change target to the next block.
        BasicBlock nextBlock = targetBlock.getFallThroughBlock();
        MIR_Branch_setTarget(g, nextBlock.makeJumpTarget());
        // fix the CFG
        bb.recomputeNormalOut(ir);
        return true;
    }
    return false;
}
Also used : BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand)

Example 4 with BranchOperand

use of org.jikesrvm.compilers.opt.ir.operand.BranchOperand in project JikesRVM by JikesRVM.

the class IRTools method makeBlockOnEdge.

/**
 * Make an empty basic block on an edge in the control flow graph,
 * and fix up the control flow graph and IR instructions accordingly.
 *
 * This routine will create the control struture
 * <pre>
 * in -&gt; bb -&gt; out.
 * </pre>
 * <em> Precondition </em>: There is an edge in the control flow graph
 * from * in -&gt; out.
 *
 * @param in the source of the control flow edge
 * @param out the sink of the control flow edge
 * @param ir the governing IR
 * @return the new basic block bb
 */
public static BasicBlock makeBlockOnEdge(BasicBlock in, BasicBlock out, IR ir) {
    // 1. Create the new basic block
    BasicBlock bb = in.createSubBlock(out.firstInstruction().getBytecodeIndex(), ir);
    // 2. Splice the new basic block into the code order
    BasicBlock next = in.nextBasicBlockInCodeOrder();
    if (next == null) {
        ir.cfg.addLastInCodeOrder(bb);
    } else {
        ir.cfg.breakCodeOrder(in, next);
        ir.cfg.linkInCodeOrder(in, bb);
        ir.cfg.linkInCodeOrder(bb, next);
    }
    // 3. update in's branch instructions
    boolean foundGoto = false;
    BranchOperand target = bb.makeJumpTarget();
    BranchOperand outTarget = out.makeJumpTarget();
    for (Enumeration<Instruction> e = in.reverseRealInstrEnumerator(); e.hasMoreElements(); ) {
        Instruction s = e.nextElement();
        if (IfCmp2.conforms(s)) {
            if (IfCmp2.getTarget1(s).similar(outTarget)) {
                IfCmp2.setTarget1(s, (BranchOperand) target.copy());
            }
            if (IfCmp2.getTarget2(s).similar(outTarget)) {
                IfCmp2.setTarget2(s, (BranchOperand) target.copy());
            }
        } else if (IfCmp.conforms(s)) {
            if (IfCmp.getTarget(s).similar(outTarget)) {
                IfCmp.setTarget(s, (BranchOperand) target.copy());
            }
        } else if (InlineGuard.conforms(s)) {
            if (InlineGuard.getTarget(s).similar(outTarget)) {
                InlineGuard.setTarget(s, (BranchOperand) target.copy());
            }
        } else if (Goto.conforms(s)) {
            foundGoto = true;
            if (Goto.getTarget(s).similar(outTarget)) {
                Goto.setTarget(s, (BranchOperand) target.copy());
            }
        } else if (TableSwitch.conforms(s)) {
            foundGoto = true;
            if (TableSwitch.getDefault(s).similar(outTarget)) {
                TableSwitch.setDefault(s, (BranchOperand) target.copy());
            }
            for (int i = 0; i < TableSwitch.getNumberOfTargets(s); i++) {
                if (TableSwitch.getTarget(s, i).similar(outTarget)) {
                    TableSwitch.setTarget(s, i, (BranchOperand) target.copy());
                }
            }
        } else if (LowTableSwitch.conforms(s)) {
            foundGoto = true;
            for (int i = 0; i < LowTableSwitch.getNumberOfTargets(s); i++) {
                if (LowTableSwitch.getTarget(s, i).similar(outTarget)) {
                    LowTableSwitch.setTarget(s, i, (BranchOperand) target.copy());
                }
            }
        } else if (LookupSwitch.conforms(s)) {
            foundGoto = true;
            if (LookupSwitch.getDefault(s).similar(outTarget)) {
                LookupSwitch.setDefault(s, (BranchOperand) target.copy());
            }
            for (int i = 0; i < LookupSwitch.getNumberOfTargets(s); i++) {
                if (LookupSwitch.getTarget(s, i).similar(outTarget)) {
                    LookupSwitch.setTarget(s, i, (BranchOperand) target.copy());
                }
            }
        } else {
            // done processing all branches
            break;
        }
    }
    // 4. Add a goto bb->out
    Instruction s = Goto.create(GOTO, out.makeJumpTarget());
    bb.appendInstruction(s);
    // control flow
    if (out != next) {
        // if there's already a GOTO, there's no fall through
        if (!foundGoto) {
            /*
         * TODO: come up with a better fix (?).
         *
         * This is a fix to a particular problem in dacapo xalan.
         *
         * We have a loop inside an exception handler, and the exception handler
         * is empty.  The loop termination condition simply falls through the
         * exception handler to the next block.  This works fine until LeaveSSA,
         * when we split the final block and insert a GOTO to the exception handler
         * block.  When we reassemble the IR afterwards, kaboom.
         *
         * I would have though it better not to fall through empty exception handlers
         * at all, and explicitly GOTO past them from the get go.   RJG 4/2/7
         */
            BasicBlock jumpTarget = next;
            while (jumpTarget.isEmpty() && jumpTarget.isExceptionHandlerBasicBlock()) {
                jumpTarget = jumpTarget.nextBasicBlockInCodeOrder();
            }
            s = Goto.create(GOTO, jumpTarget.makeJumpTarget());
            in.appendInstruction(s);
        }
    }
    // 5. Update the CFG
    in.recomputeNormalOut(ir);
    bb.recomputeNormalOut(ir);
    return bb;
}
Also used : BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand)

Example 5 with BranchOperand

use of org.jikesrvm.compilers.opt.ir.operand.BranchOperand in project JikesRVM by JikesRVM.

the class Instruction method getBranchTargets.

/**
 * Return an enumeration of the basic blocks that are targets of this
 * branch instruction.
 *
 * @return the targets of this branch instruction
 */
public Enumeration<BasicBlock> getBranchTargets() {
    int n = getNumberOfOperands();
    BasicBlock.ComputedBBEnum e = new BasicBlock.ComputedBBEnum(n);
    switch(getOpcode()) {
        case GOTO_opcode:
            {
                BranchOperand tgt = Goto.getTarget(this);
                e.addElement(tgt.target.getBasicBlock());
            }
            break;
        case INT_IFCMP2_opcode:
            e.addElement(IfCmp2.getTarget1(this).target.getBasicBlock());
            e.addPossiblyDuplicateElement(IfCmp2.getTarget2(this).target.getBasicBlock());
            break;
        case INT_IFCMP_opcode:
        case REF_IFCMP_opcode:
        case LONG_IFCMP_opcode:
        case FLOAT_IFCMP_opcode:
        case DOUBLE_IFCMP_opcode:
            e.addElement(IfCmp.getTarget(this).target.getBasicBlock());
            break;
        case IG_PATCH_POINT_opcode:
        case IG_CLASS_TEST_opcode:
        case IG_METHOD_TEST_opcode:
            e.addElement(InlineGuard.getTarget(this).target.getBasicBlock());
            break;
        case TABLESWITCH_opcode:
            e.addElement(TableSwitch.getDefault(this).target.getBasicBlock());
            for (int i = 0; i < TableSwitch.getNumberOfTargets(this); i++) {
                e.addPossiblyDuplicateElement(TableSwitch.getTarget(this, i).target.getBasicBlock());
            }
            break;
        case LOWTABLESWITCH_opcode:
            for (int i = 0; i < LowTableSwitch.getNumberOfTargets(this); i++) {
                e.addPossiblyDuplicateElement(LowTableSwitch.getTarget(this, i).target.getBasicBlock());
            }
            break;
        case LOOKUPSWITCH_opcode:
            e.addElement(LookupSwitch.getDefault(this).target.getBasicBlock());
            for (int i = 0; i < LookupSwitch.getNumberOfTargets(this); i++) {
                e.addPossiblyDuplicateElement(LookupSwitch.getTarget(this, i).target.getBasicBlock());
            }
            break;
        default:
            if (VM.BuildForIA32 && org.jikesrvm.compilers.opt.ir.ia32.MIR_Branch.conforms(this)) {
                e.addElement(org.jikesrvm.compilers.opt.ir.ia32.MIR_Branch.getTarget(this).target.getBasicBlock());
            } else if (VM.BuildForPowerPC && org.jikesrvm.compilers.opt.ir.ppc.MIR_Branch.conforms(this)) {
                e.addElement(org.jikesrvm.compilers.opt.ir.ppc.MIR_Branch.getTarget(this).target.getBasicBlock());
            } else if (VM.BuildForIA32 && org.jikesrvm.compilers.opt.ir.ia32.MIR_CondBranch.conforms(this)) {
                e.addElement(org.jikesrvm.compilers.opt.ir.ia32.MIR_CondBranch.getTarget(this).target.getBasicBlock());
            } else if (VM.BuildForPowerPC && org.jikesrvm.compilers.opt.ir.ppc.MIR_CondBranch.conforms(this)) {
                e.addElement(org.jikesrvm.compilers.opt.ir.ppc.MIR_CondBranch.getTarget(this).target.getBasicBlock());
            } else if (VM.BuildForIA32 && org.jikesrvm.compilers.opt.ir.ia32.MIR_CondBranch2.conforms(this)) {
                e.addElement(org.jikesrvm.compilers.opt.ir.ia32.MIR_CondBranch2.getTarget1(this).target.getBasicBlock());
                e.addPossiblyDuplicateElement(org.jikesrvm.compilers.opt.ir.ia32.MIR_CondBranch2.getTarget2(this).target.getBasicBlock());
            } else if (VM.BuildForPowerPC && org.jikesrvm.compilers.opt.ir.ppc.MIR_CondBranch2.conforms(this)) {
                e.addElement(org.jikesrvm.compilers.opt.ir.ppc.MIR_CondBranch2.getTarget1(this).target.getBasicBlock());
                e.addPossiblyDuplicateElement(org.jikesrvm.compilers.opt.ir.ppc.MIR_CondBranch2.getTarget2(this).target.getBasicBlock());
            } else if (VM.BuildForIA32 && org.jikesrvm.compilers.opt.ir.ia32.MIR_LowTableSwitch.conforms(this)) {
                for (int i = 0; i < org.jikesrvm.compilers.opt.ir.ia32.MIR_LowTableSwitch.getNumberOfTargets(this); i++) {
                    e.addPossiblyDuplicateElement(org.jikesrvm.compilers.opt.ir.ia32.MIR_LowTableSwitch.getTarget(this, i).target.getBasicBlock());
                }
            } else if ((VM.BuildForIA32 && org.jikesrvm.compilers.opt.ir.ia32.MIR_CondBranch2.conforms(this)) || (VM.BuildForPowerPC && org.jikesrvm.compilers.opt.ir.ppc.MIR_CondBranch2.conforms(this))) {
                throw new OptimizingCompilerException("getBranchTargets()", "operator not implemented", operator().toString());
            } else {
                throw new OptimizingCompilerException("getBranchTargets()", "operator not implemented", operator().toString());
            }
    }
    return e;
}
Also used : OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand)

Aggregations

BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)30 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)16 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)16 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)15 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)14 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)14 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)13 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)10 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)9 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)8 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)8 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)7 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)7 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)7 OptimizingCompilerException (org.jikesrvm.compilers.opt.OptimizingCompilerException)5 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)5 Operator (org.jikesrvm.compilers.opt.ir.Operator)4 OsrPoint (org.jikesrvm.compilers.opt.ir.OsrPoint)4 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)4 InlinedOsrTypeInfoOperand (org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand)4