Search in sources :

Example 61 with ForwardReference

use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method emit_regular_DFcmpGL.

@Override
protected void emit_regular_DFcmpGL(boolean single, boolean unorderedGT) {
    if (SSE2_BASE) {
        if (single) {
            // XMM0 = value2
            asm.emitMOVSS_Reg_RegInd(XMM0, SP);
            // XMM1 = value1
            asm.emitMOVSS_Reg_RegDisp(XMM1, SP, ONE_SLOT);
            // throw away slots
            adjustStack(WORDSIZE * 2, true);
        } else {
            // XMM0 = value2
            asm.emitMOVSD_Reg_RegInd(XMM0, SP);
            // XMM1 = value1
            asm.emitMOVSD_Reg_RegDisp(XMM1, SP, TWO_SLOTS);
            // throw away slots
            adjustStack(WORDSIZE * 4, true);
        }
    } else {
        if (single) {
            // Setup value2 into FP1,
            asm.emitFLD_Reg_RegInd(FP0, SP);
            // value1 into FP0
            asm.emitFLD_Reg_RegDisp(FP0, SP, ONE_SLOT);
            // throw away slots
            adjustStack(WORDSIZE * 2, true);
        } else {
            // Setup value2 into FP1,
            asm.emitFLD_Reg_RegInd_Quad(FP0, SP);
            // value1 into FP0
            asm.emitFLD_Reg_RegDisp_Quad(FP0, SP, TWO_SLOTS);
            // throw away slots
            adjustStack(WORDSIZE * 4, true);
        }
    }
    if (unorderedGT) {
        // result/T0 = 1 (high bits are 0)
        asm.emitMOV_Reg_Imm(T0, 1);
    } else {
        // clear high bits of result
        asm.emitXOR_Reg_Reg(T0, T0);
    }
    if (SSE2_BASE) {
        if (single) {
            // compare value1 and value2
            asm.emitUCOMISS_Reg_Reg(XMM1, XMM0);
        } else {
            // compare value1 and value2
            asm.emitUCOMISD_Reg_Reg(XMM1, XMM0);
        }
    } else {
        // compare and pop FPU *1
        asm.emitFUCOMIP_Reg_Reg(FP0, FP1);
    }
    ForwardReference fr1 = null;
    if (unorderedGT) {
        // if unordered goto push result (1)
        fr1 = asm.forwardJcc(PE);
    }
    // T0 = XMM0 > XMM1 ? 1 : 0
    asm.emitSET_Cond_Reg_Byte(LGT, T0);
    // T0 -= XMM0 < or unordered XMM1 ? 1 : 0
    asm.emitSBB_Reg_Imm(T0, 0);
    if (unorderedGT) {
        fr1.resolve(asm);
    }
    // push result on stack
    asm.emitPUSH_Reg(T0);
    if (!SSE2_BASE) {
        // pop FPU*1
        asm.emitFSTP_Reg_Reg(FP0, FP0);
    }
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference)

Example 62 with ForwardReference

use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method emit_lushr.

@Override
protected void emit_lushr() {
    if (VM.BuildFor32Addr) {
        if (SSE2_BASE) {
            // shift amount (6 bits)
            asm.emitPOP_Reg(T0);
            // XMM1 <- [SP]
            asm.emitMOVQ_Reg_RegInd(XMM1, SP);
            // mask to 6bits
            asm.emitAND_Reg_Imm(T0, 0x3F);
            // XMM0 <- T0
            asm.emitMOVD_Reg_Reg(XMM0, T0);
            // XMM1 >>>= XMM0
            asm.emitPSRLQ_Reg_Reg(XMM1, XMM0);
            // [SP] <- XMM1
            asm.emitMOVQ_RegInd_Reg(SP, XMM1);
        } else {
            // ECX is constrained to be the shift count
            if (VM.VerifyAssertions)
                VM._assert(ECX != T0);
            if (VM.VerifyAssertions)
                VM._assert(ECX != T1);
            // shift amount (6 bits)
            asm.emitPOP_Reg(ECX);
            // pop low half
            asm.emitPOP_Reg(T0);
            // pop high half
            asm.emitPOP_Reg(T1);
            asm.emitAND_Reg_Imm(ECX, 0x3F);
            asm.emitCMP_Reg_Imm(ECX, 32);
            ForwardReference fr1 = asm.forwardJcc(LT);
            // low half = high half
            asm.emitMOV_Reg_Reg(T0, T1);
            // high half = 0
            asm.emitXOR_Reg_Reg(T1, T1);
            fr1.resolve(asm);
            // shift low half, filling from high
            asm.emitSHRD_Reg_Reg_Reg(T0, T1, ECX);
            // shift high half
            asm.emitSHR_Reg_Reg(T1, ECX);
            // push high half
            asm.emitPUSH_Reg(T1);
            // push low half
            asm.emitPUSH_Reg(T0);
        }
    } else {
        asm.emitPOP_Reg(ECX);
        asm.emitSHR_RegInd_Reg_Quad(SP, ECX);
    }
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference)

Example 63 with ForwardReference

use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method genNullCheck.

/**
 * Generate an explicit null check (compare to zero).
 *
 * @param asm the assembler to generate into
 * @param objRefReg the register containing the reference
 */
@Inline
private static void genNullCheck(Assembler asm, GPR objRefReg) {
    // compare to zero
    asm.emitTEST_Reg_Reg(objRefReg, objRefReg);
    // Jmp around trap if index is OK
    asm.emitBranchLikelyNextInstruction();
    ForwardReference fr = asm.forwardJcc(NE);
    // trap
    asm.emitINT_Imm(RuntimeEntrypoints.TRAP_NULL_POINTER + RVM_TRAP_BASE);
    fr.resolve(asm);
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference) Inline(org.vmmagic.pragma.Inline)

Example 64 with ForwardReference

use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method emit_checkcast_resolvedInterface.

@Override
protected void emit_checkcast_resolvedInterface(RVMClass type) {
    int interfaceIndex = type.getDoesImplementIndex();
    int interfaceMask = type.getDoesImplementBitMask();
    if (VM.BuildFor32Addr) {
        // load object from stack into ECX
        asm.emitMOV_Reg_RegInd(ECX, SP);
    } else {
        // load object from stack into ECX
        asm.emitMOV_Reg_RegInd_Quad(ECX, SP);
    }
    // forward branch if ECX == 0
    ForwardReference isNull = asm.forwardJECXZ();
    // S0 = TIB of object
    asm.baselineEmitLoadTIB(S0, ECX);
    // S0 = implements bit vector
    if (VM.BuildFor32Addr) {
        asm.emitMOV_Reg_RegDisp(S0, S0, Offset.fromIntZeroExtend(TIB_DOES_IMPLEMENT_INDEX << LG_WORDSIZE));
    } else {
        asm.emitMOV_Reg_RegDisp_Quad(S0, S0, Offset.fromIntZeroExtend(TIB_DOES_IMPLEMENT_INDEX << LG_WORDSIZE));
    }
    if (DynamicTypeCheck.MIN_DOES_IMPLEMENT_SIZE <= interfaceIndex) {
        // must do arraybounds check of implements bit vector
        if (ARRAY_LENGTH_BYTES == 4) {
            asm.emitCMP_RegDisp_Imm(S0, ObjectModel.getArrayLengthOffset(), interfaceIndex);
        } else {
            asm.emitCMP_RegDisp_Imm_Quad(S0, ObjectModel.getArrayLengthOffset(), interfaceIndex);
        }
        asm.emitBranchLikelyNextInstruction();
        ForwardReference fr = asm.forwardJcc(LGT);
        asm.emitINT_Imm(RuntimeEntrypoints.TRAP_CHECKCAST + RVM_TRAP_BASE);
        fr.resolve(asm);
    }
    // Test the appropriate bit and if set, branch around another trap imm
    asm.emitTEST_RegDisp_Imm(S0, Offset.fromIntZeroExtend(interfaceIndex << LOG_BYTES_IN_INT), interfaceMask);
    asm.emitBranchLikelyNextInstruction();
    ForwardReference fr = asm.forwardJcc(NE);
    asm.emitINT_Imm(RuntimeEntrypoints.TRAP_CHECKCAST + RVM_TRAP_BASE);
    fr.resolve(asm);
    isNull.resolve(asm);
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference)

Example 65 with ForwardReference

use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method emit_invokeinterface.

@Override
protected void emit_invokeinterface(MethodReference methodRef) {
    // +1 for "this" parameter
    final int count = methodRef.getParameterWords() + 1;
    RVMMethod resolvedMethod = null;
    resolvedMethod = methodRef.peekInterfaceMethod();
    // (1) Emit dynamic type checking sequence if required to do so inline.
    if (VM.BuildForIMTInterfaceInvocation) {
        if (methodRef.isMiranda()) {
        // TODO: It's not entirely clear that we can just assume that
        // the class actually implements the interface.
        // However, we don't know what interface we need to be checking
        // so there doesn't appear to be much else we can do here.
        } else {
            if (resolvedMethod == null) {
                // Can't successfully resolve it at compile time.
                // Call uncommon case typechecking routine to do the right thing when this code actually executes.
                // T1 = "this" object
                stackMoveHelper(T1, Offset.fromIntZeroExtend((count - 1) << LG_WORDSIZE));
                // push dict id of target
                asm.emitPUSH_Imm(methodRef.getId());
                // push "this"
                asm.emitPUSH_Reg(T1);
                // pass 2 parameter word
                genParameterRegisterLoad(asm, 2);
                // check that "this" class implements the interface
                asm.generateJTOCcall(Entrypoints.unresolvedInvokeinterfaceImplementsTestMethod.getOffset());
            } else {
                RVMClass interfaceClass = resolvedMethod.getDeclaringClass();
                int interfaceIndex = interfaceClass.getDoesImplementIndex();
                int interfaceMask = interfaceClass.getDoesImplementBitMask();
                // T1 = "this" object
                stackMoveHelper(T1, Offset.fromIntZeroExtend((count - 1) << LG_WORDSIZE));
                // S0 = tib of "this" object
                asm.baselineEmitLoadTIB(S0, T1);
                if (VM.BuildFor32Addr) {
                    // implements bit vector
                    asm.emitMOV_Reg_RegDisp(S0, S0, Offset.fromIntZeroExtend(TIB_DOES_IMPLEMENT_INDEX << LG_WORDSIZE));
                } else {
                    // implements bit vector
                    asm.emitMOV_Reg_RegDisp_Quad(S0, S0, Offset.fromIntZeroExtend(TIB_DOES_IMPLEMENT_INDEX << LG_WORDSIZE));
                }
                if (DynamicTypeCheck.MIN_DOES_IMPLEMENT_SIZE <= interfaceIndex) {
                    // must do arraybounds check of implements bit vector
                    if (ARRAY_LENGTH_BYTES == 4) {
                        asm.emitCMP_RegDisp_Imm(S0, ObjectModel.getArrayLengthOffset(), interfaceIndex);
                    } else {
                        asm.emitCMP_RegDisp_Imm_Quad(S0, ObjectModel.getArrayLengthOffset(), interfaceIndex);
                    }
                    asm.emitBranchLikelyNextInstruction();
                    ForwardReference fr = asm.forwardJcc(LGT);
                    asm.emitINT_Imm(RuntimeEntrypoints.TRAP_MUST_IMPLEMENT + RVM_TRAP_BASE);
                    fr.resolve(asm);
                }
                // Test the appropriate bit and if set, branch around another trap imm
                if (interfaceIndex == 0) {
                    asm.emitTEST_RegInd_Imm(S0, interfaceMask);
                } else {
                    asm.emitTEST_RegDisp_Imm(S0, Offset.fromIntZeroExtend(interfaceIndex << LOG_BYTES_IN_INT), interfaceMask);
                }
                asm.emitBranchLikelyNextInstruction();
                ForwardReference fr = asm.forwardJcc(NE);
                asm.emitINT_Imm(RuntimeEntrypoints.TRAP_MUST_IMPLEMENT + RVM_TRAP_BASE);
                fr.resolve(asm);
            }
        }
    }
    // (2) Emit interface invocation sequence.
    if (VM.BuildForIMTInterfaceInvocation) {
        InterfaceMethodSignature sig = InterfaceMethodSignature.findOrCreate(methodRef);
        // squirrel away signature ID
        Offset offset = ArchEntrypoints.hiddenSignatureIdField.getOffset();
        asm.emitMOV_RegDisp_Imm(THREAD_REGISTER, offset, sig.getId());
        // T1 = "this" object
        stackMoveHelper(T1, Offset.fromIntZeroExtend((count - 1) << LG_WORDSIZE));
        asm.baselineEmitLoadTIB(S0, T1);
        // Load the IMT Base into S0
        if (VM.BuildFor32Addr) {
            asm.emitMOV_Reg_RegDisp(S0, S0, Offset.fromIntZeroExtend(TIB_INTERFACE_DISPATCH_TABLE_INDEX << LG_WORDSIZE));
        } else {
            asm.emitMOV_Reg_RegDisp_Quad(S0, S0, Offset.fromIntZeroExtend(TIB_INTERFACE_DISPATCH_TABLE_INDEX << LG_WORDSIZE));
        }
        genParameterRegisterLoad(methodRef, true);
        // the interface call
        asm.emitCALL_RegDisp(S0, sig.getIMTOffset());
    } else {
        int itableIndex = -1;
        if (VM.BuildForITableInterfaceInvocation && resolvedMethod != null) {
            // get the index of the method in the Itable
            itableIndex = InterfaceInvocation.getITableIndex(resolvedMethod.getDeclaringClass(), methodRef.getName(), methodRef.getDescriptor());
        }
        if (itableIndex == -1) {
            // itable index is not known at compile-time.
            // call "invokeInterface" to resolve object + method id into
            // method address
            int methodRefId = methodRef.getId();
            // "this" parameter is obj
            if (count == 1) {
                asm.emitPUSH_RegInd(SP);
            } else {
                asm.emitPUSH_RegDisp(SP, Offset.fromIntZeroExtend((count - 1) << LG_WORDSIZE));
            }
            // id of method to call
            asm.emitPUSH_Imm(methodRefId);
            // pass 2 parameter words
            genParameterRegisterLoad(asm, 2);
            // invokeinterface(obj, id) returns address to call
            asm.generateJTOCcall(Entrypoints.invokeInterfaceMethod.getOffset());
            if (VM.BuildFor32Addr) {
                // S0 has address of method
                asm.emitMOV_Reg_Reg(S0, T0);
            } else {
                // S0 has address of method
                asm.emitMOV_Reg_Reg_Quad(S0, T0);
            }
            genParameterRegisterLoad(methodRef, true);
            // the interface method (its parameters are on stack)
            asm.emitCALL_Reg(S0);
        } else {
            // itable index is known at compile-time.
            // call "findITable" to resolve object + interface id into
            // itable address
            // T0 = "this" object
            stackMoveHelper(T0, Offset.fromIntZeroExtend((count - 1) << LG_WORDSIZE));
            asm.baselineEmitLoadTIB(S0, T0);
            asm.emitPUSH_Reg(S0);
            // interface id
            asm.emitPUSH_Imm(resolvedMethod.getDeclaringClass().getInterfaceId());
            // pass 2 parameter words
            genParameterRegisterLoad(asm, 2);
            // findItableOffset(tib, id) returns iTable
            asm.generateJTOCcall(Entrypoints.findItableMethod.getOffset());
            if (VM.BuildFor32Addr) {
                // S0 has iTable
                asm.emitMOV_Reg_Reg(S0, T0);
            } else {
                // S0 has iTable
                asm.emitMOV_Reg_Reg_Quad(S0, T0);
            }
            genParameterRegisterLoad(methodRef, true);
            // the interface call
            asm.emitCALL_RegDisp(S0, Offset.fromIntZeroExtend(itableIndex << LG_WORDSIZE));
        }
    }
    genResultRegisterUnload(methodRef);
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference) InterfaceMethodSignature(org.jikesrvm.classloader.InterfaceMethodSignature) RVMMethod(org.jikesrvm.classloader.RVMMethod) RVMClass(org.jikesrvm.classloader.RVMClass) Offset(org.vmmagic.unboxed.Offset)

Aggregations

ForwardReference (org.jikesrvm.compilers.common.assembler.ForwardReference)71 Offset (org.vmmagic.unboxed.Offset)13 TypeReference (org.jikesrvm.classloader.TypeReference)5 RVMClass (org.jikesrvm.classloader.RVMClass)4 Assembler (org.jikesrvm.compilers.common.assembler.ppc.Assembler)4 RVMMethod (org.jikesrvm.classloader.RVMMethod)3 GPR (org.jikesrvm.ia32.RegisterConstants.GPR)3 XMM (org.jikesrvm.ia32.RegisterConstants.XMM)3 InterfaceMethodSignature (org.jikesrvm.classloader.InterfaceMethodSignature)2 RVMArray (org.jikesrvm.classloader.RVMArray)2 Assembler (org.jikesrvm.compilers.common.assembler.ia32.Assembler)2 FloatingPointMachineRegister (org.jikesrvm.ia32.RegisterConstants.FloatingPointMachineRegister)2 JNICompiledMethod (org.jikesrvm.jni.JNICompiledMethod)2 Entrypoint (org.vmmagic.pragma.Entrypoint)2 Inline (org.vmmagic.pragma.Inline)2 Address (org.vmmagic.unboxed.Address)2 Atom (org.jikesrvm.classloader.Atom)1 FieldReference (org.jikesrvm.classloader.FieldReference)1 MethodReference (org.jikesrvm.classloader.MethodReference)1 RVMType (org.jikesrvm.classloader.RVMType)1