Search in sources :

Example 16 with LocationOperand

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

the class ExpandRuntimeServices method perform.

/**
 * Given an HIR, expand operators that are implemented as calls to
 * runtime service methods. This method should be called as one of the
 * first steps in lowering HIR into LIR.
 *
 * @param ir  The HIR to expand
 */
@Override
public void perform(IR ir) {
    // resync generation context -- yuck...
    ir.getGc().resync();
    for (Instruction inst = ir.firstInstructionInCodeOrder(); inst != null; inst = next) {
        next = inst.nextInstructionInCodeOrder();
        int opcode = inst.getOpcode();
        switch(opcode) {
            case NEW_opcode:
                {
                    TypeOperand Type = New.getClearType(inst);
                    RVMClass cls = (RVMClass) Type.getVMType();
                    IntConstantOperand hasFinalizer = IRTools.IC(cls.hasFinalizer() ? 1 : 0);
                    RVMMethod callSite = inst.position().getMethod();
                    IntConstantOperand allocator = IRTools.IC(MemoryManager.pickAllocator(cls, callSite));
                    IntConstantOperand align = IRTools.IC(ObjectModel.getAlignment(cls));
                    IntConstantOperand offset = IRTools.IC(ObjectModel.getOffsetForAlignment(cls, false));
                    Operand tib = ConvertToLowLevelIR.getTIB(inst, ir, Type);
                    if (VM.BuildForIA32 && VM.runningVM) {
                        // shield BC2IR from address constants
                        RegisterOperand tmp = ir.regpool.makeTemp(TypeReference.TIB);
                        inst.insertBefore(Move.create(REF_MOVE, tmp, tib));
                        tib = tmp.copyRO();
                    }
                    IntConstantOperand site = IRTools.IC(MemoryManager.getAllocationSite(true));
                    RVMMethod target = Entrypoints.resolvedNewScalarMethod;
                    Call.mutate7(inst, CALL, New.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), IRTools.IC(cls.getInstanceSize()), tib, hasFinalizer, allocator, align, offset, site);
                    next = inst.prevInstructionInCodeOrder();
                    if (ir.options.H2L_INLINE_NEW) {
                        if (inst.getBasicBlock().getInfrequent())
                            container.counter1++;
                        container.counter2++;
                        if (!ir.options.FREQ_FOCUS_EFFORT || !inst.getBasicBlock().getInfrequent()) {
                            inline(inst, ir);
                        }
                    }
                }
                break;
            case NEW_UNRESOLVED_opcode:
                {
                    int typeRefId = New.getType(inst).getTypeRef().getId();
                    RVMMethod target = Entrypoints.unresolvedNewScalarMethod;
                    IntConstantOperand site = IRTools.IC(MemoryManager.getAllocationSite(true));
                    Call.mutate2(inst, CALL, New.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), IRTools.IC(typeRefId), site);
                }
                break;
            case NEWARRAY_opcode:
                {
                    TypeOperand Array = NewArray.getClearType(inst);
                    RVMArray array = (RVMArray) Array.getVMType();
                    Operand numberElements = NewArray.getClearSize(inst);
                    boolean inline = numberElements instanceof IntConstantOperand;
                    Operand width = IRTools.IC(array.getLogElementSize());
                    Operand headerSize = IRTools.IC(ObjectModel.computeArrayHeaderSize(array));
                    RVMMethod callSite = inst.position().getMethod();
                    IntConstantOperand allocator = IRTools.IC(MemoryManager.pickAllocator(array, callSite));
                    IntConstantOperand align = IRTools.IC(ObjectModel.getAlignment(array));
                    IntConstantOperand offset = IRTools.IC(ObjectModel.getOffsetForAlignment(array, false));
                    Operand tib = ConvertToLowLevelIR.getTIB(inst, ir, Array);
                    if (VM.BuildForIA32 && VM.runningVM) {
                        // shield BC2IR from address constants
                        RegisterOperand tmp = ir.regpool.makeTemp(TypeReference.TIB);
                        inst.insertBefore(Move.create(REF_MOVE, tmp, tib));
                        tib = tmp.copyRO();
                    }
                    IntConstantOperand site = IRTools.IC(MemoryManager.getAllocationSite(true));
                    RVMMethod target = Entrypoints.resolvedNewArrayMethod;
                    Call.mutate8(inst, CALL, NewArray.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), numberElements, width, headerSize, tib, allocator, align, offset, site);
                    next = inst.prevInstructionInCodeOrder();
                    if (inline && ir.options.H2L_INLINE_NEW) {
                        if (inst.getBasicBlock().getInfrequent())
                            container.counter1++;
                        container.counter2++;
                        if (!ir.options.FREQ_FOCUS_EFFORT || !inst.getBasicBlock().getInfrequent()) {
                            inline(inst, ir);
                        }
                    }
                }
                break;
            case NEWARRAY_UNRESOLVED_opcode:
                {
                    int typeRefId = NewArray.getType(inst).getTypeRef().getId();
                    Operand numberElements = NewArray.getClearSize(inst);
                    RVMMethod target = Entrypoints.unresolvedNewArrayMethod;
                    IntConstantOperand site = IRTools.IC(MemoryManager.getAllocationSite(true));
                    Call.mutate3(inst, CALL, NewArray.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), numberElements, IRTools.IC(typeRefId), site);
                }
                break;
            case NEWOBJMULTIARRAY_opcode:
                {
                    int dimensions = Multianewarray.getNumberOfDimensions(inst);
                    RVMMethod callSite = inst.position().getMethod();
                    int typeRefId = Multianewarray.getType(inst).getTypeRef().getId();
                    if (dimensions == 2) {
                        RVMMethod target = Entrypoints.optNew2DArrayMethod;
                        Call.mutate4(inst, CALL, Multianewarray.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), IRTools.IC(callSite.getId()), Multianewarray.getClearDimension(inst, 0), Multianewarray.getClearDimension(inst, 1), IRTools.IC(typeRefId));
                    } else {
                        // Step 1: Create an int array to hold the dimensions.
                        TypeOperand dimArrayType = new TypeOperand(RVMArray.IntArray);
                        RegisterOperand dimArray = ir.regpool.makeTemp(TypeReference.IntArray);
                        dimArray.setPreciseType();
                        next = NewArray.create(NEWARRAY, dimArray, dimArrayType, new IntConstantOperand(dimensions));
                        inst.insertBefore(next);
                        // Step 2: Assign the dimension values to dimArray
                        for (int i = 0; i < dimensions; i++) {
                            LocationOperand loc = new LocationOperand(TypeReference.Int);
                            inst.insertBefore(AStore.create(INT_ASTORE, Multianewarray.getClearDimension(inst, i), dimArray.copyD2U(), IRTools.IC(i), loc, IRTools.TG()));
                        }
                        // Step 3. Plant call to OptLinker.newArrayArray
                        RVMMethod target = Entrypoints.optNewArrayArrayMethod;
                        Call.mutate3(inst, CALL, Multianewarray.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), IRTools.IC(callSite.getId()), dimArray.copyD2U(), IRTools.IC(typeRefId));
                    }
                }
                break;
            case ATHROW_opcode:
                {
                    RVMMethod target = Entrypoints.athrowMethod;
                    MethodOperand methodOp = MethodOperand.STATIC(target);
                    // Record the fact that this is a non-returning call.
                    methodOp.setIsNonReturningCall(true);
                    Call.mutate1(inst, CALL, null, IRTools.AC(target.getOffset()), methodOp, Athrow.getClearValue(inst));
                }
                break;
            case MONITORENTER_opcode:
                {
                    Operand ref = MonitorOp.getClearRef(inst);
                    RVMType refType = ref.getType().peekType();
                    if (refType != null && !refType.getThinLockOffset().isMax()) {
                        RVMMethod target = Entrypoints.inlineLockMethod;
                        Call.mutate2(inst, CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), MonitorOp.getClearGuard(inst), ref, IRTools.AC(refType.getThinLockOffset()));
                        next = inst.prevInstructionInCodeOrder();
                        if (inst.getBasicBlock().getInfrequent())
                            container.counter1++;
                        container.counter2++;
                        if (!ir.options.FREQ_FOCUS_EFFORT || !inst.getBasicBlock().getInfrequent()) {
                            inline(inst, ir);
                        }
                    } else {
                        RVMMethod target = Entrypoints.lockMethod;
                        Call.mutate1(inst, CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), MonitorOp.getClearGuard(inst), ref);
                    }
                }
                break;
            case MONITOREXIT_opcode:
                {
                    Operand ref = MonitorOp.getClearRef(inst);
                    RVMType refType = ref.getType().peekType();
                    if (refType != null && !refType.getThinLockOffset().isMax()) {
                        RVMMethod target = Entrypoints.inlineUnlockMethod;
                        Call.mutate2(inst, CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), MonitorOp.getClearGuard(inst), ref, IRTools.AC(refType.getThinLockOffset()));
                        next = inst.prevInstructionInCodeOrder();
                        if (inst.getBasicBlock().getInfrequent())
                            container.counter1++;
                        container.counter2++;
                        if (!ir.options.FREQ_FOCUS_EFFORT || !inst.getBasicBlock().getInfrequent()) {
                            inline(inst, ir);
                        }
                    } else {
                        RVMMethod target = Entrypoints.unlockMethod;
                        Call.mutate1(inst, CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), MonitorOp.getClearGuard(inst), ref);
                    }
                }
                break;
            case REF_ASTORE_opcode:
                {
                    if (NEEDS_OBJECT_ASTORE_BARRIER) {
                        RVMMethod target = Entrypoints.objectArrayWriteBarrierMethod;
                        Instruction wb = Call.create3(CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), AStore.getClearGuard(inst), AStore.getArray(inst).copy(), AStore.getIndex(inst).copy(), AStore.getValue(inst).copy());
                        replaceInstructionWithBarrier(inst, wb);
                        if (ir.options.H2L_INLINE_WRITE_BARRIER) {
                            inline(wb, ir, true);
                        }
                    }
                }
                break;
            case BYTE_ASTORE_opcode:
                {
                    if (NEEDS_BYTE_ASTORE_BARRIER) {
                        primitiveArrayStoreHelper(Entrypoints.byteArrayWriteBarrierMethod, inst, ir);
                    }
                }
                break;
            case DOUBLE_ASTORE_opcode:
                {
                    if (NEEDS_DOUBLE_ASTORE_BARRIER) {
                        primitiveArrayStoreHelper(Entrypoints.doubleArrayWriteBarrierMethod, inst, ir);
                    }
                }
                break;
            case FLOAT_ASTORE_opcode:
                {
                    if (NEEDS_FLOAT_ASTORE_BARRIER) {
                        primitiveArrayStoreHelper(Entrypoints.floatArrayWriteBarrierMethod, inst, ir);
                    }
                }
                break;
            case INT_ASTORE_opcode:
                {
                    if (NEEDS_INT_ASTORE_BARRIER) {
                        primitiveArrayStoreHelper(Entrypoints.intArrayWriteBarrierMethod, inst, ir);
                    }
                }
                break;
            case LONG_ASTORE_opcode:
                {
                    if (NEEDS_LONG_ASTORE_BARRIER) {
                        primitiveArrayStoreHelper(Entrypoints.longArrayWriteBarrierMethod, inst, ir);
                    }
                }
                break;
            case SHORT_ASTORE_opcode:
                {
                    TypeReference type = AStore.getLocation(inst).getElementType();
                    if (NEEDS_SHORT_ASTORE_BARRIER && type.isShortType()) {
                        primitiveArrayStoreHelper(Entrypoints.shortArrayWriteBarrierMethod, inst, ir);
                    } else if (NEEDS_CHAR_ASTORE_BARRIER) {
                        if (VM.VerifyAssertions)
                            VM._assert(type.isCharType());
                        primitiveArrayStoreHelper(Entrypoints.charArrayWriteBarrierMethod, inst, ir);
                    }
                }
                break;
            case REF_ALOAD_opcode:
                {
                    if (NEEDS_OBJECT_ALOAD_BARRIER) {
                        RVMMethod target = Entrypoints.objectArrayReadBarrierMethod;
                        Instruction rb = Call.create2(CALL, ALoad.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), ALoad.getClearGuard(inst), ALoad.getArray(inst).copy(), ALoad.getIndex(inst).copy());
                        replaceInstructionWithBarrier(inst, rb);
                        inline(rb, ir, true);
                    }
                }
                break;
            case PUTFIELD_opcode:
                {
                    if (NEEDS_OBJECT_PUTFIELD_BARRIER) {
                        LocationOperand loc = PutField.getLocation(inst);
                        FieldReference fieldRef = loc.getFieldRef();
                        if (!fieldRef.getFieldContentsType().isPrimitiveType()) {
                            // reference PUTFIELD
                            RVMField field = fieldRef.peekResolvedField();
                            if (field == null || !field.isUntraced()) {
                                RVMMethod target = Entrypoints.objectFieldWriteBarrierMethod;
                                Instruction wb = Call.create4(CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), PutField.getClearGuard(inst), PutField.getRef(inst).copy(), PutField.getValue(inst).copy(), PutField.getOffset(inst).copy(), IRTools.IC(fieldRef.getId()));
                                replaceInstructionWithBarrier(inst, wb);
                                if (ir.options.H2L_INLINE_WRITE_BARRIER) {
                                    inline(wb, ir, true);
                                }
                            }
                        } else {
                            // primitive PUTFIELD
                            if (NEEDS_BOOLEAN_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isBooleanType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.booleanFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_BYTE_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isByteType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.byteFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_CHAR_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isCharType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.charFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_DOUBLE_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isDoubleType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.doubleFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_FLOAT_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isFloatType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.floatFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_INT_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isIntType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.intFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_LONG_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isLongType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.longFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_SHORT_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isShortType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.shortFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_WORD_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isWordType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.wordFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_ADDRESS_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isAddressType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.addressFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_EXTENT_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isExtentType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.extentFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_OFFSET_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isOffsetType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.offsetFieldWriteBarrierMethod, inst, ir, fieldRef);
                            }
                        }
                    }
                }
                break;
            case GETFIELD_opcode:
                {
                    if (NEEDS_OBJECT_GETFIELD_BARRIER) {
                        LocationOperand loc = GetField.getLocation(inst);
                        FieldReference fieldRef = loc.getFieldRef();
                        if (GetField.getResult(inst).getType().isReferenceType()) {
                            RVMField field = fieldRef.peekResolvedField();
                            if (field == null || !field.isUntraced()) {
                                RVMMethod target = Entrypoints.objectFieldReadBarrierMethod;
                                Instruction rb = Call.create3(CALL, GetField.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), GetField.getClearGuard(inst), GetField.getRef(inst).copy(), GetField.getOffset(inst).copy(), IRTools.IC(fieldRef.getId()));
                                replaceInstructionWithBarrier(inst, rb);
                                inline(rb, ir, true);
                            }
                        }
                    }
                }
                break;
            case PUTSTATIC_opcode:
                {
                    if (NEEDS_OBJECT_PUTSTATIC_BARRIER) {
                        LocationOperand loc = PutStatic.getLocation(inst);
                        FieldReference field = loc.getFieldRef();
                        if (!field.getFieldContentsType().isPrimitiveType()) {
                            RVMMethod target = Entrypoints.objectStaticWriteBarrierMethod;
                            Instruction wb = Call.create3(CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), PutStatic.getValue(inst).copy(), PutStatic.getOffset(inst).copy(), IRTools.IC(field.getId()));
                            replaceInstructionWithBarrier(inst, wb);
                            if (ir.options.H2L_INLINE_WRITE_BARRIER) {
                                inline(wb, ir, true);
                            }
                        }
                    }
                }
                break;
            case GETSTATIC_opcode:
                {
                    if (NEEDS_OBJECT_GETSTATIC_BARRIER) {
                        LocationOperand loc = GetStatic.getLocation(inst);
                        FieldReference field = loc.getFieldRef();
                        if (!field.getFieldContentsType().isPrimitiveType()) {
                            RVMMethod target = Entrypoints.objectStaticReadBarrierMethod;
                            Instruction rb = Call.create2(CALL, GetStatic.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), GetStatic.getOffset(inst).copy(), IRTools.IC(field.getId()));
                            replaceInstructionWithBarrier(inst, rb);
                            inline(rb, ir, true);
                        }
                    }
                }
                break;
            default:
                break;
        }
    }
    // If we actually inlined anything, clean up the mess
    if (didSomething) {
        if (branchOpts == null) {
            branchOpts = new BranchOptimizations(-1, true, true);
        }
        branchOpts.perform(ir, true);
        if (_os == null) {
            _os = new Simple(1, false, false, false, false);
        }
        _os.perform(ir);
    }
    // signal that we do not intend to use the gc in other phases anymore.
    ir.getGc().close();
}
Also used : IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) FieldReference(org.jikesrvm.classloader.FieldReference) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) TypeOperand(org.jikesrvm.compilers.opt.ir.operand.TypeOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) RVMType(org.jikesrvm.classloader.RVMType) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) RVMClass(org.jikesrvm.classloader.RVMClass) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) Simple(org.jikesrvm.compilers.opt.Simple) RVMMethod(org.jikesrvm.classloader.RVMMethod) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) RVMArray(org.jikesrvm.classloader.RVMArray) TypeOperand(org.jikesrvm.compilers.opt.ir.operand.TypeOperand) RVMField(org.jikesrvm.classloader.RVMField) TypeReference(org.jikesrvm.classloader.TypeReference) BranchOptimizations(org.jikesrvm.compilers.opt.controlflow.BranchOptimizations)

Example 17 with LocationOperand

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

the class GenerateMagic method mapToMetadata.

private static LocationOperand mapToMetadata(Operand metadata) {
    if (metadata instanceof IntConstantOperand) {
        int index = ((IntConstantOperand) metadata).value;
        if (index == 0)
            return null;
        MemberReference mr = MemberReference.getMemberRef(index);
        return new LocationOperand(mr.asFieldReference());
    }
    return null;
}
Also used : LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) MemberReference(org.jikesrvm.classloader.MemberReference)

Example 18 with LocationOperand

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

the class GenerateMachineSpecificMagic 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 stack as necessary
 *
 * @param bc2ir the bc2ir object generating the ir containing this magic
 * @param gc == bc2ir.gc
 * @param meth the RVMMethod that is the magic method
 * @return {@code true} if and only if magic was generated
 */
public static boolean generateMagic(BC2IR bc2ir, GenerationContext gc, MethodReference meth) throws MagicNotImplementedException {
    Atom methodName = meth.getName();
    PhysicalRegisterSet phys = gc.getTemps().getPhysicalRegisterSet().asIA32();
    if (methodName == MagicNames.getESIAsThread) {
        RegisterOperand rop = gc.getTemps().makeTROp();
        bc2ir.markGuardlessNonNull(rop);
        bc2ir.push(rop);
    } else if (methodName == MagicNames.setESIAsThread) {
        Operand val = bc2ir.popRef();
        if (val instanceof RegisterOperand) {
            bc2ir.appendInstruction(Move.create(REF_MOVE, gc.getTemps().makeTROp(), val));
        } else {
            String msg = " Unexpected operand Magic.setESIAsThread";
            throw MagicNotImplementedException.UNEXPECTED(msg);
        }
    } else if (methodName == MagicNames.getFramePointer) {
        gc.forceFrameAllocation();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.Address);
        RVMField f = ArchEntrypoints.framePointerField;
        RegisterOperand pr = new RegisterOperand(phys.getESI(), TypeReference.Address);
        bc2ir.appendInstruction(GetField.create(GETFIELD, val, pr.copy(), new AddressConstantOperand(f.getOffset()), new LocationOperand(f), new TrueGuardOperand()));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.getJTOC || methodName == MagicNames.getTocPointer) {
        TypeReference t = (methodName == MagicNames.getJTOC ? TypeReference.IntArray : TypeReference.Address);
        RegisterOperand val = gc.getTemps().makeTemp(t);
        AddressConstantOperand addr = new AddressConstantOperand(Magic.getTocPointer());
        bc2ir.appendInstruction(Move.create(REF_MOVE, val, addr));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.synchronizeInstructionCache) {
    // nothing required on Intel
    } else if (methodName == MagicNames.prefetch) {
        bc2ir.appendInstruction(CacheOp.create(PREFETCH, bc2ir.popAddress()));
    } else if (methodName == MagicNames.pause) {
        bc2ir.appendInstruction(Empty.create(PAUSE));
    } else if (methodName == MagicNames.illegalInstruction) {
        bc2ir.appendInstruction(Empty.create(ILLEGAL_INSTRUCTION));
    } else if (methodName == MagicNames.getCallerFramePointer) {
        Operand fp = bc2ir.popAddress();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.Address);
        bc2ir.appendInstruction(Load.create(REF_LOAD, val, fp, offsetOperand(STACKFRAME_FRAME_POINTER_OFFSET), null));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.setCallerFramePointer) {
        Operand val = bc2ir.popAddress();
        Operand fp = bc2ir.popAddress();
        bc2ir.appendInstruction(Store.create(REF_STORE, val, fp, offsetOperand(STACKFRAME_FRAME_POINTER_OFFSET), null));
    } else if (methodName == MagicNames.getCompiledMethodID) {
        Operand fp = bc2ir.popAddress();
        RegisterOperand val = gc.getTemps().makeTempInt();
        bc2ir.appendInstruction(Load.create(INT_LOAD, val, fp, offsetOperand(STACKFRAME_METHOD_ID_OFFSET), null));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.setCompiledMethodID) {
        Operand val = bc2ir.popInt();
        Operand fp = bc2ir.popAddress();
        bc2ir.appendInstruction(Store.create(INT_STORE, val, fp, offsetOperand(STACKFRAME_METHOD_ID_OFFSET), null));
    } else if (methodName == MagicNames.getReturnAddressLocation) {
        Operand fp = bc2ir.popAddress();
        Instruction s = bc2ir._binaryHelper(REF_ADD, fp, offsetOperand(STACKFRAME_RETURN_ADDRESS_OFFSET), TypeReference.Address);
        bc2ir.appendInstruction(s);
    } else {
        // Distinguish between magics that we know we don't implement
        // (and never plan to implement) and those (usually new ones)
        // that we want to be warned that we don't implement.
        String msg = " Magic method not implemented: " + meth;
        if (methodName == MagicNames.returnToNewStack) {
            throw MagicNotImplementedException.EXPECTED(msg);
        } else {
            return false;
        // throw MagicNotImplementedException.UNEXPECTED(msg);
        }
    }
    return true;
}
Also used : LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) IRTools.offsetOperand(org.jikesrvm.compilers.opt.ir.IRTools.offsetOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) PhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet) RVMField(org.jikesrvm.classloader.RVMField) TypeReference(org.jikesrvm.classloader.TypeReference) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) Atom(org.jikesrvm.classloader.Atom) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)

Example 19 with LocationOperand

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

the class ComplexLIR2MIRExpansion method double_2long.

private static Instruction double_2long(Instruction s, IR ir) {
    Instruction nextInstr = s.nextInstructionInCodeOrder();
    while (Label.conforms(nextInstr) || BBend.conforms(nextInstr)) {
        nextInstr = nextInstr.nextInstructionInCodeOrder();
    }
    // we need 6 basic blocks (in code order)
    // 1: the current block that does a test to see if this is a regular f2l or
    // branches to the maxint/NaN case
    // 2: a block to perform a regular f2l
    // 3: a block to test for NaN
    // 4: a block to perform give maxint
    // 5: a block to perform NaN
    // 6: the next basic block
    BasicBlock testBB = s.getBasicBlock();
    BasicBlock nextBB = testBB.splitNodeAt(s, ir);
    ir.cfg.linkInCodeOrder(testBB, nextBB);
    BasicBlock nanBB = testBB.splitNodeAt(s, ir);
    ir.cfg.linkInCodeOrder(testBB, nanBB);
    BasicBlock maxintBB = testBB.splitNodeAt(s, ir);
    ir.cfg.linkInCodeOrder(testBB, maxintBB);
    BasicBlock nanTestBB = testBB.splitNodeAt(s, ir);
    ir.cfg.linkInCodeOrder(testBB, nanTestBB);
    BasicBlock d2lBB = testBB.splitNodeAt(s, ir);
    ir.cfg.linkInCodeOrder(testBB, d2lBB);
    // branch if they are <= or unordered.
    if (VM.BuildFor32Addr) {
        RegisterOperand resultHi = Unary.getResult(s).copyRO();
        resultHi.setType(TypeReference.Int);
        RegisterOperand resultLo = new RegisterOperand(ir.regpool.getSecondReg(resultHi.getRegister()), TypeReference.Int);
        RegisterOperand value = Unary.getVal(s).asRegister().copyRO();
        RegisterOperand cw = ir.regpool.makeTempInt();
        MemoryOperand maxlong = BURS_Helpers.loadFromJTOC(ir, Entrypoints.maxlongField.getOffset(), (byte) 8);
        RegisterOperand st0 = new RegisterOperand(phys(ir).getST0(), TypeReference.Double);
        RegisterOperand st1 = new RegisterOperand(phys(ir).getST1(), TypeReference.Double);
        int offset = -ir.stackManager.allocateSpaceForConversion();
        StackLocationOperand slLo = new StackLocationOperand(true, offset, 4);
        StackLocationOperand slHi = new StackLocationOperand(true, offset + 4, 4);
        StackLocationOperand sl = new StackLocationOperand(true, offset, 8);
        MemoryOperand scratchLo = new MemoryOperand(ir.regpool.makeTROp(), null, (byte) 0, Entrypoints.scratchStorageField.getOffset(), (byte) 4, new LocationOperand(Entrypoints.scratchStorageField), null);
        MemoryOperand scratchHi = new MemoryOperand(ir.regpool.makeTROp(), null, (byte) 0, Entrypoints.scratchStorageField.getOffset().plus(4), (byte) 4, new LocationOperand(Entrypoints.scratchStorageField), null);
        s.insertBefore(CPOS(s, MIR_Move.create(IA32_MOVSD, sl, value)));
        s.insertBefore(CPOS(s, MIR_Move.create(IA32_FLD, st0, sl.copy())));
        s.insertBefore(CPOS(s, MIR_Move.create(IA32_FLD, st0.copyRO(), maxlong)));
        MIR_Compare.mutate(s, IA32_FUCOMIP, st0.copyRO(), st1);
        testBB.appendInstruction(CPOS(s, MIR_CondBranch.create(IA32_JCC, IA32ConditionOperand.LLE(), nanTestBB.makeJumpTarget(), BranchProfileOperand.unlikely())));
        testBB.insertOut(d2lBB);
        testBB.insertOut(nanTestBB);
        // Convert double to long knowing that if the value is < min long the Intel
        // unspecified result is min long
        // TODO: this would be a lot simpler and faster with SSE3's FISTTP instruction
        d2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FNSTCW, scratchLo.copy())));
        d2lBB.appendInstruction(CPOS(s, MIR_Unary.create(IA32_MOVZX__W, cw, scratchLo.copy())));
        d2lBB.appendInstruction(CPOS(s, MIR_BinaryAcc.create(IA32_OR, cw.copyRO(), IC(0xC00))));
        d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, scratchHi, cw.copyRO())));
        d2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FLDCW, scratchHi.copy())));
        d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_FISTP, sl.copy(), st0.copyRO())));
        d2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FLDCW, scratchLo.copy())));
        d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultLo, slLo)));
        d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultHi, slHi)));
        d2lBB.appendInstruction(CPOS(s, MIR_Branch.create(IA32_JMP, nextBB.makeJumpTarget())));
        d2lBB.insertOut(nextBB);
        // Did the compare find a NaN or a maximum integer?
        nanTestBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_FSTP, st0.copyRO(), st0.copyRO())));
        nanTestBB.appendInstruction(CPOS(s, MIR_CondBranch.create(IA32_JCC, IA32ConditionOperand.PE(), nanBB.makeJumpTarget(), BranchProfileOperand.unlikely())));
        nanTestBB.insertOut(nanBB);
        nanTestBB.insertOut(maxintBB);
        // Value was >= max long
        maxintBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultLo.copyRO(), IC((int) Long.MAX_VALUE))));
        maxintBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultHi.copyRO(), IC((int) (Long.MAX_VALUE >>> 32)))));
        maxintBB.appendInstruction(CPOS(s, MIR_Branch.create(IA32_JMP, nextBB.makeJumpTarget())));
        maxintBB.insertOut(nextBB);
        // In case of NaN result is 0
        nanBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultLo.copyRO(), IC(0))));
        nanBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultHi.copyRO(), IC(0))));
        nanBB.insertOut(nextBB);
        return nextInstr;
    } else {
        RegisterOperand result = Unary.getResult(s).copyRO();
        RegisterOperand value = Unary.getVal(s).asRegister().copyRO();
        RegisterOperand cw = ir.regpool.makeTempInt();
        MemoryOperand maxlong = BURS_Helpers.loadFromJTOC(ir, Entrypoints.maxlongField.getOffset(), (byte) 8);
        RegisterOperand st0 = new RegisterOperand(phys(ir).getST0(), TypeReference.Double);
        RegisterOperand st1 = new RegisterOperand(phys(ir).getST1(), TypeReference.Double);
        int offset = -ir.stackManager.allocateSpaceForConversion();
        StackLocationOperand sl = new StackLocationOperand(true, offset, 8);
        MemoryOperand scratchLo = new MemoryOperand(ir.regpool.makeTROp(), null, (byte) 0, Entrypoints.scratchStorageField.getOffset(), (byte) 4, new LocationOperand(Entrypoints.scratchStorageField), null);
        MemoryOperand scratchHi = new MemoryOperand(ir.regpool.makeTROp(), null, (byte) 0, Entrypoints.scratchStorageField.getOffset().plus(4), (byte) 4, new LocationOperand(Entrypoints.scratchStorageField), null);
        s.insertBefore(CPOS(s, MIR_Move.create(IA32_MOVSD, sl, value)));
        s.insertBefore(CPOS(s, MIR_Move.create(IA32_FLD, st0, sl.copy())));
        s.insertBefore(CPOS(s, MIR_Move.create(IA32_FLD, st0.copyRO(), maxlong)));
        MIR_Compare.mutate(s, IA32_FUCOMIP, st0.copyRO(), st1);
        testBB.appendInstruction(CPOS(s, MIR_CondBranch.create(IA32_JCC, IA32ConditionOperand.LLE(), nanTestBB.makeJumpTarget(), BranchProfileOperand.unlikely())));
        testBB.insertOut(d2lBB);
        testBB.insertOut(nanTestBB);
        // Convert double to long knowing that if the value is < min long the Intel
        // unspecified result is min long
        // TODO: this would be a lot simpler and faster with SSE3's FISTTP instruction
        d2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FNSTCW, scratchLo.copy())));
        d2lBB.appendInstruction(CPOS(s, MIR_Unary.create(IA32_MOVZX__W, cw, scratchLo.copy())));
        d2lBB.appendInstruction(CPOS(s, MIR_BinaryAcc.create(IA32_OR, cw.copyRO(), IC(0xC00))));
        d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, scratchHi, cw.copyRO())));
        d2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FLDCW, scratchHi.copy())));
        d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_FISTP, sl.copy(), st0.copyRO())));
        d2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FLDCW, scratchLo.copy())));
        d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, result, sl.copy())));
        d2lBB.appendInstruction(CPOS(s, MIR_Branch.create(IA32_JMP, nextBB.makeJumpTarget())));
        d2lBB.insertOut(nextBB);
        // Did the compare find a NaN or a maximum integer?
        nanTestBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_FSTP, st0.copyRO(), st0.copyRO())));
        nanTestBB.appendInstruction(CPOS(s, MIR_CondBranch.create(IA32_JCC, IA32ConditionOperand.PE(), nanBB.makeJumpTarget(), BranchProfileOperand.unlikely())));
        nanTestBB.insertOut(nanBB);
        nanTestBB.insertOut(maxintBB);
        // Value was >= max long
        maxintBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, result.copyRO(), LC(Long.MAX_VALUE))));
        maxintBB.appendInstruction(CPOS(s, MIR_Branch.create(IA32_JMP, nextBB.makeJumpTarget())));
        maxintBB.insertOut(nextBB);
        // In case of NaN result is 0
        nanBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, result.copyRO(), LC(0))));
        nanBB.insertOut(nextBB);
        return nextInstr;
    }
}
Also used : StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)

Example 20 with LocationOperand

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

the class BURS_Helpers method SET_EXCEPTION_OBJECT.

/**
 * Emit code to move a value in a register to the stack location
 * where a caught exception object is expected to be.
 */
protected final void SET_EXCEPTION_OBJECT(Instruction s) {
    burs.ir.stackManager.forceFrameAllocation();
    int offset = burs.ir.stackManager.allocateSpaceForCaughtException();
    Register FP = regpool.getPhysicalRegisterSet().asPPC().getFP();
    LocationOperand loc = new LocationOperand(-offset);
    RegisterOperand obj = (RegisterOperand) CacheOp.getRef(s);
    EMIT(MIR_Store.mutate(s, PPC_STAddr, obj, A(FP), IC(offset), loc, TG()));
}
Also used : LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) OsrPoint(org.jikesrvm.compilers.opt.ir.OsrPoint)

Aggregations

LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)38 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)28 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)23 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)22 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)20 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)16 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)14 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)14 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)13 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)11 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)10 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)8 MemoryOperand (org.jikesrvm.compilers.opt.ir.operand.MemoryOperand)8 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)8 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)7 FieldReference (org.jikesrvm.classloader.FieldReference)6 RVMClass (org.jikesrvm.classloader.RVMClass)6 TypeReference (org.jikesrvm.classloader.TypeReference)6 TIBConstantOperand (org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand)6 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)6