Search in sources :

Example 31 with OptimizingCompilerException

use of org.jikesrvm.compilers.opt.OptimizingCompilerException 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 32 with OptimizingCompilerException

use of org.jikesrvm.compilers.opt.OptimizingCompilerException in project JikesRVM by JikesRVM.

the class BC2IR method _refIfCmpHelper.

// helper function for if_acmp?? bytecodes
private Instruction _refIfCmpHelper(ConditionOperand cond) {
    if (VM.VerifyAssertions)
        opt_assert(cond.isEQUAL() || cond.isNOT_EQUAL());
    int offset = bcodes.getBranchOffset();
    Operand op1 = popRef();
    Operand op0 = popRef();
    if (offset == 3) {
        // remove frivolous REF_IFCMPs
        return null;
    }
    if (!(op0 instanceof RegisterOperand)) {
        // swap operands
        Operand temp = op0;
        op0 = op1;
        op1 = temp;
        cond = cond.flipOperands();
    }
    if (CF_REFIFCMP && op0.isDefinitelyNull() && op1.isDefinitelyNull()) {
        if (cond.isEQUAL()) {
            if (DBG_CF) {
                db(cond + ": changed branch to goto because predicate is true");
            }
            return _gotoHelper(offset);
        } else {
            if (DBG_CF) {
                db(cond + ": eliminated branch because predicate is false");
            }
            return null;
        }
    }
    // Check for incorrect comparison operators on unboxed types
    if (op0.isRegister()) {
        RegisterOperand op0Reg = op0.asRegister();
        if (op0Reg.getType().isUnboxedType()) {
            throw new OptimizingCompilerException("Detected incorrect comparison of unboxed types in " + gc.getMethod() + " at bytecode index " + instrIndex + " from class " + gc.getMethod().getDeclaringClass() + " . Use the methods provided on the unboxed types to do comparisons!");
        }
    }
    if (op1.isRegister()) {
        RegisterOperand op1Reg = op1.asRegister();
        if (op1Reg.getType().isUnboxedType()) {
            throw new OptimizingCompilerException("Detected incorrect comparison of unboxed types in " + gc.getMethod() + " at bytecode index " + instrIndex + " from class " + gc.getMethod().getDeclaringClass() + " . Use the methods provided on the unboxed types to do comparisons!");
        }
    }
    fallThrough = true;
    RegisterOperand guard = gc.getTemps().makeTempValidation();
    return IfCmp.create(REF_IFCMP, guard, op0, op1, cond, generateTarget(offset), gc.getConditionalBranchProfileOperand(instrIndex - bciAdjustment, offset < 0));
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) TypeOperand(org.jikesrvm.compilers.opt.ir.operand.TypeOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) OsrTypeInfoOperand(org.jikesrvm.compilers.opt.ir.operand.OsrTypeInfoOperand) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) 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) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) 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) OsrPoint(org.jikesrvm.compilers.opt.ir.OsrPoint)

Example 33 with OptimizingCompilerException

use of org.jikesrvm.compilers.opt.OptimizingCompilerException 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 34 with OptimizingCompilerException

use of org.jikesrvm.compilers.opt.OptimizingCompilerException 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)

Example 35 with OptimizingCompilerException

use of org.jikesrvm.compilers.opt.OptimizingCompilerException in project JikesRVM by JikesRVM.

the class BURS_Helpers method TRAP.

// Take the generic LIR trap and coerce into the limited vocabulary
// understand by C trap handler on PPC.  See TrapConstants.java.
protected final void TRAP(Instruction s) {
    RegisterOperand gRes = Trap.getClearGuardResult(s);
    TrapCodeOperand tc = Trap.getClearTCode(s);
    switch(tc.getTrapCode()) {
        case RuntimeEntrypoints.TRAP_NULL_POINTER:
            {
                RVMMethod target = Entrypoints.raiseNullPointerException;
                mutateTrapToCall(s, target);
            }
            break;
        case RuntimeEntrypoints.TRAP_ARRAY_BOUNDS:
            {
                RVMMethod target = Entrypoints.raiseArrayBoundsException;
                mutateTrapToCall(s, target);
            }
            break;
        case RuntimeEntrypoints.TRAP_DIVIDE_BY_ZERO:
            {
                RVMMethod target = Entrypoints.raiseArithmeticException;
                mutateTrapToCall(s, target);
            }
            break;
        case RuntimeEntrypoints.TRAP_CHECKCAST:
            {
                EMIT(MIR_Trap.mutate(s, PPC_TWI, gRes, PowerPCTrapOperand.ALWAYS(), I(12), IC(CHECKCAST_TRAP & 0xffff), tc));
            }
            break;
        case RuntimeEntrypoints.TRAP_MUST_IMPLEMENT:
            {
                EMIT(MIR_Trap.mutate(s, PPC_TWI, gRes, PowerPCTrapOperand.ALWAYS(), I(12), IC(MUST_IMPLEMENT_TRAP & 0xffff), tc));
            }
            break;
        case RuntimeEntrypoints.TRAP_STORE_CHECK:
            {
                EMIT(MIR_Trap.mutate(s, PPC_TWI, gRes, PowerPCTrapOperand.ALWAYS(), I(12), IC(STORE_CHECK_TRAP & 0xffff), tc));
            }
            break;
        default:
            throw new OptimizingCompilerException("Unexpected case of trap_if" + s);
    }
}
Also used : RVMMethod(org.jikesrvm.classloader.RVMMethod) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException)

Aggregations

OptimizingCompilerException (org.jikesrvm.compilers.opt.OptimizingCompilerException)47 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)25 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)18 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)17 Register (org.jikesrvm.compilers.opt.ir.Register)16 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)14 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)11 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)11 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)11 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)10 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)10 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)9 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)9 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)9 TypeReference (org.jikesrvm.classloader.TypeReference)8 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)8 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)8 DoubleConstantOperand (org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand)6 FloatConstantOperand (org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand)6 Offset (org.vmmagic.unboxed.Offset)6