Search in sources :

Example 46 with Register

use of org.jikesrvm.compilers.opt.ir.Register 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 47 with Register

use of org.jikesrvm.compilers.opt.ir.Register 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 48 with Register

use of org.jikesrvm.compilers.opt.ir.Register 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)

Example 49 with Register

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

the class CallingConvention method prologueExpand.

// ///////////////////
// Implementation
// ///////////////////
/**
 * Expand the prologue instruction to make calling convention explicit.
 */
private static void prologueExpand(IR ir) {
    // set up register lists for dead code elimination.
    boolean useDU = ir.options.getOptLevel() >= 1;
    if (useDU) {
        DefUse.computeDU(ir);
    }
    Instruction prologueInstr = ir.firstInstructionInCodeOrder().nextInstructionInCodeOrder();
    if (VM.VerifyAssertions)
        VM._assert(prologueInstr.operator() == IR_PROLOGUE);
    Instruction start = prologueInstr.nextInstructionInCodeOrder();
    int int_index = 0;
    int double_index = 0;
    int spilledArgumentCounter = (-256 - STACKFRAME_HEADER_SIZE) >> LOG_BYTES_IN_ADDRESS;
    GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
    Register FP = phys.getFP();
    for (Enumeration<Operand> symParams = prologueInstr.getDefs(); symParams.hasMoreElements(); ) {
        RegisterOperand symParamOp = (RegisterOperand) symParams.nextElement();
        Register symParam = symParamOp.getRegister();
        TypeReference t = symParamOp.getType();
        if (t.isFloatType()) {
            // Why? TODO: figure this out and remove the 'true' case below
            if (true || !useDU || symParam.useList != null) {
                if (double_index < NUMBER_DOUBLE_PARAM) {
                    Register param = phys.get(FIRST_DOUBLE_PARAM + (double_index));
                    start.insertBefore(MIR_Move.create(PPC_FMR, F(symParam), F(param)));
                } else {
                    // spilled parameter
                    start.insertBefore(MIR_Load.create(PPC_LFS, F(symParam), A(FP), IC((spilledArgumentCounter << LOG_BYTES_IN_ADDRESS) - BYTES_IN_ADDRESS + BYTES_IN_FLOAT)));
                    spilledArgumentCounter--;
                }
            }
            double_index++;
        } else if (t.isDoubleType()) {
            // Why? TODO: figure this out and remove the 'true' case below
            if (true || !useDU || symParam.useList != null) {
                if (double_index < NUMBER_DOUBLE_PARAM) {
                    Register param = phys.get(FIRST_DOUBLE_PARAM + (double_index));
                    start.insertBefore(MIR_Move.create(PPC_FMR, D(symParam), D(param)));
                } else {
                    // spilled parameter
                    start.insertBefore(MIR_Load.create(PPC_LFD, D(symParam), A(FP), IC(spilledArgumentCounter << LOG_BYTES_IN_ADDRESS)));
                    spilledArgumentCounter -= BYTES_IN_DOUBLE / BYTES_IN_ADDRESS;
                }
            }
            double_index++;
        } else {
            // Why? TODO: figure this out and remove the 'true' case below
            if (true || !useDU || symParam.useList != null) {
                if (int_index < NUMBER_INT_PARAM) {
                    Register param = phys.get(FIRST_INT_PARAM + (int_index));
                    start.insertBefore(MIR_Move.create(PPC_MOVE, new RegisterOperand(symParam, t), A(param)));
                } else {
                    // spilled parameter
                    if (VM.BuildFor64Addr && (t.isIntType() || t.isShortType() || t.isByteType() || t.isCharType() || t.isBooleanType())) {
                        start.insertBefore(MIR_Load.create(PPC_LInt, new RegisterOperand(symParam, t), A(FP), IC((spilledArgumentCounter << LOG_BYTES_IN_ADDRESS) - BYTES_IN_ADDRESS + BYTES_IN_INT)));
                    } else {
                        // same size as addr (ie, either we're in 32 bit mode or we're in 64 bit mode and it's a reference or long)
                        start.insertBefore(MIR_Load.create(PPC_LAddr, new RegisterOperand(symParam, t), A(FP), IC(spilledArgumentCounter << LOG_BYTES_IN_ADDRESS)));
                    }
                    spilledArgumentCounter--;
                }
            }
            int_index++;
        }
    }
    removeDefsFromPrologue(prologueInstr);
}
Also used : GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) TypeReference(org.jikesrvm.classloader.TypeReference) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 50 with Register

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

the class RegisterPreferences method initialize.

/**
 * Set up register preferences based on instructions in an IR.
 */
@Override
public void initialize(IR ir) {
    for (Enumeration<Instruction> e = ir.forwardInstrEnumerator(); e.hasMoreElements(); ) {
        Instruction s = e.nextElement();
        switch(s.getOpcode()) {
            case PPC_MOVE_opcode:
                // add affinities produced by MOVE instructions
                Operand result = MIR_Move.getResult(s);
                Operand value = MIR_Move.getValue(s);
                if (result.isRegister() && value.isRegister()) {
                    Register r1 = result.asRegister().getRegister();
                    Register r2 = value.asRegister().getRegister();
                    addAffinity(1, r2, r1);
                    // above.
                    if (SYMBOLIC_SYMBOLIC_HEURISTIC && r1.isSymbolic() && r2.isSymbolic()) {
                        addAffinity(1, r2, r1);
                    }
                }
                break;
            default:
                break;
        }
    }
}
Also used : Register(org.jikesrvm.compilers.opt.ir.Register) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Aggregations

Register (org.jikesrvm.compilers.opt.ir.Register)279 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)144 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)106 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)82 Test (org.junit.Test)52 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)50 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)45 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)43 GenericPhysicalRegisterSet (org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet)40 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)39 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)32 MemoryOperand (org.jikesrvm.compilers.opt.ir.operand.MemoryOperand)30 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)29 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)27 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)26 OsrPoint (org.jikesrvm.compilers.opt.ir.OsrPoint)25 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)24 IA32ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand)23 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)22 StackLocationOperand (org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)22