Search in sources :

Example 1 with GPR

use of org.jikesrvm.ia32.RegisterConstants.GPR in project JikesRVM by JikesRVM.

the class AssemblerBase method doLOWTABLESWITCH.

/**
 * Emit the given instruction, assuming that
 * it is a MIR_LowTableSwitch instruction
 * and has a MIR_LOWTABLESWITCH operator
 *
 * @param inst the instruction to assemble
 */
protected void doLOWTABLESWITCH(Instruction inst) {
    // n = number of normal cases (0..n-1)
    int n = MIR_LowTableSwitch.getNumberOfTargets(inst);
    GPR ms = GPR.lookup(MIR_LowTableSwitch.getMethodStart(inst).getRegister().number);
    GPR idx = GPR.lookup(MIR_LowTableSwitch.getIndex(inst).getRegister().number);
    emitTableswitchCode(ms, idx);
    // loaded for the cases
    for (int i = 0; i < n; i++) {
        Operand target = MIR_LowTableSwitch.getTarget(inst, i);
        emitOFFSET_Imm_ImmOrLabel(i, getImm(target), getLabel(target));
    }
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IA32ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) GPR(org.jikesrvm.ia32.RegisterConstants.GPR)

Example 2 with GPR

use of org.jikesrvm.ia32.RegisterConstants.GPR in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method genParameterCopy.

/**
 * Stores parameters into local space of the callee's stackframe.
 * <p>
 * Assumption: although some parameters may be passed in registers,
 * space for all parameters is laid out in order on the caller's stackframe.
 *
 * @param srcOffset offset from frame pointer of first parameter in caller's stackframe.
 */
private void genParameterCopy(Offset srcOffset) {
    // number of general purpose registers unloaded
    int gpr = 0;
    // number of floating point registers unloaded
    int fpr = 0;
    // next GPR to get a parameter
    GPR T = T0;
    // offset from the bottom of the locals for the current parameter
    int dstOffset = 0;
    if (!method.isStatic()) {
        // handle "this" parameter
        if (gpr < NUM_PARAMETER_GPRS) {
            asm.emitPUSH_Reg(T);
            // at most 2 parameters can be passed in general purpose registers
            T = T1;
            gpr++;
        } else {
            // no parameters passed in registers
            asm.emitPUSH_RegDisp(SP, srcOffset);
        }
        dstOffset -= WORDSIZE;
    }
    // to handle floating point parameters in registers
    int[] fprOffset = new int[NUM_PARAMETER_FPRS];
    // to handle floating point parameters in registers
    boolean[] is32bit = new boolean[NUM_PARAMETER_FPRS];
    // in the case of doubles and floats SP may drift from the expected value as we don't use push/pop
    int spIsOffBy = 0;
    for (TypeReference t : method.getParameterTypes()) {
        if (t.isLongType()) {
            if (spIsOffBy != 0) {
                // fix up SP if it drifted
                adjustStack(-spIsOffBy, true);
                spIsOffBy = 0;
            }
            if (gpr < NUM_PARAMETER_GPRS) {
                if (VM.BuildFor32Addr) {
                    // hi mem := lo register (== hi order word)
                    asm.emitPUSH_Reg(T);
                    // at most 2 parameters can be passed in general purpose registers
                    T = T1;
                    gpr++;
                    if (gpr < NUM_PARAMETER_GPRS) {
                        // lo mem := hi register (== lo order word)
                        asm.emitPUSH_Reg(T);
                        gpr++;
                    } else {
                        // lo mem from caller's stackframe
                        asm.emitPUSH_RegDisp(SP, srcOffset);
                    }
                } else {
                    // create empty slot
                    adjustStack(-WORDSIZE, true);
                    // push long
                    asm.emitPUSH_Reg(T);
                    // at most 2 parameters can be passed in general purpose registers
                    T = T1;
                    gpr++;
                }
            } else {
                if (VM.BuildFor32Addr) {
                    // hi mem from caller's stackframe
                    asm.emitPUSH_RegDisp(SP, srcOffset);
                    // lo mem from caller's stackframe
                    asm.emitPUSH_RegDisp(SP, srcOffset);
                } else {
                    // create empty slot
                    adjustStack(-WORDSIZE, true);
                    // push long
                    asm.emitPUSH_RegDisp(SP, srcOffset);
                }
            }
            dstOffset -= 2 * WORDSIZE;
        } else if (t.isFloatType()) {
            if (fpr < NUM_PARAMETER_FPRS) {
                spIsOffBy += WORDSIZE;
                fprOffset[fpr] = dstOffset;
                is32bit[fpr] = true;
                fpr++;
            } else {
                if (spIsOffBy != 0) {
                    // fix up SP if it drifted
                    adjustStack(-spIsOffBy, true);
                    spIsOffBy = 0;
                }
                asm.emitPUSH_RegDisp(SP, srcOffset);
            }
            dstOffset -= WORDSIZE;
        } else if (t.isDoubleType()) {
            if (fpr < NUM_PARAMETER_FPRS) {
                spIsOffBy += 2 * WORDSIZE;
                dstOffset -= WORDSIZE;
                fprOffset[fpr] = dstOffset;
                dstOffset -= WORDSIZE;
                is32bit[fpr] = false;
                fpr++;
            } else {
                if (spIsOffBy != 0) {
                    // fix up SP if it drifted
                    adjustStack(-spIsOffBy, true);
                    spIsOffBy = 0;
                }
                if (VM.BuildFor32Addr) {
                    // hi mem from caller's stackframe
                    asm.emitPUSH_RegDisp(SP, srcOffset);
                    // lo mem from caller's stackframe
                    asm.emitPUSH_RegDisp(SP, srcOffset);
                } else {
                    // create empty slot
                    adjustStack(-WORDSIZE, true);
                    // push double
                    asm.emitPUSH_RegDisp(SP, srcOffset);
                }
                dstOffset -= 2 * WORDSIZE;
            }
        } else {
            // t is object, int, short, char, byte, or boolean
            if (spIsOffBy != 0) {
                // fix up SP if it drifted
                adjustStack(-spIsOffBy, true);
                spIsOffBy = 0;
            }
            if (gpr < NUM_PARAMETER_GPRS) {
                asm.emitPUSH_Reg(T);
                // at most 2 parameters can be passed in general purpose registers
                T = T1;
                gpr++;
            } else {
                asm.emitPUSH_RegDisp(SP, srcOffset);
            }
            dstOffset -= WORDSIZE;
        }
    }
    if (spIsOffBy != 0) {
        // fix up SP if it drifted
        adjustStack(-spIsOffBy, true);
    }
    for (int i = fpr - 1; 0 <= i; i--) {
        // unload the floating point register stack (backwards)
        if (is32bit[i]) {
            if (SSE2_BASE) {
                asm.emitMOVSS_RegDisp_Reg(SP, Offset.fromIntSignExtend(fprOffset[i] - dstOffset - WORDSIZE), XMM.lookup(i));
            } else {
                asm.emitFSTP_RegDisp_Reg(SP, Offset.fromIntSignExtend(fprOffset[i] - dstOffset - WORDSIZE), FP0);
            }
        } else {
            if (SSE2_BASE) {
                asm.emitMOVSD_RegDisp_Reg(SP, Offset.fromIntSignExtend(fprOffset[i] - dstOffset - WORDSIZE), XMM.lookup(i));
            } else {
                asm.emitFSTP_RegDisp_Reg_Quad(SP, Offset.fromIntSignExtend(fprOffset[i] - dstOffset - WORDSIZE), FP0);
            }
        }
    }
}
Also used : GPR(org.jikesrvm.ia32.RegisterConstants.GPR) TypeReference(org.jikesrvm.classloader.TypeReference)

Example 3 with GPR

use of org.jikesrvm.ia32.RegisterConstants.GPR in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method genParameterRegisterLoad.

/**
 * Copy parameters from operand stack into registers.
 * Assumption: parameters are layed out on the stack in order
 * with SP pointing to the last parameter.
 * Also, this method is called before the generation of an explicit method call.
 * @param method is the method to be called.
 * @param hasThisParam is the method virtual?
 */
protected void genParameterRegisterLoad(MethodReference method, boolean hasThisParam) {
    int max = NUM_PARAMETER_GPRS + NUM_PARAMETER_FPRS;
    // quit looking when all registers are full
    if (max == 0)
        return;
    // number of general purpose registers filled
    int gpr = 0;
    // number of floating point  registers filled
    int fpr = 0;
    // next GPR to get a parameter
    GPR T = T0;
    int params = method.getParameterWords() + (hasThisParam ? 1 : 0);
    // stack offset of first parameter word
    Offset offset = Offset.fromIntSignExtend((params - 1) << LG_WORDSIZE);
    if (hasThisParam) {
        if (gpr < NUM_PARAMETER_GPRS) {
            stackMoveHelper(T, offset);
            // at most 2 parameters can be passed in general purpose registers
            T = T1;
            gpr++;
            max--;
        }
        offset = offset.minus(WORDSIZE);
    }
    for (TypeReference type : method.getParameterTypes()) {
        // quit looking when all registers are full
        if (max == 0)
            return;
        TypeReference t = type;
        if (t.isLongType()) {
            if (gpr < NUM_PARAMETER_GPRS) {
                if (WORDSIZE == 4) {
                    // lo register := hi mem (== hi order word)
                    stackMoveHelper(T, offset);
                    // at most 2 parameters can be passed in general purpose registers
                    T = T1;
                    gpr++;
                    max--;
                    if (gpr < NUM_PARAMETER_GPRS) {
                        // hi register := lo mem (== lo order word)
                        stackMoveHelper(T, offset.minus(WORDSIZE));
                        gpr++;
                        max--;
                    }
                } else {
                    // initially offset will point at junk word, move down and over
                    stackMoveHelper(T, offset.minus(WORDSIZE));
                    // at most 2 parameters can be passed in general purpose registers
                    T = T1;
                    gpr++;
                    max--;
                }
            }
            offset = offset.minus(2 * WORDSIZE);
        } else if (t.isFloatType()) {
            if (fpr < NUM_PARAMETER_FPRS) {
                if (SSE2_FULL) {
                    asm.emitMOVSS_Reg_RegDisp(XMM.lookup(fpr), SP, offset);
                } else {
                    asm.emitFLD_Reg_RegDisp(FP0, SP, offset);
                }
                fpr++;
                max--;
            }
            offset = offset.minus(WORDSIZE);
        } else if (t.isDoubleType()) {
            if (fpr < NUM_PARAMETER_FPRS) {
                if (SSE2_FULL) {
                    asm.emitMOVSD_Reg_RegDisp(XMM.lookup(fpr), SP, offset.minus(WORDSIZE));
                } else {
                    asm.emitFLD_Reg_RegDisp_Quad(FP0, SP, offset.minus(WORDSIZE));
                }
                fpr++;
                max--;
            }
            offset = offset.minus(2 * WORDSIZE);
        } else if (t.isReferenceType() || t.isWordLikeType()) {
            if (gpr < NUM_PARAMETER_GPRS) {
                stackMoveHelper(T, offset);
                // at most 2 parameters can be passed in general purpose registers
                T = T1;
                gpr++;
                max--;
            }
            offset = offset.minus(WORDSIZE);
        } else {
            // t is object, int, short, char, byte, or boolean
            if (gpr < NUM_PARAMETER_GPRS) {
                if (offset.isZero()) {
                    asm.emitMOV_Reg_RegInd(T, SP);
                } else {
                    asm.emitMOV_Reg_RegDisp(T, SP, offset);
                }
                // at most 2 parameters can be passed in general purpose registers
                T = T1;
                gpr++;
                max--;
            }
            offset = offset.minus(WORDSIZE);
        }
    }
    if (VM.VerifyAssertions)
        VM._assert(offset.EQ(Offset.fromIntSignExtend(-WORDSIZE)));
}
Also used : GPR(org.jikesrvm.ia32.RegisterConstants.GPR) TypeReference(org.jikesrvm.classloader.TypeReference) Offset(org.vmmagic.unboxed.Offset)

Example 4 with GPR

use of org.jikesrvm.ia32.RegisterConstants.GPR in project JikesRVM by JikesRVM.

the class OptExceptionDeliverer method deliverException.

/**
 * Pass control to a catch block.
 */
@Override
@Unpreemptible("Deliver exception possibly from unpreemptible code")
public void deliverException(CompiledMethod compiledMethod, Address catchBlockInstructionAddress, Throwable exceptionObject, AbstractRegisters registers) {
    OptCompiledMethod optMethod = (OptCompiledMethod) compiledMethod;
    Address fp = registers.getInnermostFramePointer();
    RVMThread myThread = RVMThread.getCurrentThread();
    if (TRACE) {
        VM.sysWrite("Frame size of ");
        VM.sysWrite(optMethod.getMethod());
        VM.sysWrite(" is ");
        VM.sysWrite(optMethod.getFrameFixedSize());
        VM.sysWriteln();
    }
    // reset sp to "empty params" state (ie same as it was after prologue)
    Address sp = fp.minus(optMethod.getFrameFixedSize());
    registers.getGPRs().set(STACK_POINTER.value(), sp.toWord());
    // store exception object for later retrieval by catch block
    int offset = optMethod.getUnsignedExceptionOffset();
    if (offset != 0) {
        // only put the exception object in the stackframe if the catch block is expecting it.
        // (if the method hasn't allocated a stack slot for caught exceptions, then we can safely
        // drop the exceptionObject on the floor).
        Magic.setObjectAtOffset(Magic.addressAsObject(fp), Offset.fromIntSignExtend(-offset), exceptionObject);
        if (TRACE) {
            VM.sysWrite("Storing exception object ");
            VM.sysWrite(Magic.objectAsAddress(exceptionObject));
            VM.sysWrite(" at offset ");
            VM.sysWrite(offset);
            VM.sysWrite(" from framepoint ");
            VM.sysWrite(fp);
            VM.sysWriteln();
        }
    }
    if (TRACE) {
        VM.sysWrite("Registers before delivering exception in ");
        VM.sysWrite(optMethod.getMethod());
        VM.sysWriteln();
        for (GPR reg : GPR.values()) {
            VM.sysWrite(reg.toString());
            VM.sysWrite(" = ");
            VM.sysWrite(registers.getGPRs().get(reg.value()));
            VM.sysWriteln();
        }
    }
    // set address at which to resume executing frame
    registers.setIP(catchBlockInstructionAddress);
    if (TRACE) {
        VM.sysWrite("Set ip to ");
        VM.sysWrite(registers.getIP());
        VM.sysWriteln();
    }
    // disabled right before RuntimeEntrypoints.deliverException was called
    VM.enableGC();
    if (VM.VerifyAssertions)
        VM._assert(registers.getInUse());
    registers.setInUse(false);
    // 'give back' the portion of the stack we borrowed to run
    // exception delivery code when invoked for a hardware trap.
    // If this was a straight software trap (athrow) then setting
    // the stacklimit should be harmless, since the stacklimit should already have exactly
    // the value we are setting it too.
    myThread.stackLimit = Magic.objectAsAddress(myThread.getStack()).plus(STACK_SIZE_GUARD);
    // "branches" to catchBlockInstructionAddress
    Magic.restoreHardwareExceptionState(registers);
    if (VM.VerifyAssertions)
        VM._assert(NOT_REACHED);
}
Also used : OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) Address(org.vmmagic.unboxed.Address) RVMThread(org.jikesrvm.scheduler.RVMThread) GPR(org.jikesrvm.ia32.RegisterConstants.GPR) Unpreemptible(org.vmmagic.pragma.Unpreemptible)

Example 5 with GPR

use of org.jikesrvm.ia32.RegisterConstants.GPR in project JikesRVM by JikesRVM.

the class OptExceptionDeliverer method unwindStackFrame.

/**
 * Unwind a stackframe.
 */
@Override
@Unpreemptible("Unwind stack possibly from unpreemptible code")
public void unwindStackFrame(CompiledMethod compiledMethod, AbstractRegisters registers) {
    Address fp = registers.getInnermostFramePointer();
    OptCompiledMethod optMethod = (OptCompiledMethod) compiledMethod;
    if (TRACE) {
        VM.sysWrite("Registers before unwinding frame for ");
        VM.sysWrite(optMethod.getMethod());
        VM.sysWriteln();
        for (GPR reg : GPR.values()) {
            VM.sysWrite(reg.toString());
            VM.sysWrite(" = ");
            VM.sysWrite(registers.getGPRs().get(reg.value()));
            VM.sysWriteln();
        }
    }
    // restore non-volatile registers
    int frameOffset = optMethod.getUnsignedNonVolatileOffset();
    for (int i = optMethod.getFirstNonVolatileGPR(); i < NUM_NONVOLATILE_GPRS; i++, frameOffset += BYTES_IN_ADDRESS) {
        registers.getGPRs().set(NONVOLATILE_GPRS[i].value(), fp.minus(frameOffset).loadWord());
    }
    if (VM.VerifyAssertions)
        VM._assert(NUM_NONVOLATILE_FPRS == 0);
    registers.unwindStackFrame();
    if (TRACE) {
        VM.sysWrite("Registers after unwinding frame for ");
        VM.sysWrite(optMethod.getMethod());
        VM.sysWriteln();
        for (GPR reg : GPR.values()) {
            VM.sysWrite(reg.toString());
            VM.sysWrite(" = ");
            VM.sysWrite(registers.getGPRs().get(reg.value()));
            VM.sysWriteln();
        }
    }
}
Also used : OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) Address(org.vmmagic.unboxed.Address) GPR(org.jikesrvm.ia32.RegisterConstants.GPR) Unpreemptible(org.vmmagic.pragma.Unpreemptible)

Aggregations

GPR (org.jikesrvm.ia32.RegisterConstants.GPR)10 TypeReference (org.jikesrvm.classloader.TypeReference)3 ForwardReference (org.jikesrvm.compilers.common.assembler.ForwardReference)3 OptCompiledMethod (org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod)3 Offset (org.vmmagic.unboxed.Offset)3 FloatingPointMachineRegister (org.jikesrvm.ia32.RegisterConstants.FloatingPointMachineRegister)2 XMM (org.jikesrvm.ia32.RegisterConstants.XMM)2 Unpreemptible (org.vmmagic.pragma.Unpreemptible)2 Address (org.vmmagic.unboxed.Address)2 Assembler (org.jikesrvm.compilers.common.assembler.ia32.Assembler)1 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)1 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)1 MemoryOperand (org.jikesrvm.compilers.opt.ir.operand.MemoryOperand)1 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)1 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)1 StackLocationOperand (org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)1 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)1 IA32ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand)1 RVMThread (org.jikesrvm.scheduler.RVMThread)1 Entrypoint (org.vmmagic.pragma.Entrypoint)1