Search in sources :

Example 6 with PhysicalRegisterSet

use of org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet in project JikesRVM by JikesRVM.

the class StackManager method saveVolatiles.

/**
 * Insert code in the prologue to save the
 * volatile registers.
 *
 * @param inst
 */
private void saveVolatiles(Instruction inst) {
    PhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet().asPPC();
    // 1. save the volatile GPRs
    Register FP = phys.getFP();
    int i = 0;
    for (Enumeration<Register> e = phys.enumerateVolatileGPRs(); e.hasMoreElements(); i++) {
        Register r = e.nextElement();
        int location = saveVolatileGPRLocation[i];
        inst.insertBefore(MIR_Store.create(PPC_STAddr, A(r), A(FP), IC(location)));
    }
    // 2. save the volatile FPRs
    i = 0;
    for (Enumeration<Register> e = phys.enumerateVolatileFPRs(); e.hasMoreElements(); i++) {
        Register r = e.nextElement();
        int location = saveVolatileFPRLocation[i];
        inst.insertBefore(MIR_Store.create(PPC_STFD, D(r), A(FP), IC(location)));
    }
    // 3. Save some special registers
    Register temp = phys.getTemp();
    inst.insertBefore(MIR_Move.create(PPC_MFSPR, I(temp), I(phys.getXER())));
    inst.insertBefore(MIR_Store.create(PPC_STW, I(temp), A(FP), IC(saveXERLocation)));
    inst.insertBefore(MIR_Move.create(PPC_MFSPR, A(temp), A(phys.getCTR())));
    inst.insertBefore(MIR_Store.create(PPC_STAddr, A(temp), A(FP), IC(saveCTRLocation)));
}
Also used : Register(org.jikesrvm.compilers.opt.ir.Register) PhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet) GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet)

Example 7 with PhysicalRegisterSet

use of org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet in project JikesRVM by JikesRVM.

the class StackManager method restoreVolatileRegisters.

/**
 * Insert code before a return instruction to restore the
 * volatile registers.
 *
 * @param inst the return instruction
 */
private void restoreVolatileRegisters(Instruction inst) {
    PhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet().asPPC();
    // 1. restore the volatile GPRs
    Register FP = phys.getFP();
    int i = 0;
    for (Enumeration<Register> e = phys.enumerateVolatileGPRs(); e.hasMoreElements(); i++) {
        Register r = e.nextElement();
        int location = saveVolatileGPRLocation[i];
        inst.insertBefore(MIR_Load.create(PPC_LAddr, A(r), A(FP), IC(location)));
    }
    // 2. restore the volatile FPRs
    i = 0;
    for (Enumeration<Register> e = phys.enumerateVolatileFPRs(); e.hasMoreElements(); i++) {
        Register r = e.nextElement();
        int location = saveVolatileFPRLocation[i];
        inst.insertBefore(MIR_Load.create(PPC_LFD, D(r), A(FP), IC(location)));
    }
    // 3. Restore some special registers
    Register temp = phys.getTemp();
    inst.insertBefore(MIR_Load.create(PPC_LInt, I(temp), A(FP), IC(saveXERLocation)));
    inst.insertBefore(MIR_Move.create(PPC_MTSPR, I(phys.getXER()), I(temp)));
    inst.insertBefore(MIR_Load.create(PPC_LAddr, A(temp), A(FP), IC(saveCTRLocation)));
    inst.insertBefore(MIR_Move.create(PPC_MTSPR, A(phys.getCTR()), A(temp)));
}
Also used : Register(org.jikesrvm.compilers.opt.ir.Register) PhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet) GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet)

Example 8 with PhysicalRegisterSet

use of org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet in project JikesRVM by JikesRVM.

the class StackManager method insertNormalPrologue.

/*
  * Insert the prologue.
  * The available scratch registers are normally: R0, S0, S1
  * However, if this is the prologue for a 'save volatile' frame,
  * then R0 is the only available scratch register.
  * The "normal" prologue must perform the following tasks:
  *    stack overflow check
  *    set TSR for the yieldpoint if there is a prologue yieldpoint instruction
  *    save lr
  *    store cmid
  *    buy stack frame
  *    store any used non volatiles
  * We schedule the prologue for this combination of operations,
  * since it is currently the common case.
  * When this changes, this code should be modifed accordingly.
  * The desired sequence is:
  *  1    mflr    00  # return addr
  *  2    l       S1 takeYieldpointOffset(PR)                # setting TSR for yield point
  *  3    stu     FP -frameSize(FP)                          # buy frame, save caller's fp
  *  4    l       S0 stackLimitOffset(S0)                    # stack overflow check
  *  5    <save used non volatiles>
  *  6    cmpi    TSR S1 0x0                                 # setting TSR for yield point (S1 is now free)
  *  7    lil     S1 CMID                                    # cmid
  *  8    st      00 STACKFRAME_RETURN_ADDRESS_OFFSET(FP)  # return addr (00 is now free)
  *  9    st      S1 STACKFRAME_METHOD_ID_OFFSET(FP)         # cmid
  *  10   tgt     S0, FP                                     # stack overflow check (already bought frame)
  */
/**
 * Schedule prologue for 'normal' case (see above)
 */
@Override
public void insertNormalPrologue() {
    PhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet().asPPC();
    Register FP = phys.getFP();
    Register TR = phys.getTR();
    Register TSR = phys.getTSR();
    Register R0 = phys.getTemp();
    Register S0 = phys.getGPR(FIRST_SCRATCH_GPR);
    Register S1 = phys.getGPR(LAST_SCRATCH_GPR);
    boolean interruptible = ir.method.isInterruptible();
    boolean stackOverflow = interruptible;
    boolean yp = hasPrologueYieldpoint();
    int frameFixedSize = getFrameFixedSize();
    ir.compiledMethod.setFrameFixedSize(frameFixedSize);
    if (frameFixedSize >= STACK_SIZE_GUARD || ir.compiledMethod.isSaveVolatile()) {
        insertExceptionalPrologue();
        return;
    }
    Instruction ptr = ir.firstInstructionInCodeOrder().nextInstructionInCodeOrder();
    if (VM.VerifyAssertions)
        VM._assert(ptr.getOpcode() == IR_PROLOGUE_opcode);
    // 1
    ptr.insertBefore(MIR_Move.create(PPC_MFSPR, A(R0), A(phys.getLR())));
    if (yp) {
        Offset offset = Entrypoints.takeYieldpointField.getOffset();
        if (VM.VerifyAssertions)
            VM._assert(fits(offset, 16));
        // 2
        ptr.insertBefore(MIR_Load.create(PPC_LInt, I(S1), A(TR), IC(PPCMaskLower16(offset))));
    }
    // 3
    ptr.insertBefore(MIR_StoreUpdate.create(PPC_STAddrU, A(FP), A(FP), IC(-frameSize)));
    if (stackOverflow) {
        Offset offset = Entrypoints.stackLimitField.getOffset();
        if (VM.VerifyAssertions)
            VM._assert(fits(offset, 16));
        // 4
        ptr.insertBefore(MIR_Load.create(PPC_LAddr, A(S0), A(phys.getTR()), IC(PPCMaskLower16(offset))));
    }
    // Now add any instructions to save the volatiles and nonvolatiles (5)
    saveNonVolatiles(ptr);
    if (yp) {
        // 6
        ptr.insertBefore(MIR_Binary.create(PPC_CMPI, I(TSR), I(S1), IC(0)));
    }
    int cmid = ir.compiledMethod.getId();
    if (cmid <= 0x7fff) {
        // 7
        ptr.insertBefore(MIR_Unary.create(PPC_LDI, I(S1), IC(cmid)));
    } else {
        // 7 (a)
        ptr.insertBefore(MIR_Unary.create(PPC_LDIS, I(S1), IC(cmid >>> 16)));
        // 7 (b)
        ptr.insertBefore(MIR_Binary.create(PPC_ORI, I(S1), I(S1), IC(cmid & 0xffff)));
    }
    ptr.insertBefore(MIR_Store.create(PPC_STAddr, A(R0), A(FP), // 8
    IC(frameSize + STACKFRAME_RETURN_ADDRESS_OFFSET.toInt())));
    // 9
    ptr.insertBefore(MIR_Store.create(PPC_STW, I(S1), A(FP), IC(STACKFRAME_METHOD_ID_OFFSET.toInt())));
    if (stackOverflow) {
        // Mutate the Prologue instruction into the trap
        MIR_Trap.mutate(ptr, PPC_TAddr, PowerPCTrapOperand.GREATER(), A(S0), A(FP), // 10
        TrapCodeOperand.StackOverflow());
    } else {
        // no stack overflow test, so we remove the IR_Prologue instruction
        ptr.remove();
    }
}
Also used : Register(org.jikesrvm.compilers.opt.ir.Register) PhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet) GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) Offset(org.vmmagic.unboxed.Offset)

Example 9 with PhysicalRegisterSet

use of org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet in project JikesRVM by JikesRVM.

the class StackManager method insertUnspillBefore.

/**
 * Insert a load of a physical register from a spill location before
 * instruction s.
 *
 * @param s the instruction before which the spill should occur
 * @param r the register (should be physical) to spill
 * @param type one of INT_VALUE, FLOAT_VALUE, DOUBLE_VALUE, or
 *                    CONDITION_VALUE
 * @param location the spill location
 */
@Override
public void insertUnspillBefore(Instruction s, Register r, Register type, int location) {
    PhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet().asPPC();
    Register FP = phys.getFP();
    if (type.isCondition()) {
        Register temp = phys.getTemp();
        s.insertBefore(MIR_Load.create(PPC_LWZ, I(temp), A(FP), IC(location + BYTES_IN_ADDRESS - BYTES_IN_INT)));
    } else if (type.isDouble()) {
        s.insertBefore(MIR_Load.create(PPC_LFD, D(r), A(FP), IC(location)));
    } else if (type.isFloat()) {
        s.insertBefore(MIR_Load.create(PPC_LFS, F(r), A(FP), IC(location + BYTES_IN_ADDRESS - BYTES_IN_FLOAT)));
    } else if (type.isNatural()) {
        // integer or half of long
        s.insertBefore(MIR_Load.create(PPC_LAddr, A(r), A(FP), IC(location)));
    } else {
        throw new OptimizingCompilerException("insertUnspillBefore", "unknown type:" + type);
    }
}
Also used : Register(org.jikesrvm.compilers.opt.ir.Register) PhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet) GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException)

Example 10 with PhysicalRegisterSet

use of org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet in project JikesRVM by JikesRVM.

the class StackManager method insertEpilogue.

/**
 * Insert the epilogue before a particular return instruction.
 *
 * @param ret the return instruction.
 */
private void insertEpilogue(Instruction ret) {
    // 1. Restore any saved registers
    if (ir.compiledMethod.isSaveVolatile()) {
        restoreVolatileRegisters(ret);
    }
    restoreNonVolatiles(ret);
    // 2. Restore return address
    PhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet().asPPC();
    Register temp = phys.getTemp();
    Register FP = phys.getFP();
    ret.insertBefore(MIR_Load.create(PPC_LAddr, A(temp), A(FP), IC(STACKFRAME_RETURN_ADDRESS_OFFSET.toInt() + frameSize)));
    // 3. Load return address into LR
    ret.insertBefore(MIR_Move.create(PPC_MTSPR, A(phys.getLR()), A(phys.getTemp())));
    // 4. Restore old FP
    ret.insertBefore(MIR_Binary.create(PPC_ADDI, A(FP), A(FP), IC(frameSize)));
}
Also used : Register(org.jikesrvm.compilers.opt.ir.Register) PhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet) GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet)

Aggregations

PhysicalRegisterSet (org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet)13 GenericPhysicalRegisterSet (org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet)9 Register (org.jikesrvm.compilers.opt.ir.Register)9 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)5 OptimizingCompilerException (org.jikesrvm.compilers.opt.OptimizingCompilerException)4 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)4 Offset (org.vmmagic.unboxed.Offset)4 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)3 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)2 MachineCodeOffsets (org.jikesrvm.compilers.opt.mir2mc.MachineCodeOffsets)2 InterfaceMethodSignature (org.jikesrvm.classloader.InterfaceMethodSignature)1 RVMMethod (org.jikesrvm.classloader.RVMMethod)1 CodeArray (org.jikesrvm.compilers.common.CodeArray)1 Lister (org.jikesrvm.compilers.common.assembler.ppc.Lister)1 OperationNotImplementedException (org.jikesrvm.compilers.opt.OperationNotImplementedException)1 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)1 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)1 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)1 DoubleConstantOperand (org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand)1 FloatConstantOperand (org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand)1