Search in sources :

Example 21 with StackLocationOperand

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

the class CallingConvention method expandParametersToCall.

/**
 * Explicitly copy parameters to a call into the appropriate physical
 * registers as defined by the calling convention.<p>
 *
 * Note: Assumes that ESP points to the word before the slot where the
 * first parameter should be stored.
 *
 * @param call the call instruction
 * @param ir the IR that contains the call
 * @return number of bytes necessary to hold the parameters
 */
private static int expandParametersToCall(Instruction call, IR ir) {
    int nGPRParams = 0;
    int nFPRParams = 0;
    PhysicalRegisterSet phys = (PhysicalRegisterSet) ir.regpool.getPhysicalRegisterSet();
    // count the number FPR parameters in a pre-pass
    int FPRRegisterParams = countFPRParams(call);
    FPRRegisterParams = Math.min(FPRRegisterParams, PhysicalRegisterSet.getNumberOfFPRParams());
    // offset, in bytes, from the SP, for the next parameter slot on the
    // stack
    int parameterBytes = 0;
    // Require ESP to be at bottom of frame before a call,
    call.insertBefore(MIR_UnaryNoRes.create(REQUIRE_ESP, IC(0)));
    // walk over each parameter
    // must count then before we start nulling them out!
    int numParams = MIR_Call.getNumberOfParams(call);
    int nParamsInRegisters = 0;
    for (int i = 0; i < numParams; i++) {
        Operand param = MIR_Call.getClearParam(call, i);
        MIR_Call.setParam(call, i, null);
        TypeReference paramType = param.getType();
        if (paramType.isFloatingPointType()) {
            nFPRParams++;
            int size;
            if (paramType.isFloatType()) {
                size = BYTES_IN_FLOAT;
                parameterBytes -= WORDSIZE;
            } else {
                size = BYTES_IN_DOUBLE;
                parameterBytes -= 2 * WORDSIZE;
            }
            if (nFPRParams > PhysicalRegisterSet.getNumberOfFPRParams()) {
                // pass the FP parameter on the stack
                Operand M = new StackLocationOperand(false, parameterBytes, size);
                if (SSE2_FULL) {
                    if (paramType.isFloatType()) {
                        call.insertBefore(MIR_Move.create(IA32_MOVSS, M, param));
                    } else {
                        call.insertBefore(MIR_Move.create(IA32_MOVSD, M, param));
                    }
                } else {
                    call.insertBefore(MIR_Move.create(IA32_FMOV, M, param));
                }
            } else {
                // Pass the parameter in a register.
                RegisterOperand real;
                if (SSE2_FULL) {
                    real = new RegisterOperand(phys.getFPRParam(nFPRParams - 1), paramType);
                    if (paramType.isFloatType()) {
                        call.insertBefore(MIR_Move.create(IA32_MOVSS, real, param));
                    } else {
                        call.insertBefore(MIR_Move.create(IA32_MOVSD, real, param));
                    }
                } else {
                    // Note that if k FPRs are passed in registers,
                    // the 1st goes in F(k-1),
                    // the 2nd goes in F(k-2), etc...
                    real = new RegisterOperand(phys.getFPRParam(FPRRegisterParams - nFPRParams), paramType);
                    call.insertBefore(MIR_Move.create(IA32_FMOV, real, param));
                }
                // Record that the call now has a use of the real register.
                MIR_Call.setParam(call, nParamsInRegisters++, real.copy());
            }
        } else {
            nGPRParams++;
            parameterBytes -= WORDSIZE;
            if (paramIsNativeLongOn64Bit(param)) {
                parameterBytes -= WORDSIZE;
            }
            if (nGPRParams > PhysicalRegisterSet.getNumberOfGPRParams()) {
                // parameter into the appropriate stack frame location.
                if (paramIsNativeLongOn64Bit(param)) {
                    call.insertBefore(MIR_UnaryNoRes.create(REQUIRE_ESP, IC(parameterBytes + WORDSIZE * 2)));
                    call.insertBefore(MIR_UnaryNoRes.create(IA32_PUSH, IC(0)));
                } else {
                    call.insertBefore(MIR_UnaryNoRes.create(REQUIRE_ESP, IC(parameterBytes + WORDSIZE)));
                }
                call.insertBefore(MIR_UnaryNoRes.create(IA32_PUSH, param));
            } else {
                // Pass the parameter in a register.
                Register phy = phys.getGPRParam(nGPRParams - 1);
                RegisterOperand real = new RegisterOperand(phy, paramType);
                call.insertBefore(MIR_Move.create(IA32_MOV, real, param));
                // Record that the call now has a use of the real register.
                MIR_Call.setParam(call, nParamsInRegisters++, real.copy());
            }
        }
    }
    return parameterBytes;
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) 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) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) PhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet) TypeReference(org.jikesrvm.classloader.TypeReference) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)

Example 22 with StackLocationOperand

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

the class CallingConvention method restoreNonvolatilesAfterSysCall.

/**
 * Restore all nonvolatile registers after a syscall.
 * We do this in case the sys call does not respect our
 * register conventions.<p>
 *
 * We save/restore all nonvolatiles and the PR, whether
 * or not this routine uses them.  This may be a tad inefficient, but if
 * you're making a system call, you probably don't care.
 *
 * @param call the sys call
 * @param ir the IR that contains the call
 */
static void restoreNonvolatilesAfterSysCall(Instruction call, IR ir) {
    GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
    StackManager sm = (StackManager) ir.stackManager;
    // get the offset into the stack frame of where to stash the first
    // nonvolatile for this case.
    int location = sm.getOffsetForSysCall();
    // restore each non-volatile
    for (Enumeration<Register> e = phys.enumerateNonvolatileGPRs(); e.hasMoreElements(); ) {
        Register r = e.nextElement();
        Operand M = new StackLocationOperand(true, -location, (byte) WORDSIZE);
        call.insertAfter(MIR_Move.create(IA32_MOV, new RegisterOperand(r, wordType), M));
        location += WORDSIZE;
    }
    // restore the thread register
    Operand M = new StackLocationOperand(true, -location, (byte) WORDSIZE);
    call.insertAfter(MIR_Move.create(IA32_MOV, ir.regpool.makeTROp(), M));
    // restore the JTOC, if applicable
    if (JTOC_REGISTER != null) {
        location += WORDSIZE;
        Operand jtocSave = new StackLocationOperand(true, -location, (byte) WORDSIZE);
        call.insertAfter(MIR_Move.create(IA32_MOV, ir.regpool.makeTocOp(), jtocSave));
    }
}
Also used : GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) 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) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)

Example 23 with StackLocationOperand

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

the class BURS_Helpers method SSE2_X87_REM.

/**
 * Performs a long -&gt; double/float conversion using x87 and
 * marshalls between to XMMs.
 *
 * @param s instruction to modify for the conversion
 */
protected final void SSE2_X87_REM(Instruction s) {
    Operand result = Binary.getClearResult(s);
    RegisterOperand st0 = new RegisterOperand(getST0(), result.getType());
    int offset = -burs.ir.stackManager.allocateSpaceForConversion();
    StackLocationOperand sl = new StackLocationOperand(true, offset, SSE2_SIZE(result));
    EMIT(CPOS(s, MIR_Move.create(SSE2_MOVE(result), sl, Binary.getClearVal2(s))));
    EMIT(CPOS(s, MIR_Move.create(IA32_FLD, st0, sl.copy())));
    EMIT(CPOS(s, MIR_Move.create(SSE2_MOVE(result), sl.copy(), Binary.getClearVal1(s))));
    EMIT(CPOS(s, MIR_Move.create(IA32_FLD, st0.copy(), sl.copy())));
    // The parameters to FPREM actually get ignored (implied ST0/ST1)
    EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_FPREM, st0.copy(), st0.copy())));
    EMIT(CPOS(s, MIR_Move.create(IA32_FSTP, sl.copy(), st0.copy())));
    EMIT(CPOS(s, MIR_Nullary.create(IA32_FFREE, st0.copy())));
    EMIT(MIR_Move.mutate(s, SSE2_MOVE(result), result, sl.copy()));
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IA32ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) InlinedOsrTypeInfoOperand(org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) BURSManagedFPROperand(org.jikesrvm.compilers.opt.ir.operand.ia32.BURSManagedFPROperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) OsrPoint(org.jikesrvm.compilers.opt.ir.OsrPoint) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)

Example 24 with StackLocationOperand

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

the class BURS_Helpers method GET_EXCEPTION_OBJECT.

/*
   * IA32-specific emit rules that are complex enough that we didn't want to
   * write them in the LIR2MIR.rules file. However, all expansions in this file
   * are called during BURS and thus are constrained to generate nonbranching
   * code (ie they can't create new basic blocks and/or do branching).
   */
/**
 * Emit code to get a caught exception object into a register
 *
 * @param s the instruction to expand
 */
protected final void GET_EXCEPTION_OBJECT(Instruction s) {
    int offset = -burs.ir.stackManager.allocateSpaceForCaughtException();
    StackLocationOperand sl = new StackLocationOperand(true, offset, DW);
    EMIT(MIR_Move.mutate(s, IA32_MOV, Nullary.getResult(s), sl));
}
Also used : OsrPoint(org.jikesrvm.compilers.opt.ir.OsrPoint) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)

Example 25 with StackLocationOperand

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

the class BURS_Helpers method GPR2FPR_64.

/**
 * Emits code to move 64 bits from GPRs to FPRs.
 *
 * @param s instruction to modify for the move
 */
protected final void GPR2FPR_64(Instruction s) {
    int offset = -burs.ir.stackManager.allocateSpaceForConversion();
    StackLocationOperand sl = new StackLocationOperand(true, offset, QW);
    StackLocationOperand sl1 = new StackLocationOperand(true, offset + 4, DW);
    StackLocationOperand sl2 = new StackLocationOperand(true, offset, DW);
    Operand i1, i2;
    Operand val = Unary.getClearVal(s);
    if (val instanceof RegisterOperand) {
        RegisterOperand rval = (RegisterOperand) val;
        i1 = val;
        i2 = new RegisterOperand(regpool.getSecondReg(rval.getRegister()), TypeReference.Int);
    } else {
        LongConstantOperand rhs = (LongConstantOperand) val;
        i1 = IC(rhs.upper32());
        i2 = IC(rhs.lower32());
    }
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, sl1, i1)));
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, sl2, i2)));
    EMIT(MIR_Move.mutate(s, IA32_FMOV, Unary.getResult(s), sl));
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IA32ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) InlinedOsrTypeInfoOperand(org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) BURSManagedFPROperand(org.jikesrvm.compilers.opt.ir.operand.ia32.BURSManagedFPROperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) OsrPoint(org.jikesrvm.compilers.opt.ir.OsrPoint) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)

Aggregations

StackLocationOperand (org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)28 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)26 MemoryOperand (org.jikesrvm.compilers.opt.ir.operand.MemoryOperand)22 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)20 IA32ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand)20 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)15 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)13 GenericPhysicalRegisterSet (org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet)12 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)11 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)11 Register (org.jikesrvm.compilers.opt.ir.Register)10 OsrPoint (org.jikesrvm.compilers.opt.ir.OsrPoint)9 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)8 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)7 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)6 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)6 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)6 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)6 DoubleConstantOperand (org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand)6 FloatConstantOperand (org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand)6