Search in sources :

Example 16 with MethodOperand

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

the class OptMachineCodeMap method generateMCInformation.

// //////////////////////////////////////////
// Create the map (at compile time)
// //////////////////////////////////////////
/**
 *  This method walks the IR map, and for each entry it creates
 *  the machine code mapping information for the entry.
 *  It is called during the compilation of the method, not at GC time.
 *  @param irMap  the irmap to translate from
 *  @param DUMP_MAPS dump while we work
 *  @param mcOffsets machine code offset information
 *  @return the machine code map
 */
private static OptMachineCodeMap generateMCInformation(GCIRMap irMap, boolean DUMP_MAPS, MachineCodeOffsets mcOffsets) {
    CallSiteTree inliningMap = new CallSiteTree();
    int numEntries = 0;
    // construct and encode the inlining information for those entries.
    for (GCIRMapElement irMapElem : irMap) {
        numEntries++;
        Instruction instr = irMapElem.getInstruction();
        if (instr.position() == null && instr.getBytecodeIndex() != INSTRUMENTATION_BCI) {
            if ((VM.BuildForIA32 && org.jikesrvm.compilers.opt.ir.ia32.MIR_Call.conforms(instr) && org.jikesrvm.compilers.opt.ir.ia32.MIR_Call.hasMethod(instr)) || (VM.BuildForPowerPC && org.jikesrvm.compilers.opt.ir.ppc.MIR_Call.conforms(instr) && org.jikesrvm.compilers.opt.ir.ppc.MIR_Call.hasMethod(instr))) {
                throw new OptimizingCompilerException("position required for all call instructions " + instr);
            }
        } else {
            inliningMap.addLocation(instr.position());
        }
    }
    // if no entries, then we are done.
    if (numEntries == 0)
        return emptyMachineCodeMap;
    int[] inlineEncoding = OptEncodedCallSiteTree.getEncoding(inliningMap);
    // (2) Encode the primary machine code mapping information and the GCMaps.
    OptGCMap gcMapBuilder = new OptGCMap();
    int[] tmpMC = new int[numEntries * SIZEOF_HUGE_ENTRY];
    int lastMCInfoEntry = 0;
    for (GCIRMapElement irMapElem : irMap) {
        Instruction instr = irMapElem.getInstruction();
        if (DUMP_MAPS)
            VM.sysWrite("IR Map for " + instr + "\n\t" + irMapElem);
        // retrieve the machine code offset (in bytes) from the instruction,
        ensureCorrectMapConstruction(mcOffsets, instr);
        int mco = mcOffsets.getMachineCodeOffset(instr);
        if (mco < 0) {
            VM.sysWrite("Negative machine code MCOffset found:" + mco);
            Instruction i = irMapElem.getInstruction();
            int machineCodeOffsetForI = mcOffsets.getMachineCodeOffset(i);
            VM.sysWriteln(i.getBytecodeIndex() + ", " + i + ", " + machineCodeOffsetForI);
            throw new OptimizingCompilerException("Negative machine code MCOffset found");
        }
        // create GC map and get GCI
        int gci = gcMapBuilder.generateGCMapEntry(irMapElem);
        // get bci information
        int bci = instr.getBytecodeIndex();
        if (bci < 0) {
            if ((bci == UNKNOWN_BCI) && ((VM.BuildForIA32 && org.jikesrvm.compilers.opt.ir.ia32.MIR_Call.conforms(instr) && org.jikesrvm.compilers.opt.ir.ia32.MIR_Call.hasMethod(instr)) || (VM.BuildForPowerPC && org.jikesrvm.compilers.opt.ir.ppc.MIR_Call.conforms(instr) && org.jikesrvm.compilers.opt.ir.ppc.MIR_Call.hasMethod(instr)))) {
                throw new OptimizingCompilerException("valid bytecode index required for all calls " + instr);
            }
            bci = -1;
        }
        // get index into inline encoding
        int iei = -1;
        if (instr.position() != null) {
            iei = inliningMap.find(instr.position()).encodedOffset;
        }
        // set the call info
        int cm = 0;
        if ((VM.BuildForIA32 && org.jikesrvm.compilers.opt.ir.ia32.MIR_Call.conforms(instr)) || (VM.BuildForPowerPC && org.jikesrvm.compilers.opt.ir.ppc.MIR_Call.conforms(instr))) {
            MethodOperand mo;
            if (VM.BuildForIA32) {
                mo = org.jikesrvm.compilers.opt.ir.ia32.MIR_Call.getMethod(instr);
            } else {
                if (VM.VerifyAssertions)
                    VM._assert(VM.BuildForPowerPC);
                mo = org.jikesrvm.compilers.opt.ir.ppc.MIR_Call.getMethod(instr);
            }
            if (mo != null && mo.isGuardedInlineOffBranch()) {
                cm = IS_GUARDED_CALL;
            } else {
                cm = IS_UNGUARDED_CALL;
            }
        }
        // Encode this entry into MCInformation
        if (bci < INVALID_BCI && iei < INVALID_IEI && gci < INVALID_GCI && mco < (OFFSET_MASK >>> OFFSET_SHIFT)) {
            // use a small entry
            if (bci == -1)
                bci = INVALID_BCI;
            if (iei == -1)
                iei = INVALID_IEI;
            if (gci == -1)
                gci = INVALID_GCI;
            if (VM.VerifyAssertions) {
                VM._assert((cm & (CALL_MASK >>> CALL_SHIFT)) == cm);
                VM._assert((bci & (BCI_MASK >>> BCI_SHIFT)) == bci);
                VM._assert((iei & (IEI_MASK >>> IEI_SHIFT)) == iei);
                VM._assert((gci & (GCI_MASK >>> GCI_SHIFT)) == gci);
                VM._assert((mco & (OFFSET_MASK >>> OFFSET_SHIFT)) == mco);
            }
            int t = START_OF_ENTRY;
            t |= (cm << CALL_SHIFT);
            t |= (bci << BCI_SHIFT);
            t |= (iei << IEI_SHIFT);
            t |= (gci << GCI_SHIFT);
            t |= (mco << OFFSET_SHIFT);
            tmpMC[lastMCInfoEntry++] = t;
        } else if (bci < BIG_INVALID_BCI && iei < BIG_INVALID_IEI && gci < BIG_INVALID_GCI && mco < (BIG_OFFSET_MASK >>> BIG_OFFSET_SHIFT)) {
            // use a big entry
            if (bci == -1)
                bci = BIG_INVALID_BCI;
            if (iei == -1)
                iei = BIG_INVALID_IEI;
            if (gci == -1)
                gci = BIG_INVALID_GCI;
            if (VM.VerifyAssertions) {
                VM._assert((cm & (BIG_CALL_MASK >>> BIG_CALL_SHIFT)) == cm);
                VM._assert((bci & (BIG_BCI_MASK >>> BIG_BCI_SHIFT)) == bci);
                VM._assert((iei & (BIG_IEI_MASK >>> BIG_IEI_SHIFT)) == iei);
                VM._assert((gci & (BIG_GCI_MASK >>> BIG_GCI_SHIFT)) == gci);
                VM._assert((mco & (BIG_OFFSET_MASK >>> BIG_OFFSET_SHIFT)) == mco);
            }
            int startIdx = lastMCInfoEntry;
            tmpMC[startIdx] = START_OF_BIG_ENTRY;
            tmpMC[startIdx + BIG_CALL_IDX_ADJ] |= (cm << BIG_CALL_SHIFT);
            tmpMC[startIdx + BIG_BCI_IDX_ADJ] |= (bci << BIG_BCI_SHIFT);
            tmpMC[startIdx + BIG_OFFSET_IDX_ADJ] |= (mco << BIG_OFFSET_SHIFT);
            tmpMC[startIdx + BIG_GCI_IDX_ADJ] |= (gci << BIG_GCI_SHIFT);
            tmpMC[startIdx + BIG_IEI_IDX_ADJ] |= (iei << BIG_IEI_SHIFT);
            lastMCInfoEntry += SIZEOF_BIG_ENTRY;
        } else {
            // use a huge entry
            if (bci == -1)
                bci = HUGE_INVALID_BCI;
            if (iei == -1)
                iei = HUGE_INVALID_IEI;
            if (gci == -1)
                gci = HUGE_INVALID_GCI;
            if (VM.VerifyAssertions) {
                VM._assert((cm & (HUGE_CALL_MASK >>> HUGE_CALL_SHIFT)) == cm);
                VM._assert((bci & (HUGE_BCI_MASK >>> HUGE_BCI_SHIFT)) == bci);
                VM._assert((iei & (HUGE_IEI_MASK >>> HUGE_IEI_SHIFT)) == iei);
                VM._assert((gci & (HUGE_GCI_MASK >>> HUGE_GCI_SHIFT)) == gci);
                VM._assert((mco & (HUGE_OFFSET_MASK >>> HUGE_OFFSET_SHIFT)) == mco);
            }
            int startIdx = lastMCInfoEntry;
            tmpMC[startIdx] = START_OF_HUGE_ENTRY;
            tmpMC[startIdx + HUGE_CALL_IDX_ADJ] |= (cm << HUGE_CALL_SHIFT);
            tmpMC[startIdx + HUGE_BCI_IDX_ADJ] |= (bci << HUGE_BCI_SHIFT);
            tmpMC[startIdx + HUGE_OFFSET_IDX_ADJ] |= (mco << HUGE_OFFSET_SHIFT);
            tmpMC[startIdx + HUGE_GCI_IDX_ADJ] |= (gci << HUGE_GCI_SHIFT);
            tmpMC[startIdx + HUGE_IEI_IDX_ADJ] |= (iei << HUGE_IEI_SHIFT);
            lastMCInfoEntry += SIZEOF_HUGE_ENTRY;
        }
    }
    int[] mcInformation = new int[lastMCInfoEntry];
    System.arraycopy(tmpMC, 0, mcInformation, 0, mcInformation.length);
    int[] gcMaps = gcMapBuilder.finish();
    return new OptMachineCodeMap(mcInformation, gcMaps, inlineEncoding);
}
Also used : CallSiteTree(org.jikesrvm.compilers.opt.inlining.CallSiteTree) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) GCIRMapElement(org.jikesrvm.compilers.opt.ir.GCIRMapElement) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand)

Example 17 with MethodOperand

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

the class CallingConvention method callExpand.

/**
 * Expands the calling convention for a particular call instruction.
 *
 * @param call the call instruction
 * @param ir the IR that contains the call instruction
 */
private static void callExpand(Instruction call, IR ir) {
    boolean isSysCall = call.operator() == IA32_SYSCALL;
    // 0. Handle the parameters
    int parameterBytes = isSysCall ? expandParametersToSysCall(call, ir) : expandParametersToCall(call, ir);
    // 1. Clear the floating-point stack if dirty.
    if (!SSE2_FULL) {
        if (!call.operator().isCallSaveVolatile()) {
            int FPRRegisterParams = countFPRParams(call);
            FPRRegisterParams = Math.min(FPRRegisterParams, PhysicalRegisterSet.getNumberOfFPRParams());
            call.insertBefore(MIR_UnaryNoRes.create(IA32_FCLEAR, IC(FPRRegisterParams)));
        }
    }
    // 2. Move the return value into a register
    expandResultOfCall(call, isSysCall, ir);
    // in the processor object to hold the interface signature id.
    if (VM.BuildForIMTInterfaceInvocation) {
        if (MIR_Call.hasMethod(call)) {
            MethodOperand mo = MIR_Call.getMethod(call);
            if (mo.isInterface()) {
                InterfaceMethodSignature sig = InterfaceMethodSignature.findOrCreate(mo.getMemberRef());
                MemoryOperand M = MemoryOperand.BD(ir.regpool.makeTROp(), ArchEntrypoints.hiddenSignatureIdField.getOffset(), (byte) WORDSIZE, null, null);
                call.insertBefore(MIR_Move.create(IA32_MOV, M, IC(sig.getId())));
            }
        }
    }
    // 4. ESP must be parameterBytes before call, will be at either parameterBytes
    // or 0 afterwards depending on whether or it is an RVM method or a sysCall.
    Instruction requireESP = MIR_UnaryNoRes.create(REQUIRE_ESP, IC(parameterBytes));
    call.insertBefore(requireESP);
    Instruction adviseESP = MIR_UnaryNoRes.create(ADVISE_ESP, IC(isSysCall ? parameterBytes : 0));
    call.insertAfter(adviseESP);
    // by 16 at the call.
    if (VM.BuildFor64Addr && isSysCall) {
        alignStackForX64SysCall(call, ir, parameterBytes, requireESP, adviseESP);
    }
}
Also used : InterfaceMethodSignature(org.jikesrvm.classloader.InterfaceMethodSignature) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand)

Example 18 with MethodOperand

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

the class GenerateMagic method generateMagic.

/**
 * "Semantic inlining" of methods of the Magic class.
 * Based on the methodName, generate a sequence of opt instructions
 * that implement the magic, updating the expression stack as necessary.
 *
 * @param bc2ir the bc2ir object that is generating the
 *              ir containing this magic
 * @param gc must be bc2ir.gc
 * @param meth the RVMMethod that is the magic method
 * @return {@code true} if and only if magic was generated
 */
static boolean generateMagic(BC2IR bc2ir, GenerationContext gc, MethodReference meth) throws MagicNotImplementedException {
    if (gc.getMethod().hasNoInlinePragma())
        gc.forceFrameAllocation();
    Atom methodName = meth.getName();
    boolean address = (meth.getType() == TypeReference.Address);
    // Address magic
    TypeReference[] types = meth.getParameterTypes();
    TypeReference returnType = meth.getReturnType();
    if (address && isLoad(methodName)) {
        // LOAD
        Operand offset = (types.length == 0) ? AC(Address.zero()) : bc2ir.popAddress();
        Operand base = bc2ir.popAddress();
        RegisterOperand result = gc.getTemps().makeTemp(returnType);
        bc2ir.appendInstruction(Load.create(getOperator(returnType, LOAD_OP), result, base, offset, null));
        bc2ir.push(result.copyD2U(), returnType);
    } else if (address && isPrepare(methodName)) {
        // PREPARE
        Operand offset = (types.length == 0) ? AC(Address.zero()) : bc2ir.popAddress();
        Operand base = bc2ir.popAddress();
        RegisterOperand result = gc.getTemps().makeTemp(returnType);
        bc2ir.appendInstruction(Prepare.create(getOperator(returnType, PREPARE_OP), result, base, offset, null));
        bc2ir.push(result.copyD2U(), returnType);
    } else if (address && methodName == MagicNames.attempt) {
        // ATTEMPT
        TypeReference attemptType = types[0];
        Operand offset = (types.length == 2) ? AC(Address.zero()) : bc2ir.popAddress();
        Operand newVal = bc2ir.pop();
        Operand oldVal = bc2ir.pop();
        Operand base = bc2ir.popAddress();
        RegisterOperand test = gc.getTemps().makeTempInt();
        bc2ir.appendInstruction(Attempt.create(getOperator(attemptType, ATTEMPT_OP), test, base, offset, oldVal, newVal, null));
        bc2ir.push(test.copyD2U(), returnType);
    } else if (address && methodName == MagicNames.store) {
        // STORE
        TypeReference storeType = types[0];
        Operand offset = (types.length == 1) ? AC(Address.zero()) : bc2ir.popAddress();
        Operand val = bc2ir.pop(storeType);
        Operand base = bc2ir.popAddress();
        bc2ir.appendInstruction(Store.create(getOperator(storeType, STORE_OP), val, base, offset, null));
    } else if (methodName == MagicNames.getThreadRegister) {
        RegisterOperand rop = gc.getTemps().makeTROp();
        bc2ir.markGuardlessNonNull(rop);
        bc2ir.push(rop);
    } else if (methodName == MagicNames.setThreadRegister) {
        Operand val = bc2ir.popRef();
        if (val instanceof RegisterOperand) {
            bc2ir.appendInstruction(Move.create(REF_MOVE, gc.getTemps().makeTROp(), val));
        } else {
            String msg = " Unexpected operand Magic.setThreadRegister";
            throw MagicNotImplementedException.UNEXPECTED(msg);
        }
    } else if (methodName == MagicNames.addressArrayCreate) {
        Instruction s = bc2ir.generateAnewarray(null, meth.getType().getArrayElementType());
        bc2ir.appendInstruction(s);
    } else if (methodName == MagicNames.addressArrayLength) {
        Operand op1 = bc2ir.pop();
        bc2ir.clearCurrentGuard();
        if (bc2ir.do_NullCheck(op1)) {
            return true;
        }
        RegisterOperand t = gc.getTemps().makeTempInt();
        Instruction s = GuardedUnary.create(ARRAYLENGTH, t, op1, bc2ir.getCurrentGuard());
        bc2ir.push(t.copyD2U());
        bc2ir.appendInstruction(s);
    } else if (methodName == MagicNames.addressArrayGet) {
        TypeReference elementType = meth.getReturnType();
        Operand index = bc2ir.popInt();
        Operand ref = bc2ir.popRef();
        RegisterOperand offsetI = gc.getTemps().makeTempInt();
        RegisterOperand offset = gc.getTemps().makeTempOffset();
        RegisterOperand result;
        if (meth.getType().isCodeArrayType()) {
            if (VM.BuildForIA32) {
                result = gc.getTemps().makeTemp(TypeReference.Byte);
                bc2ir.appendInstruction(Load.create(BYTE_LOAD, result, ref, index, new LocationOperand(elementType), new TrueGuardOperand()));
            } else if (VM.BuildForPowerPC) {
                result = gc.getTemps().makeTemp(TypeReference.Int);
                bc2ir.appendInstruction(Binary.create(INT_SHL, offsetI, index, new IntConstantOperand(LOG_BYTES_IN_INT)));
                bc2ir.appendInstruction(Unary.create(INT_2ADDRZerExt, offset, offsetI.copy()));
                bc2ir.appendInstruction(Load.create(INT_LOAD, result, ref, offset.copy(), new LocationOperand(elementType), new TrueGuardOperand()));
            }
        } else {
            result = gc.getTemps().makeTemp(elementType);
            bc2ir.appendInstruction(Binary.create(INT_SHL, offsetI, index, new IntConstantOperand(LOG_BYTES_IN_ADDRESS)));
            bc2ir.appendInstruction(Unary.create(INT_2ADDRZerExt, offset, offsetI.copy()));
            bc2ir.appendInstruction(Load.create(REF_LOAD, result, ref, offset.copy(), new LocationOperand(elementType), new TrueGuardOperand()));
        }
        bc2ir.push(result.copyD2U());
    } else if (methodName == MagicNames.addressArraySet) {
        TypeReference elementType = meth.getParameterTypes()[1];
        Operand val = bc2ir.pop();
        Operand index = bc2ir.popInt();
        Operand ref = bc2ir.popRef();
        RegisterOperand offsetI = gc.getTemps().makeTempInt();
        RegisterOperand offset = gc.getTemps().makeTempOffset();
        if (meth.getType().isCodeArrayType()) {
            if (VM.BuildForIA32) {
                bc2ir.appendInstruction(Store.create(BYTE_STORE, val, ref, index, new LocationOperand(elementType), new TrueGuardOperand()));
            } else if (VM.BuildForPowerPC) {
                bc2ir.appendInstruction(Binary.create(INT_SHL, offsetI, index, new IntConstantOperand(LOG_BYTES_IN_INT)));
                bc2ir.appendInstruction(Unary.create(INT_2ADDRZerExt, offset, offsetI.copy()));
                bc2ir.appendInstruction(Store.create(INT_STORE, val, ref, offset.copy(), new LocationOperand(elementType), new TrueGuardOperand()));
            }
        } else {
            bc2ir.appendInstruction(Binary.create(INT_SHL, offsetI, index, new IntConstantOperand(LOG_BYTES_IN_ADDRESS)));
            bc2ir.appendInstruction(Unary.create(INT_2ADDRZerExt, offset, offsetI.copy()));
            bc2ir.appendInstruction(Store.create(REF_STORE, val, ref, offset.copy(), new LocationOperand(elementType), new TrueGuardOperand()));
        }
    } else if (methodName == MagicNames.getIntAtOffset) {
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        RegisterOperand val = gc.getTemps().makeTempInt();
        bc2ir.appendInstruction(Load.create(INT_LOAD, val, object, offset, null));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.setIntAtOffset) {
        LocationOperand loc = null;
        if (meth.getParameterTypes().length == 4) {
            loc = mapToMetadata(bc2ir.popInt());
        }
        Operand val = bc2ir.popInt();
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        bc2ir.appendInstruction(Store.create(INT_STORE, val, object, offset, loc));
    } else if (methodName == MagicNames.getFloatAtOffset) {
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        RegisterOperand val = gc.getTemps().makeTempFloat();
        bc2ir.appendInstruction(Load.create(FLOAT_LOAD, val, object, offset, null));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.setFloatAtOffset) {
        LocationOperand loc = null;
        if (meth.getParameterTypes().length == 4) {
            loc = mapToMetadata(bc2ir.popInt());
        }
        Operand val = bc2ir.popFloat();
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        bc2ir.appendInstruction(Store.create(FLOAT_STORE, val, object, offset, loc));
    } else if (methodName == MagicNames.getWordAtOffset) {
        LocationOperand loc = null;
        if (meth.getParameterTypes().length == 3) {
            loc = mapToMetadata(bc2ir.popInt());
        }
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.Word);
        bc2ir.appendInstruction(Load.create(REF_LOAD, val, object, offset, loc));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.getAddressAtOffset) {
        LocationOperand loc = null;
        if (meth.getParameterTypes().length == 3) {
            loc = mapToMetadata(bc2ir.popInt());
        }
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.Address);
        bc2ir.appendInstruction(Load.create(REF_LOAD, val, object, offset, loc));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.getExtentAtOffset) {
        LocationOperand loc = null;
        if (meth.getParameterTypes().length == 3) {
            loc = mapToMetadata(bc2ir.popInt());
        }
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.Extent);
        bc2ir.appendInstruction(Load.create(REF_LOAD, val, object, offset, loc));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.getOffsetAtOffset) {
        LocationOperand loc = null;
        if (meth.getParameterTypes().length == 3) {
            loc = mapToMetadata(bc2ir.popInt());
        }
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.Offset);
        bc2ir.appendInstruction(Load.create(REF_LOAD, val, object, offset, loc));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.setWordAtOffset || methodName == MagicNames.setAddressAtOffset || methodName == MagicNames.setOffsetAtOffset || methodName == MagicNames.setExtentAtOffset) {
        LocationOperand loc = null;
        if (meth.getParameterTypes().length == 4) {
            loc = mapToMetadata(bc2ir.popInt());
        }
        Operand val = bc2ir.popRef();
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        bc2ir.appendInstruction(Store.create(REF_STORE, val, object, offset, loc));
    } else if (methodName == MagicNames.getLongAtOffset) {
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        RegisterOperand val = gc.getTemps().makeTempLong();
        bc2ir.appendInstruction(Load.create(LONG_LOAD, val, object, offset, null));
        bc2ir.pushDual(val.copyD2U());
    } else if (methodName == MagicNames.setLongAtOffset) {
        LocationOperand loc = null;
        if (meth.getParameterTypes().length == 4) {
            loc = mapToMetadata(bc2ir.popInt());
        }
        Operand val = bc2ir.popLong();
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        bc2ir.appendInstruction(Store.create(LONG_STORE, val, object, offset, loc));
    } else if (methodName == MagicNames.getDoubleAtOffset) {
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        RegisterOperand val = gc.getTemps().makeTempDouble();
        bc2ir.appendInstruction(Load.create(DOUBLE_LOAD, val, object, offset, null));
        bc2ir.pushDual(val.copyD2U());
    } else if (methodName == MagicNames.setDoubleAtOffset) {
        LocationOperand loc = null;
        if (meth.getParameterTypes().length == 4) {
            loc = mapToMetadata(bc2ir.popInt());
        }
        Operand val = bc2ir.popDouble();
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        bc2ir.appendInstruction(Store.create(DOUBLE_STORE, val, object, offset, loc));
    } else if (methodName == MagicNames.getObjectAtOffset) {
        LocationOperand loc = null;
        if (meth.getParameterTypes().length == 3) {
            loc = mapToMetadata(bc2ir.popInt());
        }
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.JavaLangObject);
        bc2ir.appendInstruction(Load.create(REF_LOAD, val, object, offset, loc));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.getTIBAtOffset) {
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.TIB);
        bc2ir.appendInstruction(Load.create(REF_LOAD, val, object, offset, null));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.setObjectAtOffset) {
        LocationOperand loc = null;
        if (meth.getParameterTypes().length == 4) {
            loc = mapToMetadata(bc2ir.popInt());
        }
        Operand val = bc2ir.popRef();
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        bc2ir.appendInstruction(Store.create(REF_STORE, val, object, offset, loc));
    } else if (methodName == MagicNames.getByteAtOffset) {
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.Byte);
        bc2ir.appendInstruction(Load.create(BYTE_LOAD, val, object, offset, null));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.getUnsignedByteAtOffset) {
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.Byte);
        bc2ir.appendInstruction(Load.create(UBYTE_LOAD, val, object, offset, null));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.setByteAtOffset || methodName == MagicNames.setBooleanAtOffset) {
        LocationOperand loc = null;
        if (meth.getParameterTypes().length == 4) {
            loc = mapToMetadata(bc2ir.popInt());
        }
        Operand val = bc2ir.popInt();
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        bc2ir.appendInstruction(Store.create(BYTE_STORE, val, object, offset, loc));
    } else if (methodName == MagicNames.getShortAtOffset) {
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.Char);
        bc2ir.appendInstruction(Load.create(SHORT_LOAD, val, object, offset, null));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.getCharAtOffset) {
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.Char);
        bc2ir.appendInstruction(Load.create(USHORT_LOAD, val, object, offset, null));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.setCharAtOffset || methodName == MagicNames.setShortAtOffset) {
        LocationOperand loc = null;
        if (meth.getParameterTypes().length == 4) {
            loc = mapToMetadata(bc2ir.popInt());
        }
        Operand val = bc2ir.popInt();
        Operand offset = bc2ir.popAddress();
        Operand object = bc2ir.popRef();
        bc2ir.appendInstruction(Store.create(SHORT_STORE, val, object, offset, loc));
    } else if (methodName == MagicNames.getMemoryInt) {
        Operand memAddr = bc2ir.popAddress();
        RegisterOperand val = gc.getTemps().makeTempInt();
        bc2ir.appendInstruction(Load.create(INT_LOAD, val, memAddr, AC(Offset.zero()), null));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.getMemoryWord) {
        Operand memAddr = bc2ir.popAddress();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.Word);
        bc2ir.appendInstruction(Load.create(REF_LOAD, val, memAddr, AC(Offset.zero()), null));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.getMemoryAddress) {
        Operand memAddr = bc2ir.popAddress();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.Address);
        bc2ir.appendInstruction(Load.create(REF_LOAD, val, memAddr, AC(Offset.zero()), null));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.setMemoryInt) {
        Operand val = bc2ir.popInt();
        Operand memAddr = bc2ir.popAddress();
        bc2ir.appendInstruction(Store.create(INT_STORE, val, memAddr, AC(Offset.zero()), null));
    } else if (methodName == MagicNames.setMemoryWord) {
        Operand val = bc2ir.popRef();
        Operand memAddr = bc2ir.popAddress();
        bc2ir.appendInstruction(Store.create(REF_STORE, val, memAddr, AC(Offset.zero()), null));
    } else if (meth.isSysCall()) {
        // All methods of SysCall have the following signature:
        // callNAME(Address functionAddress, <var args to pass via native calling convention>)
        // With 64 bit PowerPC ELF ABI, functionAddress points to the function descriptor
        TypeReference[] args = meth.getParameterTypes();
        Instruction call = Call.create(SYSCALL, null, null, null, null, args.length - 1);
        for (int i = args.length - 1; i >= 1; i--) {
            Call.setParam(call, i - 1, bc2ir.pop(args[i]));
        }
        Operand functionAddress = bc2ir.pop(args[0]);
        Call.setAddress(call, functionAddress);
        if (!returnType.isVoidType()) {
            RegisterOperand op0 = gc.getTemps().makeTemp(returnType);
            Call.setResult(call, op0);
            bc2ir.push(op0.copyD2U(), returnType);
        }
        Call.setMethod(call, MethodOperand.STATIC(meth, meth.peekResolvedMethod()));
        bc2ir.appendInstruction(call);
    } else if (meth.isSpecializedInvoke()) {
        // The callsite looks like              RETURN = INVOKE (ID, OBJECT, P0, P1 .. PN)
        // And the actual method will look like RETURN = INVOKE     (OBJECT, P0, P1 .. PN)
        // Create the call instruction
        Instruction call = Call.create(CALL, null, null, null, null, types.length - 1);
        // Plumb all of the normal parameters into the call
        for (int i = types.length - 1; i >= 2; i--) {
            Call.setParam(call, i - 1, bc2ir.pop(types[i]));
        }
        // The object being specialized
        Operand objectOperand = bc2ir.pop(types[1]);
        Call.setParam(call, 0, objectOperand);
        Operand guard = BC2IR.copyGuardFromOperand(objectOperand);
        if (guard == null) {
            // it's magic, so assume that it's OK....
            guard = new TrueGuardOperand();
        }
        Call.setGuard(call, guard);
        // Load the tib of this object
        RegisterOperand tibObject = gc.getTemps().makeTemp(TypeReference.TIB);
        bc2ir.appendInstruction(GuardedUnary.create(GET_OBJ_TIB, tibObject, objectOperand.copy(), guard.copy()));
        // The index of the specialized method
        Operand methodId = bc2ir.popInt();
        // Add the base offset for specialized methods and convert from index to address
        RegisterOperand tibOffset = gc.getTemps().makeTemp(TypeReference.Int);
        bc2ir.appendInstruction(Binary.create(INT_ADD, tibOffset, methodId, new IntConstantOperand(TIB_FIRST_SPECIALIZED_METHOD_INDEX)));
        bc2ir.appendInstruction(Binary.create(INT_SHL, tibOffset.copyRO(), tibOffset.copyD2U(), new IntConstantOperand(LOG_BYTES_IN_ADDRESS)));
        // Load the code address from the TIB
        RegisterOperand codeAddress = gc.getTemps().makeTemp(TypeReference.Address);
        bc2ir.appendInstruction(Load.create(REF_LOAD, codeAddress, tibObject.copyD2U(), tibOffset.copyD2U(), null));
        Call.setAddress(call, codeAddress.copyD2U());
        if (!returnType.isVoidType()) {
            RegisterOperand op0 = gc.getTemps().makeTemp(returnType);
            Call.setResult(call, op0);
            bc2ir.push(op0.copyD2U(), returnType);
        }
        bc2ir.appendInstruction(call);
    } else if (methodName == MagicNames.objectAsType) {
        RegisterOperand reg = gc.getTemps().makeTemp(TypeReference.Type);
        bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popRef()));
        bc2ir.push(reg.copyD2U());
    } else if (methodName == MagicNames.objectAsThread) {
        RegisterOperand reg = gc.getTemps().makeTemp(TypeReference.Thread);
        bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popRef()));
        bc2ir.push(reg.copyD2U());
    } else if (methodName == MagicNames.objectAsAddress) {
        RegisterOperand reg = gc.getTemps().makeTemp(TypeReference.Address);
        bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popRef()));
        bc2ir.push(reg.copyD2U());
    } else if (methodName == MagicNames.addressAsObject) {
        RegisterOperand reg = gc.getTemps().makeTemp(TypeReference.JavaLangObject);
        bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popAddress()));
        bc2ir.push(reg.copyD2U());
    } else if (methodName == MagicNames.addressAsTIB) {
        RegisterOperand reg = gc.getTemps().makeTemp(TypeReference.TIB);
        bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popAddress()));
        bc2ir.push(reg.copyD2U());
    } else if (methodName == MagicNames.addressAsByteArray) {
        RegisterOperand reg = gc.getTemps().makeTemp(TypeReference.ByteArray);
        bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popAddress()));
        bc2ir.push(reg.copyD2U());
    } else if (methodName == MagicNames.objectAsShortArray) {
        RegisterOperand reg = gc.getTemps().makeTemp(TypeReference.ShortArray);
        bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popRef()));
        bc2ir.push(reg.copyD2U());
    } else if (methodName == MagicNames.objectAsIntArray) {
        RegisterOperand reg = gc.getTemps().makeTemp(TypeReference.IntArray);
        bc2ir.appendInstruction(Move.create(REF_MOVE, reg, bc2ir.popRef()));
        bc2ir.push(reg.copyD2U());
    } else if (methodName == MagicNames.floatAsIntBits) {
        Operand val = bc2ir.popFloat();
        RegisterOperand op0 = gc.getTemps().makeTempInt();
        bc2ir.appendInstruction(Unary.create(FLOAT_AS_INT_BITS, op0, val));
        bc2ir.push(op0.copyD2U());
    } else if (methodName == MagicNames.intBitsAsFloat) {
        Operand val = bc2ir.popInt();
        RegisterOperand op0 = gc.getTemps().makeTempFloat();
        bc2ir.appendInstruction(Unary.create(INT_BITS_AS_FLOAT, op0, val));
        bc2ir.push(op0.copyD2U());
    } else if (methodName == MagicNames.doubleAsLongBits) {
        Operand val = bc2ir.popDouble();
        RegisterOperand op0 = gc.getTemps().makeTempLong();
        bc2ir.appendInstruction(Unary.create(DOUBLE_AS_LONG_BITS, op0, val));
        bc2ir.pushDual(op0.copyD2U());
    } else if (methodName == MagicNames.longBitsAsDouble) {
        Operand val = bc2ir.popLong();
        RegisterOperand op0 = gc.getTemps().makeTempDouble();
        bc2ir.appendInstruction(Unary.create(LONG_BITS_AS_DOUBLE, op0, val));
        bc2ir.pushDual(op0.copyD2U());
    } else if (methodName == MagicNames.sqrt) {
        TypeReference[] args = meth.getParameterTypes();
        if (args[0] == TypeReference.Float) {
            Operand val = bc2ir.popFloat();
            RegisterOperand op0 = gc.getTemps().makeTempFloat();
            bc2ir.appendInstruction(Unary.create(FLOAT_SQRT, op0, val));
            bc2ir.push(op0.copyD2U());
        } else if (args[0] == TypeReference.Double) {
            Operand val = bc2ir.popDouble();
            RegisterOperand op0 = gc.getTemps().makeTempDouble();
            bc2ir.appendInstruction(Unary.create(DOUBLE_SQRT, op0, val));
            bc2ir.pushDual(op0.copyD2U());
        } else {
            if (VM.VerifyAssertions)
                VM._assert(VM.NOT_REACHED, "SQRT only handles Double or Float operands");
        }
    } else if (methodName == MagicNames.getObjectType) {
        Operand val = bc2ir.popRef();
        if (val.isObjectConstant()) {
            bc2ir.push(new ObjectConstantOperand(val.getType().peekType(), Offset.zero()));
        } else {
            Operand guard = BC2IR.copyGuardFromOperand(val);
            if (guard == null) {
                // it's magic, so assume that it's OK....
                guard = new TrueGuardOperand();
            }
            RegisterOperand tibPtr = gc.getTemps().makeTemp(TypeReference.TIB);
            bc2ir.appendInstruction(GuardedUnary.create(GET_OBJ_TIB, tibPtr, val, guard));
            RegisterOperand op0;
            TypeReference argType = val.getType();
            if (argType.isArrayType()) {
                op0 = gc.getTemps().makeTemp(TypeReference.RVMArray);
            } else {
                if (argType == TypeReference.JavaLangObject || argType == TypeReference.JavaLangCloneable || argType == TypeReference.JavaIoSerializable) {
                    // could be an array or a class, so make op0 be a RVMType
                    op0 = gc.getTemps().makeTemp(TypeReference.Type);
                } else {
                    op0 = gc.getTemps().makeTemp(TypeReference.Class);
                }
            }
            bc2ir.markGuardlessNonNull(op0);
            bc2ir.appendInstruction(Unary.create(GET_TYPE_FROM_TIB, op0, tibPtr.copyD2U()));
            bc2ir.push(op0.copyD2U());
        }
    } else if (methodName == MagicNames.getArrayLength) {
        Operand val = bc2ir.popRef();
        RegisterOperand op0 = gc.getTemps().makeTempInt();
        bc2ir.appendInstruction(GuardedUnary.create(ARRAYLENGTH, op0, val, new TrueGuardOperand()));
        bc2ir.push(op0.copyD2U());
    } else if (methodName == MagicNames.invokeClassInitializer) {
        Instruction s = Call.create0(CALL, null, bc2ir.popRef(), null);
        bc2ir.appendInstruction(s);
    } else if ((methodName == MagicNames.invokeMethodReturningObject) || (methodName == MagicNames.invokeMethodReturningVoid) || (methodName == MagicNames.invokeMethodReturningLong) || (methodName == MagicNames.invokeMethodReturningDouble) || (methodName == MagicNames.invokeMethodReturningFloat) || (methodName == MagicNames.invokeMethodReturningInt)) {
        Operand spills = bc2ir.popRef();
        Operand fprmeta = bc2ir.popRef();
        Operand fprs = bc2ir.popRef();
        Operand gprs = bc2ir.popRef();
        Operand code = bc2ir.popRef();
        RegisterOperand res = null;
        if (methodName == MagicNames.invokeMethodReturningObject) {
            res = gc.getTemps().makeTemp(TypeReference.JavaLangObject);
            bc2ir.push(res.copyD2U());
        } else if (methodName == MagicNames.invokeMethodReturningLong) {
            res = gc.getTemps().makeTemp(TypeReference.Long);
            bc2ir.push(res.copyD2U(), TypeReference.Long);
        } else if (methodName == MagicNames.invokeMethodReturningDouble) {
            res = gc.getTemps().makeTempDouble();
            bc2ir.push(res.copyD2U(), TypeReference.Double);
        } else if (methodName == MagicNames.invokeMethodReturningFloat) {
            res = gc.getTemps().makeTempFloat();
            bc2ir.push(res.copyD2U(), TypeReference.Float);
        } else if (methodName == MagicNames.invokeMethodReturningInt) {
            res = gc.getTemps().makeTempInt();
            bc2ir.push(res.copyD2U());
        }
        RVMField target = ArchEntrypoints.reflectiveMethodInvokerInstructionsField;
        MethodOperand met = MethodOperand.STATIC(target);
        Instruction s = Call.create5(CALL, res, AC(target.getOffset()), met, code, gprs, fprs, fprmeta, spills);
        bc2ir.appendInstruction(s);
    } else if (methodName == MagicNames.saveThreadState) {
        Operand p1 = bc2ir.popRef();
        RVMField target = ArchEntrypoints.saveThreadStateInstructionsField;
        MethodOperand mo = MethodOperand.STATIC(target);
        bc2ir.appendInstruction(Call.create1(CALL, null, AC(target.getOffset()), mo, p1));
    } else if (methodName == MagicNames.threadSwitch) {
        Operand p2 = bc2ir.popRef();
        Operand p1 = bc2ir.popRef();
        RVMField target = ArchEntrypoints.threadSwitchInstructionsField;
        MethodOperand mo = MethodOperand.STATIC(target);
        bc2ir.appendInstruction(Call.create2(CALL, null, AC(target.getOffset()), mo, p1, p2));
    } else if (methodName == MagicNames.restoreHardwareExceptionState) {
        RVMField target = ArchEntrypoints.restoreHardwareExceptionStateInstructionsField;
        MethodOperand mo = MethodOperand.STATIC(target);
        bc2ir.appendInstruction(Call.create1(CALL, null, AC(target.getOffset()), mo, bc2ir.popRef()));
    } else if (methodName == MagicNames.prepareInt) {
        Operand offset = bc2ir.popAddress();
        Operand base = bc2ir.popRef();
        RegisterOperand val = gc.getTemps().makeTempInt();
        bc2ir.appendInstruction(Prepare.create(PREPARE_INT, val, base, offset, null));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.prepareLong) {
        Operand offset = bc2ir.popAddress();
        Operand base = bc2ir.popRef();
        RegisterOperand val = gc.getTemps().makeTempLong();
        bc2ir.appendInstruction(Prepare.create(PREPARE_LONG, val, base, offset, null));
        bc2ir.pushDual(val.copyD2U());
    } else if (methodName == MagicNames.prepareObject) {
        Operand offset = bc2ir.popAddress();
        Operand base = bc2ir.popRef();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.JavaLangObject);
        bc2ir.appendInstruction(Prepare.create(PREPARE_ADDR, val, base, offset, null));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.prepareAddress) {
        Operand offset = bc2ir.popAddress();
        Operand base = bc2ir.popRef();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.Address);
        bc2ir.appendInstruction(Prepare.create(PREPARE_ADDR, val, base, offset, null));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.prepareWord) {
        Operand offset = bc2ir.popAddress();
        Operand base = bc2ir.popRef();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.Word);
        bc2ir.appendInstruction(Prepare.create(PREPARE_ADDR, val, base, offset, null));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.attemptInt) {
        Operand newVal = bc2ir.popInt();
        Operand oldVal = bc2ir.popInt();
        Operand offset = bc2ir.popAddress();
        Operand base = bc2ir.popRef();
        RegisterOperand test = gc.getTemps().makeTempBoolean();
        bc2ir.appendInstruction(Attempt.create(ATTEMPT_INT, test, base, offset, oldVal, newVal, null));
        bc2ir.push(test.copyD2U());
    } else if (methodName == MagicNames.attemptLong) {
        Operand newVal = bc2ir.popLong();
        Operand oldVal = bc2ir.popLong();
        Operand offset = bc2ir.popAddress();
        Operand base = bc2ir.popRef();
        RegisterOperand test = gc.getTemps().makeTempBoolean();
        bc2ir.appendInstruction(Attempt.create(ATTEMPT_LONG, test, base, offset, oldVal, newVal, null));
        bc2ir.push(test.copyD2U());
    } else if (methodName == MagicNames.attemptObject) {
        Operand newVal = bc2ir.popRef();
        Operand oldVal = bc2ir.popRef();
        Operand offset = bc2ir.popAddress();
        Operand base = bc2ir.popRef();
        RegisterOperand test = gc.getTemps().makeTempBoolean();
        bc2ir.appendInstruction(Attempt.create(ATTEMPT_ADDR, test, base, offset, oldVal, newVal, null));
        bc2ir.push(test.copyD2U());
    } else if (methodName == MagicNames.attemptAddress) {
        Operand newVal = bc2ir.popAddress();
        Operand oldVal = bc2ir.popAddress();
        Operand offset = bc2ir.popAddress();
        Operand base = bc2ir.popRef();
        RegisterOperand test = gc.getTemps().makeTempBoolean();
        bc2ir.appendInstruction(Attempt.create(ATTEMPT_ADDR, test, base, offset, oldVal, newVal, null));
        bc2ir.push(test.copyD2U());
    } else if (methodName == MagicNames.attemptWord) {
        Operand newVal = bc2ir.pop();
        Operand oldVal = bc2ir.pop();
        Operand offset = bc2ir.popAddress();
        Operand base = bc2ir.popRef();
        RegisterOperand test = gc.getTemps().makeTempBoolean();
        bc2ir.appendInstruction(Attempt.create(ATTEMPT_ADDR, test, base, offset, oldVal, newVal, null));
        bc2ir.push(test.copyD2U());
    } else if (methodName == MagicNames.fence) {
        bc2ir.appendInstruction(Empty.create(FENCE));
    } else if (methodName == MagicNames.combinedLoadBarrier) {
        bc2ir.appendInstruction(Empty.create(READ_CEILING));
    } else if (methodName == MagicNames.storeStoreBarrier) {
        bc2ir.appendInstruction(Empty.create(WRITE_FLOOR));
    } else if (generatePolymorphicMagic(bc2ir, gc, meth, methodName)) {
        return true;
    } else if (methodName == MagicNames.getTimeBase) {
        RegisterOperand op0 = gc.getTemps().makeTempLong();
        bc2ir.appendInstruction(Nullary.create(GET_TIME_BASE, op0));
        bc2ir.pushDual(op0.copyD2U());
    } else if (methodName == MagicNames.getInlineDepth) {
        bc2ir.push(new IntConstantOperand(gc.getInlineSequence().getInlineDepth()));
    } else if (methodName == MagicNames.getCompilerLevel) {
        bc2ir.push(new IntConstantOperand(gc.getOptions().getOptLevel()));
    } else if (methodName == MagicNames.isConstantParameter) {
        Operand requestedOperand = bc2ir.pop();
        if (!(requestedOperand instanceof IntConstantOperand)) {
            throw new OptimizingCompilerException("Must supply constant to Magic.isConstantParameter");
        }
        int requested = ((IntConstantOperand) (requestedOperand)).value;
        boolean isConstant = gc.getArguments()[requested].isConstant();
        bc2ir.push(new IntConstantOperand(isConstant ? 1 : 0));
    } else if (methodName == MagicNames.getFrameSize) {
        RegisterOperand res = gc.getTemps().makeTempInt();
        gc.forceFrameAllocation();
        bc2ir.appendInstruction(Nullary.create(FRAMESIZE, res));
        bc2ir.push(res.copyD2U());
    } else {
        // Wasn't machine-independent, so try the machine-dependent magics next.
        if (VM.BuildForIA32) {
            return org.jikesrvm.compilers.opt.bc2ir.ia32.GenerateMachineSpecificMagic.generateMagic(bc2ir, gc, meth);
        } else {
            if (VM.VerifyAssertions)
                VM._assert(VM.BuildForPowerPC);
            return org.jikesrvm.compilers.opt.bc2ir.ppc.GenerateMachineSpecificMagic.generateMagic(bc2ir, gc, meth);
        }
    }
    return true;
}
Also used : IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) 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) ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) Atom(org.jikesrvm.classloader.Atom) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) RVMField(org.jikesrvm.classloader.RVMField) TypeReference(org.jikesrvm.classloader.TypeReference) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException)

Example 19 with MethodOperand

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

the class BURS_Helpers method CALL.

/**
 * Expand a call instruction.
 */
protected final void CALL(Instruction s) {
    Operand target = Call.getClearAddress(s);
    MethodOperand meth = Call.getClearMethod(s);
    // Step 1: Find out how many parameters we're going to have.
    int numParams = Call.getNumberOfParams(s);
    int longParams = 0;
    if (VM.BuildFor32Addr) {
        for (int pNum = 0; pNum < numParams; pNum++) {
            if (Call.getParam(s, pNum).getType().isLongType()) {
                longParams++;
            }
        }
    }
    // Step 2: Figure out what the result and result2 values will be
    RegisterOperand result = Call.getClearResult(s);
    RegisterOperand result2 = null;
    if (VM.BuildFor32Addr) {
        if (result != null && result.getType().isLongType()) {
            result2 = I(regpool.getSecondReg(result.getRegister()));
        }
    }
    // Step 3: Figure out what the operator is going to be
    Operator callOp;
    if (target instanceof RegisterOperand) {
        // indirect call through target (contains code addr)
        Register ctr = regpool.getPhysicalRegisterSet().asPPC().getCTR();
        EMIT(MIR_Move.create(PPC_MTSPR, A(ctr), (RegisterOperand) target));
        target = null;
        callOp = PPC_BCTRL;
    } else if (target instanceof BranchOperand) {
        // Earlier analysis has tagged this call as recursive,
        // set up for a direct call.
        callOp = PPC_BL;
    } else {
        throw new OptimizingCompilerException("Unexpected target operand " + target + " to call " + s);
    }
    // Step 4: Mutate the Call to an MIR_Call.
    // Note MIR_Call and Call have a different number of fixed
    // arguments, so some amount of copying is required. We'll hope the
    // opt compiler can manage to make this more efficient than it looks.
    Operand[] params = new Operand[numParams];
    for (int i = 0; i < numParams; i++) {
        params[i] = Call.getClearParam(s, i);
    }
    // see step 3: callTarget is either null or already a BranchOperand
    BranchOperand callTarget = (BranchOperand) target;
    EMIT(MIR_Call.mutate(s, callOp, result, result2, callTarget, meth, numParams + longParams));
    for (int paramIdx = 0, mirCallIdx = 0; paramIdx < numParams; ) {
        Operand param = params[paramIdx++];
        MIR_Call.setParam(s, mirCallIdx++, param);
        if (VM.BuildFor32Addr) {
            if (param instanceof RegisterOperand) {
                RegisterOperand rparam = (RegisterOperand) param;
                if (rparam.getType().isLongType()) {
                    MIR_Call.setParam(s, mirCallIdx++, L(regpool.getSecondReg(rparam.getRegister())));
                }
            }
        }
    }
}
Also used : Operator(org.jikesrvm.compilers.opt.ir.Operator) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) PowerPCConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ppc.PowerPCConditionOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) 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) PowerPCTrapOperand(org.jikesrvm.compilers.opt.ir.operand.ppc.PowerPCTrapOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) InlinedOsrTypeInfoOperand(org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) OsrPoint(org.jikesrvm.compilers.opt.ir.OsrPoint) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand)

Example 20 with MethodOperand

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

the class BURS_Helpers method SYSCALL.

/**
 * Expand a syscall instruction.
 */
protected final void SYSCALL(Instruction s) {
    burs.ir.setHasSysCall(true);
    Operand target = Call.getClearAddress(s);
    MethodOperand meth = Call.getClearMethod(s);
    // Step 1: Find out how many parameters we're going to have.
    int numParams = Call.getNumberOfParams(s);
    int longParams = 0;
    if (VM.BuildFor32Addr) {
        for (int pNum = 0; pNum < numParams; pNum++) {
            if (Call.getParam(s, pNum).getType().isLongType()) {
                longParams++;
            }
        }
    }
    // Step 2: Figure out what the result and result2 values will be
    RegisterOperand result = Call.getClearResult(s);
    RegisterOperand result2 = null;
    if (VM.BuildFor32Addr) {
        if (result != null && result.getType().isLongType()) {
            result2 = I(regpool.getSecondReg(result.getRegister()));
        }
    }
    // Step 3: Figure out what the operator is going to be
    Operator callOp;
    if (target instanceof RegisterOperand) {
        // indirect call through target (contains code addr)
        Register ctr = regpool.getPhysicalRegisterSet().asPPC().getCTR();
        EMIT(MIR_Move.create(PPC_MTSPR, A(ctr), (RegisterOperand) target));
        target = null;
        callOp = PPC_BCTRL_SYS;
    } else if (target instanceof BranchOperand) {
        // Earlier analysis has tagged this call as recursive,
        // set up for a direct call.
        callOp = PPC_BL_SYS;
    } else {
        throw new OptimizingCompilerException("Unexpected target operand " + target + " to call " + s);
    }
    // Step 4: Mutate the SysCall to an MIR_Call.
    // Note MIR_Call and Call have a different number of fixed
    // arguments, so some amount of copying is required. We'll hope the
    // opt compiler can manage to make this more efficient than it looks.
    Operand[] params = new Operand[numParams];
    for (int i = 0; i < numParams; i++) {
        params[i] = Call.getClearParam(s, i);
    }
    // see step 3: callTarget is either null or already a BranchOperand
    BranchOperand callTarget = (BranchOperand) target;
    EMIT(MIR_Call.mutate(s, callOp, result, result2, callTarget, meth, numParams + longParams));
    for (int paramIdx = 0, mirCallIdx = 0; paramIdx < numParams; ) {
        Operand param = params[paramIdx++];
        MIR_Call.setParam(s, mirCallIdx++, param);
        if (VM.BuildFor32Addr) {
            if (param instanceof RegisterOperand) {
                RegisterOperand rparam = (RegisterOperand) param;
                if (rparam.getType().isLongType()) {
                    MIR_Call.setParam(s, mirCallIdx++, L(regpool.getSecondReg(rparam.getRegister())));
                }
            }
        }
    }
}
Also used : Operator(org.jikesrvm.compilers.opt.ir.Operator) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) PowerPCConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ppc.PowerPCConditionOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) 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) PowerPCTrapOperand(org.jikesrvm.compilers.opt.ir.operand.ppc.PowerPCTrapOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) InlinedOsrTypeInfoOperand(org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) OsrPoint(org.jikesrvm.compilers.opt.ir.OsrPoint) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand)

Aggregations

MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)34 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)26 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)26 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)17 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)12 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)11 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)11 NormalMethod (org.jikesrvm.classloader.NormalMethod)10 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)10 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)10 Test (org.junit.Test)10 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)9 InlineSequence (org.jikesrvm.compilers.opt.inlining.InlineSequence)9 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)9 ExceptionHandlerBasicBlockBag (org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlockBag)9 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)9 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)9 RVMMethod (org.jikesrvm.classloader.RVMMethod)8 TypeReference (org.jikesrvm.classloader.TypeReference)8 OptOptions (org.jikesrvm.compilers.opt.OptOptions)8