Search in sources :

Example 6 with MemoryOperand

use of org.jikesrvm.compilers.opt.ir.operand.MemoryOperand 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);
        restoreFloatingPointState(ret);
    }
    restoreNonVolatiles(ret);
    // 2. Restore caller's stackpointer and framepointer
    int frameSize = getFrameFixedSize();
    ret.insertBefore(MIR_UnaryNoRes.create(REQUIRE_ESP, IC(frameSize)));
    MemoryOperand fpHome = MemoryOperand.BD(ir.regpool.makeTROp(), ArchEntrypoints.framePointerField.getOffset(), (byte) WORDSIZE, null, null);
    ret.insertBefore(MIR_Nullary.create(IA32_POP, fpHome));
}
Also used : MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand)

Example 7 with MemoryOperand

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

the class StackManager method isScratchFreeMove.

/**
 * @param s the instruction to check
 * @return {@code true} if and only if the instruction is a MOVE instruction
 *  that can be generated without resorting to scratch registers
 */
private boolean isScratchFreeMove(Instruction s) {
    if (s.operator() != IA32_MOV)
        return false;
    // registers in these move instructions.
    if (!FLOAT_ESP)
        return false;
    Operand result = MIR_Move.getResult(s);
    Operand value = MIR_Move.getValue(s);
    // memory operands.
    if (result.isMemory()) {
        MemoryOperand M = result.asMemory();
        if (hasSymbolicRegister(M))
            return false;
        // disable these too.  What's left?  WORDSIZE only.
        if (M.size != WORDSIZE)
            return false;
    }
    if (value.isMemory()) {
        MemoryOperand M = value.asMemory();
        if (hasSymbolicRegister(M))
            return false;
        // disable these too.  What's left?  WORDSIZE only.
        if (M.size != WORDSIZE)
            return false;
    }
    // If we get here, all is kosher.
    return true;
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) IA32ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand)

Example 8 with MemoryOperand

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

the class StackManager method moveESPBefore.

/**
 * Before instruction s, insert code to adjust ESP so that it lies at a
 * particular offset from its usual location.
 *
 * @param s the instruction before which ESP must have the desired offset
 * @param desiredOffset the desired offset
 */
private void moveESPBefore(Instruction s, int desiredOffset) {
    PhysicalRegisterSet phys = (PhysicalRegisterSet) ir.regpool.getPhysicalRegisterSet();
    Register ESP = phys.getESP();
    int delta = desiredOffset - ESPOffset;
    if (delta != 0) {
        if (canModifyEFLAGS(s)) {
            s.insertBefore(MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(ESP, PRIMITIVE_TYPE_FOR_WORD), VM.BuildFor32Addr ? IC(delta) : LC(delta)));
        } else {
            MemoryOperand M = MemoryOperand.BD(new RegisterOperand(ESP, PRIMITIVE_TYPE_FOR_WORD), Offset.fromIntSignExtend(delta), (byte) WORDSIZE, null, null);
            s.insertBefore(MIR_Lea.create(IA32_LEA, new RegisterOperand(ESP, PRIMITIVE_TYPE_FOR_WORD), M));
        }
        ESPOffset = desiredOffset;
    }
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) PhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet)

Example 9 with MemoryOperand

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

the class StackManager method insertNormalStackOverflowCheck.

/**
 * Insert an explicit stack overflow check in the prologue <em>after</em>
 * buying the stack frame.<p>
 *
 * SIDE EFFECT: mutates the plg into a trap instruction.  We need to
 * mutate so that the trap instruction is in the GC map data structures.
 *
 * @param plg the prologue instruction
 */
private void insertNormalStackOverflowCheck(Instruction plg) {
    if (!ir.method.isInterruptible()) {
        plg.remove();
        return;
    }
    if (ir.compiledMethod.isSaveVolatile()) {
        return;
    }
    PhysicalRegisterSet phys = (PhysicalRegisterSet) ir.regpool.getPhysicalRegisterSet();
    Register ESP = phys.getESP();
    MemoryOperand M = MemoryOperand.BD(ir.regpool.makeTROp(), Entrypoints.stackLimitField.getOffset(), (byte) WORDSIZE, null, null);
    // Trap if ESP <= active Thread Stack Limit
    MIR_TrapIf.mutate(plg, IA32_TRAPIF, null, new RegisterOperand(ESP, PRIMITIVE_TYPE_FOR_WORD), M, IA32ConditionOperand.LE(), TrapCodeOperand.StackOverflow());
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) PhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet)

Example 10 with MemoryOperand

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

the class StackManager method rewriteStackLocations.

/**
 * Walks through the IR.  For each StackLocationOperand, replace the
 * operand with the appropriate MemoryOperand.
 */
private void rewriteStackLocations() {
    // ESP is initially WORDSIZE above where the framepointer is going to be.
    ESPOffset = getFrameFixedSize() + WORDSIZE;
    Register ESP = ((PhysicalRegisterSet) ir.regpool.getPhysicalRegisterSet()).getESP();
    boolean seenReturn = false;
    for (Enumeration<Instruction> e = ir.forwardInstrEnumerator(); e.hasMoreElements(); ) {
        Instruction s = e.nextElement();
        if (s.isReturn()) {
            seenReturn = true;
            continue;
        }
        if (s.isBranch()) {
            // restore ESP to home location at end of basic block.
            moveESPBefore(s, 0);
            continue;
        }
        if (s.operator() == BBEND) {
            if (seenReturn) {
                // at a return ESP will be at FrameFixedSize,
                seenReturn = false;
                ESPOffset = 0;
            } else {
                moveESPBefore(s, 0);
            }
            continue;
        }
        if (s.operator() == ADVISE_ESP) {
            ESPOffset = MIR_UnaryNoRes.getVal(s).asIntConstant().value;
            continue;
        }
        if (s.operator() == REQUIRE_ESP) {
            // ESP is required to be at the given offset from the bottom of the frame
            moveESPBefore(s, MIR_UnaryNoRes.getVal(s).asIntConstant().value);
            continue;
        }
        if (s.operator() == YIELDPOINT_PROLOGUE || s.operator() == YIELDPOINT_BACKEDGE || s.operator() == YIELDPOINT_EPILOGUE) {
            moveESPBefore(s, 0);
            continue;
        }
        if (s.operator() == IA32_MOV) {
            rewriteMoveInstruction(s);
        }
        // stacklocation and memory operands.
        if (s.operator() == IA32_POP) {
            ESPOffset += WORDSIZE;
        }
        for (Enumeration<Operand> ops = s.getOperands(); ops.hasMoreElements(); ) {
            Operand op = ops.nextElement();
            if (op instanceof StackLocationOperand) {
                StackLocationOperand sop = (StackLocationOperand) op;
                int offset = sop.getOffset();
                if (sop.isFromTop()) {
                    offset = FPOffset2SPOffset(offset);
                }
                offset -= ESPOffset;
                byte size = sop.getSize();
                MemoryOperand M = MemoryOperand.BD(new RegisterOperand(ESP, PRIMITIVE_TYPE_FOR_WORD), Offset.fromIntSignExtend(offset), size, null, null);
                s.replaceOperand(op, M);
            } else if (op instanceof MemoryOperand) {
                MemoryOperand M = op.asMemory();
                if ((M.base != null && M.base.getRegister() == ESP) || (M.index != null && M.index.getRegister() == ESP)) {
                    M.disp = M.disp.minus(ESPOffset);
                }
            }
        }
        // stacklocation and memory operands.
        if (s.operator() == IA32_PUSH) {
            ESPOffset -= WORDSIZE;
        }
    }
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) IA32ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) PhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)

Aggregations

MemoryOperand (org.jikesrvm.compilers.opt.ir.operand.MemoryOperand)32 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)24 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)13 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)13 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)11 Register (org.jikesrvm.compilers.opt.ir.Register)10 StackLocationOperand (org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)9 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)9 IA32ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand)9 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)8 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)8 PhysicalRegisterSet (org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet)7 GenericPhysicalRegisterSet (org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet)6 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)6 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)5 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)4 DoubleConstantOperand (org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand)3 FloatConstantOperand (org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand)3 BURSManagedFPROperand (org.jikesrvm.compilers.opt.ir.operand.ia32.BURSManagedFPROperand)3 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)2