Search in sources :

Example 16 with MemoryOperand

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

the class BURS_MemOp_Helpers method MO_MC.

protected final MemoryOperand MO_MC(Instruction s) {
    // JTOC
    Operand base = Binary.getVal1(s);
    // float or double value
    Operand val = Binary.getVal2(s);
    if (val instanceof FloatConstantOperand) {
        FloatConstantOperand fc = (FloatConstantOperand) val;
        Offset offset = fc.offset;
        LocationOperand loc = new LocationOperand(offset);
        if (base instanceof IntConstantOperand) {
            return MO_D(offset.plus(IV(base)), DW, loc, TG());
        } else if (VM.BuildFor64Addr && base instanceof LongConstantOperand) {
            return MO_D(offset.plus(Offset.fromLong(LV(base))), DW, loc, TG());
        } else {
            return MO_BD(base, offset, DW, loc, TG());
        }
    } else {
        DoubleConstantOperand dc = (DoubleConstantOperand) val;
        Offset offset = dc.offset;
        LocationOperand loc = new LocationOperand(offset);
        if (base instanceof IntConstantOperand) {
            return MO_D(offset.plus(IV(base)), QW, loc, TG());
        } else if (VM.BuildFor64Addr && base instanceof LongConstantOperand) {
            return MO_D(offset.plus(Offset.fromLong(LV(base))), QW, loc, TG());
        } else {
            return MO_BD(Binary.getVal1(s), dc.offset, QW, loc, TG());
        }
    }
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) Offset(org.vmmagic.unboxed.Offset)

Example 17 with MemoryOperand

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

the class RewriteMemoryOperandsWithOversizedDisplacements method disp64MemOperandConversion.

private static void disp64MemOperandConversion(IR ir, Instruction inst, MemoryOperand mo) {
    if (!mo.disp.isZero() && !Bits.fits(mo.disp, 32)) {
        RegisterOperand effectiveAddress = ir.regpool.makeTempLong();
        RegisterOperand temp = null;
        inst.insertBefore(MIR_Move.create(IMMQ_MOV, effectiveAddress, LC(mo.disp.toLong())));
        if (mo.index != null) {
            if (mo.scale != 0) {
                temp = ir.regpool.makeTempLong();
                TypeReference indexType = mo.index.getType();
                if (indexType.isLongType() || indexType.isWordLikeType()) {
                    inst.insertBefore(MIR_Move.create(IA32_MOV, temp, mo.index.copy()));
                } else if (indexType.isIntType()) {
                    inst.insertBefore(MIR_Unary.create(IA32_MOVSXDQ, temp, mo.index.copy()));
                } else if (indexType.isByteType()) {
                    inst.insertBefore(MIR_Unary.create(IA32_MOVSXQ__B, temp, mo.index.copy()));
                } else if (indexType.isShortType() || indexType.isCharType()) {
                    inst.insertBefore(MIR_Unary.create(IA32_MOVSXQ__W, temp, mo.index.copy()));
                } else {
                    String msg = "Unhandled type: " + indexType;
                    if (VM.VerifyAssertions)
                        VM._assert(VM.NOT_REACHED, msg);
                }
                inst.insertBefore(MIR_BinaryAcc.create(IA32_SHL, temp.copy(), IC(mo.scale)));
                inst.insertBefore(MIR_BinaryAcc.create(IA32_ADD, effectiveAddress.copy(), temp.copy()));
            } else {
                TypeReference indexType = mo.index.getType();
                if (indexType.isLongType() || indexType.isWordLikeType()) {
                    inst.insertBefore(MIR_BinaryAcc.create(IA32_ADD, effectiveAddress.copy(), mo.index.copy()));
                } else {
                    temp = ir.regpool.makeTempLong();
                    if (indexType.isIntType()) {
                        inst.insertBefore(MIR_Unary.create(IA32_MOVSXDQ, temp, mo.index.copy()));
                    } else if (indexType.isByteType()) {
                        inst.insertBefore(MIR_Unary.create(IA32_MOVSXQ__B, temp, mo.index.copy()));
                    } else if (indexType.isShortType() || indexType.isCharType()) {
                        inst.insertBefore(MIR_Unary.create(IA32_MOVSXQ__W, temp, mo.index.copy()));
                    } else {
                        String msg = "Unhandled type: " + indexType;
                        if (VM.VerifyAssertions)
                            VM._assert(VM.NOT_REACHED, msg);
                    }
                    inst.insertBefore(MIR_BinaryAcc.create(IA32_ADD, effectiveAddress.copy(), temp.copy()));
                }
            }
        }
        if (mo.base != null) {
            inst.insertBefore(MIR_BinaryAcc.create(IA32_ADD, effectiveAddress.copy(), mo.base.copy()));
        }
        MemoryOperand newMo = MemoryOperand.I(effectiveAddress.copy().asRegister(), mo.size, null != mo.loc ? (LocationOperand) mo.loc.copy() : null, mo.guard != null ? mo.guard.copy() : null);
        inst.replaceOperand(mo, newMo);
    }
}
Also used : LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) TypeReference(org.jikesrvm.classloader.TypeReference)

Example 18 with MemoryOperand

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

the class StackManager method insertNormalPrologue.

/**
 * Insert the prologue for a normal method.
 *
 * Assume we are inserting the prologue for method B called from method
 * A.
 *    <ul>
 *    <li> Perform a stack overflow check.
 *    <li> Store a back pointer to A's frame
 *    <li> Store B's compiled method id
 *    <li> Adjust frame pointer to point to B's frame
 *    <li> Save any used non-volatile registers
 *    </ul>
 */
@Override
public void insertNormalPrologue() {
    PhysicalRegisterSet phys = (PhysicalRegisterSet) ir.regpool.getPhysicalRegisterSet();
    Register ESP = phys.getESP();
    MemoryOperand fpHome = MemoryOperand.BD(ir.regpool.makeTROp(), ArchEntrypoints.framePointerField.getOffset(), (byte) WORDSIZE, null, null);
    // the prologue instruction
    Instruction plg = ir.firstInstructionInCodeOrder().nextInstructionInCodeOrder();
    // inst is the instruction immediately after the IR_PROLOGUE
    // instruction
    Instruction inst = plg.nextInstructionInCodeOrder();
    int frameFixedSize = getFrameFixedSize();
    ir.compiledMethod.setFrameFixedSize(frameFixedSize);
    // See sysSignal_ia32.c
    if (frameFixedSize >= BIG_FRAME_MINIMUM_SIZE) {
        // 1. Insert Stack overflow check.
        insertBigFrameStackOverflowCheck(plg);
        // 2. Save caller's frame pointer
        inst.insertBefore(MIR_UnaryNoRes.create(IA32_PUSH, fpHome));
        // 3. Set my frame pointer to current value of stackpointer
        inst.insertBefore(MIR_Move.create(IA32_MOV, fpHome.copy(), new RegisterOperand(ESP, PRIMITIVE_TYPE_FOR_WORD)));
        // 4. Store my compiled method id
        int cmid = ir.compiledMethod.getId();
        inst.insertBefore(MIR_UnaryNoRes.create(IA32_PUSH, VM.BuildFor32Addr ? IC(cmid) : LC(cmid)));
    } else {
        // 1. Save caller's frame pointer
        inst.insertBefore(MIR_UnaryNoRes.create(IA32_PUSH, fpHome));
        // 2. Set my frame pointer to current value of stackpointer
        inst.insertBefore(MIR_Move.create(IA32_MOV, fpHome.copy(), new RegisterOperand(ESP, PRIMITIVE_TYPE_FOR_WORD)));
        // 3. Store my compiled method id
        int cmid = ir.compiledMethod.getId();
        inst.insertBefore(MIR_UnaryNoRes.create(IA32_PUSH, VM.BuildFor32Addr ? IC(cmid) : LC(cmid)));
        // 4. Insert Stack overflow check.
        insertNormalStackOverflowCheck(plg);
    }
    // II. Save any used volatile and non-volatile registers
    if (ir.compiledMethod.isSaveVolatile()) {
        saveVolatiles(inst);
        saveFloatingPointState(inst);
    }
    saveNonVolatiles(inst);
}
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) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 19 with MemoryOperand

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

the class StackManager method insertBigFrameStackOverflowCheck.

/**
 * Insert an explicit stack overflow check in the prologue <em>before</em>
 * buying the stack frame.
 * 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 insertBigFrameStackOverflowCheck(Instruction plg) {
    if (!ir.method.isInterruptible()) {
        plg.remove();
        return;
    }
    if (ir.compiledMethod.isSaveVolatile()) {
        return;
    }
    PhysicalRegisterSet phys = (PhysicalRegisterSet) ir.regpool.getPhysicalRegisterSet();
    Register ESP = phys.getESP();
    Register ECX = phys.getECX();
    // ECX := active Thread Stack Limit
    MemoryOperand M = MemoryOperand.BD(ir.regpool.makeTROp(), Entrypoints.stackLimitField.getOffset(), (byte) WORDSIZE, null, null);
    plg.insertBefore(MIR_Move.create(IA32_MOV, new RegisterOperand((ECX), PRIMITIVE_TYPE_FOR_WORD), M));
    // ECX += frame Size
    int frameSize = getFrameFixedSize();
    plg.insertBefore(MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(ECX, PRIMITIVE_TYPE_FOR_WORD), VM.BuildFor32Addr ? IC(frameSize) : LC(frameSize)));
    // Trap if ESP <= ECX
    MIR_TrapIf.mutate(plg, IA32_TRAPIF, null, new RegisterOperand(ESP, PRIMITIVE_TYPE_FOR_WORD), new RegisterOperand(ECX, PRIMITIVE_TYPE_FOR_WORD), 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 20 with MemoryOperand

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

the class StackManager method rewriteMoveInstruction.

/**
 * Rewrites a move instruction if it has 2 memory operands.
 * One of the 2 memory operands must be a stack location operand.  Move
 * the SP to the appropriate location and use a push or pop instruction.
 *
 * @param s the instruction to rewrite
 */
private void rewriteMoveInstruction(Instruction s) {
    // first attempt to mutate the move into a noop
    if (mutateMoveToNop(s))
        return;
    Operand result = MIR_Move.getResult(s);
    Operand val = MIR_Move.getValue(s);
    if (result instanceof StackLocationOperand) {
        if (val instanceof MemoryOperand || val instanceof StackLocationOperand) {
            int offset = ((StackLocationOperand) result).getOffset();
            byte size = ((StackLocationOperand) result).getSize();
            offset = FPOffset2SPOffset(offset) + size;
            moveESPBefore(s, offset);
            MIR_UnaryNoRes.mutate(s, IA32_PUSH, val);
        }
    } else {
        if (result instanceof MemoryOperand) {
            if (val instanceof StackLocationOperand) {
                int offset = ((StackLocationOperand) val).getOffset();
                offset = FPOffset2SPOffset(offset);
                moveESPBefore(s, offset);
                MIR_Nullary.mutate(s, IA32_POP, result);
            }
        }
    }
}
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) 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