Search in sources :

Example 26 with StackLocationOperand

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

the class ComplexLIR2MIRExpansion method float_2long.

private static Instruction float_2long(Instruction s, IR ir) {
    Instruction nextInstr = s.nextInstructionInCodeOrder();
    while (Label.conforms(nextInstr) || BBend.conforms(nextInstr)) {
        nextInstr = nextInstr.nextInstructionInCodeOrder();
    }
    if (VM.BuildFor32Addr) {
        // 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 f2lBB = testBB.splitNodeAt(s, ir);
        ir.cfg.linkInCodeOrder(testBB, f2lBB);
        // Move the maxlongFloat value and the value into x87 registers and compare and
        // branch if they are <= or unordered.
        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.maxlongFloatField.getOffset(), (byte) 4);
        RegisterOperand st0 = new RegisterOperand(phys(ir).getST0(), TypeReference.Float);
        RegisterOperand st1 = new RegisterOperand(phys(ir).getST1(), TypeReference.Float);
        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_MOVSS, slLo, value)));
        s.insertBefore(CPOS(s, MIR_Move.create(IA32_FLD, st0, slLo.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(f2lBB);
        testBB.insertOut(nanTestBB);
        // Convert float 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
        f2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FNSTCW, scratchLo.copy())));
        f2lBB.appendInstruction(CPOS(s, MIR_Unary.create(IA32_MOVZX__W, cw, scratchLo.copy())));
        f2lBB.appendInstruction(CPOS(s, MIR_BinaryAcc.create(IA32_OR, cw.copyRO(), IC(0xC00))));
        f2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, scratchHi, cw.copyRO())));
        f2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FLDCW, scratchHi.copy())));
        f2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_FISTP, sl, st0.copyRO())));
        f2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FLDCW, scratchLo.copy())));
        f2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultLo, slLo.copy())));
        f2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultHi, slHi)));
        f2lBB.appendInstruction(CPOS(s, MIR_Branch.create(IA32_JMP, nextBB.makeJumpTarget())));
        f2lBB.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);
    } else {
        // we need 4 basic blocks (in code order)
        // 1: the current block which includes a test for NaN
        // 2: a block to perform regular f2l
        // 3: a block to handle NaN (which gives a result of 0)
        // 4: 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 f2lBB = testBB.splitNodeAt(s, ir);
        ir.cfg.linkInCodeOrder(testBB, f2lBB);
        RegisterOperand result = Unary.getResult(s).copyRO();
        RegisterOperand value = Unary.getVal(s).asRegister().copyRO();
        RegisterOperand adjustment = ir.regpool.makeTempInt();
        testBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, adjustment.copy(), IC(0))));
        MemoryOperand maxlong = BURS_Helpers.loadFromJTOC(ir, Entrypoints.maxlongFloatField.getOffset(), (byte) 4);
        MIR_Compare.mutate(s, IA32_UCOMISS, value.copy(), maxlong);
        testBB.appendInstruction(CPOS(s, MIR_CondBranch.create(IA32_JCC, IA32ConditionOperand.PE(), nanBB.makeJumpTarget(), BranchProfileOperand.unlikely())));
        testBB.insertOut(f2lBB);
        testBB.insertOut(nanBB);
        f2lBB.appendInstruction(CPOS(s, MIR_Set.create(IA32_SET__B, adjustment.copy(), IA32ConditionOperand.LGE())));
        f2lBB.appendInstruction(CPOS(s, MIR_Unary.create(IA32_CVTTSS2SI, result.copy(), value.copy())));
        f2lBB.appendInstruction(CPOS(s, MIR_BinaryAcc.create(IA32_SUB, result.copy(), adjustment.copy())));
        f2lBB.appendInstruction(CPOS(s, MIR_Branch.create(IA32_JMP, nextBB.makeJumpTarget())));
        f2lBB.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 27 with StackLocationOperand

use of org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand 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.
 *
 * @param s the instruction to expand
 */
protected final void SET_EXCEPTION_OBJECT(Instruction s) {
    int offset = -burs.ir.stackManager.allocateSpaceForCaughtException();
    StackLocationOperand sl = new StackLocationOperand(true, offset, DW);
    Operand val = CacheOp.getClearRef(s);
    if (val.isRegister()) {
        EMIT(MIR_Move.mutate(s, IA32_MOV, sl, val));
    } else if (val.isConstant()) {
        RegisterOperand temp;
        if (val.isIntConstant()) {
            if (VM.VerifyAssertions)
                opt_assert(VM.BuildFor32Addr);
            temp = regpool.makeTempInt();
        } else if (val.isLongConstant()) {
            if (VM.VerifyAssertions)
                opt_assert(VM.BuildFor64Addr);
            temp = regpool.makeTempLong();
        } else {
            throw new OptimizingCompilerException("BURS_Helpers", "unexpected operand type " + val + " in SET_EXCEPTION_OBJECT");
        }
        EMIT(CPOS(s, MIR_Move.create(IA32_MOV, temp, val)));
        // for opt compiler var usage info?
        val = temp.copyRO();
        EMIT(MIR_Move.mutate(s, IA32_MOV, sl, temp.copy()));
    } else {
        throw new OptimizingCompilerException("BURS_Helpers", "unexpected operand type " + val + " in SET_EXCEPTION_OBJECT");
    }
}
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) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IA32ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) 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) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) InlinedOsrTypeInfoOperand(org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) BURSManagedFPROperand(org.jikesrvm.compilers.opt.ir.operand.ia32.BURSManagedFPROperand) 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) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)

Example 28 with StackLocationOperand

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

the class BURS_Helpers method FPR2GPR_64.

/**
 * Emits code to move 64 bits from FPRs to GPRs
 *
 * @param s instruction to modify for the move
 */
protected final void FPR2GPR_64(Instruction s) {
    int offset = -burs.ir.stackManager.allocateSpaceForConversion();
    StackLocationOperand sl = new StackLocationOperand(true, offset, QW);
    StackLocationOperand sl1 = new StackLocationOperand(true, offset + 4, DW);
    StackLocationOperand sl2 = new StackLocationOperand(true, offset, DW);
    EMIT(CPOS(s, MIR_Move.create(IA32_FMOV, sl, Unary.getClearVal(s))));
    RegisterOperand i1 = Unary.getClearResult(s);
    RegisterOperand i2 = new RegisterOperand(regpool.getSecondReg(i1.getRegister()), TypeReference.Int);
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, i1, sl1)));
    EMIT(MIR_Move.mutate(s, IA32_MOV, i2, sl2));
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) OsrPoint(org.jikesrvm.compilers.opt.ir.OsrPoint) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)

Aggregations

StackLocationOperand (org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)28 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)26 MemoryOperand (org.jikesrvm.compilers.opt.ir.operand.MemoryOperand)22 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)20 IA32ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand)20 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)15 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)13 GenericPhysicalRegisterSet (org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet)12 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)11 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)11 Register (org.jikesrvm.compilers.opt.ir.Register)10 OsrPoint (org.jikesrvm.compilers.opt.ir.OsrPoint)9 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)8 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)7 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)6 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)6 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)6 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)6 DoubleConstantOperand (org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand)6 FloatConstantOperand (org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand)6