# HG changeset patch # User Doug Simon # Date 1367870868 -7200 # Node ID d84ea522800e93c5cf77dff2e549004158aa525f # Parent c59beafffb290d3046c7546dfe5be36d66100067 replaced arithmetic_[fd]rem stubs with inline compiled code (GRAAL-81) diff -r c59beafffb29 -r d84ea522800e graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java --- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Mon May 06 21:00:20 2013 +0200 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Mon May 06 22:07:48 2013 +0200 @@ -2420,11 +2420,16 @@ emitByte(b2 + i); } - public final void fld(AMD64Address src) { + public final void fld_d(AMD64Address src) { emitByte(0xDD); emitOperandHelper(0, src); } + public final void fld_s(AMD64Address src) { + emitByte(0xD9); + emitOperandHelper(0, src); + } + public final void fldln2() { emitByte(0xD9); emitByte(0xED); @@ -2440,11 +2445,49 @@ emitByte(0xF1); } - public final void fstp(AMD64Address src) { + public final void fstp_s(AMD64Address src) { + emitByte(0xD9); + emitOperandHelper(3, src); + } + + public final void fstp_d(AMD64Address src) { emitByte(0xDD); emitOperandHelper(3, src); } + private void emitFPUArith(int b1, int b2, int i) { + assert 0 <= i && i < 8 : "illegal FPU register: " + i; + emitByte(b1); + emitByte(b2 + i); + } + + public void ffree(int i) { + emitFPUArith(0xDD, 0xC0, i); + } + + public void fincstp() { + emitByte(0xD9); + emitByte(0xF7); + } + + public void fxch(int i) { + emitFPUArith(0xD9, 0xC8, i); + } + + public void fnstsw_ax() { + emitByte(0xDF); + emitByte(0xE0); + } + + public void fwait() { + emitByte(0x9B); + } + + public void fprem() { + emitByte(0xD9); + emitByte(0xF8); + } + public final void fsin() { emitByte(0xD9); emitByte(0xFE); diff -r c59beafffb29 -r d84ea522800e graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java --- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java Mon May 06 21:00:20 2013 +0200 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java Mon May 06 22:07:48 2013 +0200 @@ -218,17 +218,12 @@ } public final void flog(Register dest, Register value, boolean base10) { - assert dest.getRegisterCategory() == AMD64.XMM && value.getRegisterCategory() == AMD64.XMM; - - AMD64Address tmp = new AMD64Address(AMD64.rsp); if (base10) { fldlg2(); } else { fldln2(); } - subq(AMD64.rsp, 8); - movsd(tmp, value); - fld(tmp); + AMD64Address tmp = trigPrologue(value); fyl2x(); trigEpilogue(dest, tmp); } @@ -252,18 +247,23 @@ trigEpilogue(dest, tmp); } + public final void fpop() { + ffree(0); + fincstp(); + } + private AMD64Address trigPrologue(Register value) { assert value.getRegisterCategory() == AMD64.XMM; AMD64Address tmp = new AMD64Address(AMD64.rsp); subq(AMD64.rsp, 8); movsd(tmp, value); - fld(tmp); + fld_d(tmp); return tmp; } private void trigEpilogue(Register dest, AMD64Address tmp) { assert dest.getRegisterCategory() == AMD64.XMM; - fstp(tmp); + fstp_d(tmp); movsd(dest, tmp); addq(AMD64.rsp, 8); } diff -r c59beafffb29 -r d84ea522800e graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Mon May 06 21:00:20 2013 +0200 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Mon May 06 22:07:48 2013 +0200 @@ -31,7 +31,6 @@ import com.oracle.graal.amd64.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.amd64.AMD64Address.Scale; @@ -48,6 +47,7 @@ import com.oracle.graal.lir.amd64.AMD64Arithmetic.BinaryRegStack; import com.oracle.graal.lir.amd64.AMD64Arithmetic.BinaryRegStackConst; import com.oracle.graal.lir.amd64.AMD64Arithmetic.DivRemOp; +import com.oracle.graal.lir.amd64.AMD64Arithmetic.FPDivRemOp; import com.oracle.graal.lir.amd64.AMD64Arithmetic.Unary1Op; import com.oracle.graal.lir.amd64.AMD64Arithmetic.Unary2Op; import com.oracle.graal.lir.amd64.AMD64Compare.CompareOp; @@ -78,9 +78,6 @@ */ public abstract class AMD64LIRGenerator extends LIRGenerator { - public static final Descriptor ARITHMETIC_FREM = new Descriptor("arithmeticFrem", false, float.class, float.class, float.class); - public static final Descriptor ARITHMETIC_DREM = new Descriptor("arithmeticDrem", false, double.class, double.class, double.class); - private static final RegisterValue RAX_I = AMD64.rax.asValue(Kind.Int); private static final RegisterValue RAX_L = AMD64.rax.asValue(Kind.Long); private static final RegisterValue RDX_I = AMD64.rdx.asValue(Kind.Int); @@ -578,12 +575,14 @@ emitDivRem(LREM, a, b, state(deopting)); return emitMove(RDX_L); case Float: { - RuntimeCallTarget stub = runtime.lookupRuntimeCall(ARITHMETIC_FREM); - return emitCall(stub, stub.getCallingConvention(), null, a, b); + Variable result = newVariable(a.getPlatformKind()); + append(new FPDivRemOp(FREM, result, load(a), load(b))); + return result; } case Double: { - RuntimeCallTarget stub = runtime.lookupRuntimeCall(ARITHMETIC_DREM); - return emitCall(stub, stub.getCallingConvention(), null, a, b); + Variable result = newVariable(a.getPlatformKind()); + append(new FPDivRemOp(DREM, result, load(a), load(b))); + return result; } default: throw GraalInternalError.shouldNotReachHere(); diff -r c59beafffb29 -r d84ea522800e graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Mon May 06 21:00:20 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Mon May 06 22:07:48 2013 +0200 @@ -23,7 +23,6 @@ package com.oracle.graal.hotspot.amd64; import static com.oracle.graal.amd64.AMD64.*; -import static com.oracle.graal.compiler.amd64.AMD64LIRGenerator.*; import static com.oracle.graal.hotspot.HotSpotBackend.*; import static com.oracle.graal.hotspot.nodes.MonitorEnterStubCall.*; import static com.oracle.graal.hotspot.nodes.MonitorExitStubCall.*; @@ -35,7 +34,6 @@ import static com.oracle.graal.hotspot.replacements.CipherBlockChainingSubstitutions.DecryptAESCryptStubCall.*; import static com.oracle.graal.hotspot.replacements.CipherBlockChainingSubstitutions.EncryptAESCryptStubCall.*; -import com.oracle.graal.amd64.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; @@ -66,18 +64,6 @@ /* arg0: exception */ rax.asValue(Kind.Object), /* arg1: exceptionPc */ rdx.asValue(word)); - addRuntimeCall(ARITHMETIC_FREM, config.arithmeticFremStub, - /* temps */ new Register[]{AMD64.rax}, - /* ret */ ret(Kind.Float), - /* arg0: a */ javaCallingConvention(Kind.Float, - /* arg1: b */ Kind.Float)); - - addRuntimeCall(ARITHMETIC_DREM, config.arithmeticDremStub, - /* temps */ new Register[]{AMD64.rax}, - /* ret */ ret(Kind.Double), - /* arg0: a */ javaCallingConvention(Kind.Double, - /* arg1: b */ Kind.Double)); - addRuntimeCall(MONITORENTER, config.monitorEnterStub, /* temps */ null, /* ret */ ret(Kind.Void), diff -r c59beafffb29 -r d84ea522800e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Mon May 06 21:00:20 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Mon May 06 22:07:48 2013 +0200 @@ -381,8 +381,6 @@ public long createOutOfBoundsExceptionStub; public long javaTimeMillisStub; public long javaTimeNanosStub; - public long arithmeticFremStub; - public long arithmeticDremStub; public long arithmeticSinStub; public long arithmeticCosStub; public long arithmeticTanStub; diff -r c59beafffb29 -r d84ea522800e graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java Mon May 06 21:00:20 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java Mon May 06 22:07:48 2013 +0200 @@ -27,7 +27,9 @@ import com.oracle.graal.amd64.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.*; import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; @@ -36,8 +38,8 @@ public enum AMD64Arithmetic { IADD, ISUB, IMUL, IDIV, IDIVREM, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR, LADD, LSUB, LMUL, LDIV, LDIVREM, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR, - FADD, FSUB, FMUL, FDIV, FAND, FOR, FXOR, - DADD, DSUB, DMUL, DDIV, DAND, DOR, DXOR, + FADD, FSUB, FMUL, FDIV, FREM, FAND, FOR, FXOR, + DADD, DSUB, DMUL, DDIV, DREM, DAND, DOR, DXOR, INEG, LNEG, I2L, L2I, I2B, I2C, I2S, F2D, D2F, @@ -278,6 +280,64 @@ } } + public static class FPDivRemOp extends AMD64LIRInstruction { + @Opcode private final AMD64Arithmetic opcode; + @Def protected AllocatableValue result; + @Use protected AllocatableValue x; + @Use protected AllocatableValue y; + @Temp protected AllocatableValue raxTemp; + + public FPDivRemOp(AMD64Arithmetic opcode, AllocatableValue result, AllocatableValue x, AllocatableValue y) { + this.opcode = opcode; + this.result = result; + this.raxTemp = AMD64.rax.asValue(Kind.Int); + this.x = x; + this.y = y; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { + AMD64Address tmp = new AMD64Address(AMD64.rsp); + masm.subq(AMD64.rsp, 8); + if (opcode == FREM) { + masm.movflt(tmp, asRegister(y)); + masm.fld_s(tmp); + masm.movflt(tmp, asRegister(x)); + masm.fld_s(tmp); + } else { + assert opcode == DREM; + masm.movsd(tmp, asRegister(y)); + masm.fld_d(tmp); + masm.movsd(tmp, asRegister(x)); + masm.fld_d(tmp); + } + + Label label = new Label(); + masm.bind(label); + masm.fprem(); + masm.fwait(); + masm.fnstsw_ax(); + masm.testl(AMD64.rax, 0x400); + masm.jcc(ConditionFlag.NotZero, label); + masm.fxch(1); + masm.fpop(); + + if (opcode == FREM) { + masm.fstp_s(tmp); + masm.movflt(asRegister(result), tmp); + } else { + masm.fstp_d(tmp); + masm.movsd(asRegister(result), tmp); + } + masm.addq(AMD64.rsp, 8); + } + + @Override + protected void verify() { + super.verify(); + verifyKind(opcode, result, x, y); + } + } @SuppressWarnings("unused") protected static void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Arithmetic opcode, AllocatableValue result) { diff -r c59beafffb29 -r d84ea522800e src/cpu/x86/vm/graalRuntime_x86.cpp --- a/src/cpu/x86/vm/graalRuntime_x86.cpp Mon May 06 21:00:20 2013 +0200 +++ b/src/cpu/x86/vm/graalRuntime_x86.cpp Mon May 06 22:07:48 2013 +0200 @@ -697,48 +697,6 @@ break; } - case arithmetic_frem_id: { - __ subptr(rsp, 8); - __ movflt(Address(rsp, 0), xmm1); - __ fld_s(Address(rsp, 0)); - __ movflt(Address(rsp, 0), xmm0); - __ fld_s(Address(rsp, 0)); - Label L; - __ bind(L); - __ fprem(); - __ fwait(); - __ fnstsw_ax(); - __ testl(rax, 0x400); - __ jcc(Assembler::notZero, L); - __ fxch(1); - __ fpop(); - __ fstp_s(Address(rsp, 0)); - __ movflt(xmm0, Address(rsp, 0)); - __ addptr(rsp, 8); - __ ret(0); - break; - } - case arithmetic_drem_id: { - __ subptr(rsp, 8); - __ movdbl(Address(rsp, 0), xmm1); - __ fld_d(Address(rsp, 0)); - __ movdbl(Address(rsp, 0), xmm0); - __ fld_d(Address(rsp, 0)); - Label L; - __ bind(L); - __ fprem(); - __ fwait(); - __ fnstsw_ax(); - __ testl(rax, 0x400); - __ jcc(Assembler::notZero, L); - __ fxch(1); - __ fpop(); - __ fstp_d(Address(rsp, 0)); - __ movdbl(xmm0, Address(rsp, 0)); - __ addptr(rsp, 8); - __ ret(0); - break; - } case monitorenter_id: { Register obj = j_rarg0; Register lock = j_rarg1; diff -r c59beafffb29 -r d84ea522800e src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Mon May 06 21:00:20 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Mon May 06 22:07:48 2013 +0200 @@ -769,8 +769,6 @@ set_address("createOutOfBoundsExceptionStub", GraalRuntime::entry_for(GraalRuntime::create_out_of_bounds_exception_id)); set_address("javaTimeMillisStub", CAST_FROM_FN_PTR(address, os::javaTimeMillis)); set_address("javaTimeNanosStub", CAST_FROM_FN_PTR(address, os::javaTimeNanos)); - set_address("arithmeticFremStub", GraalRuntime::entry_for(GraalRuntime::arithmetic_frem_id)); - set_address("arithmeticDremStub", GraalRuntime::entry_for(GraalRuntime::arithmetic_drem_id)); set_address("arithmeticSinStub", CAST_FROM_FN_PTR(address, SharedRuntime::dsin)); set_address("arithmeticCosStub", CAST_FROM_FN_PTR(address, SharedRuntime::dcos)); set_address("arithmeticTanStub", CAST_FROM_FN_PTR(address, SharedRuntime::dtan)); diff -r c59beafffb29 -r d84ea522800e src/share/vm/graal/graalRuntime.cpp --- a/src/share/vm/graal/graalRuntime.cpp Mon May 06 21:00:20 2013 +0200 +++ b/src/share/vm/graal/graalRuntime.cpp Mon May 06 22:07:48 2013 +0200 @@ -125,15 +125,7 @@ #ifdef ASSERT // Make sure that stubs that need oopmaps have them - switch (id) { - // These stubs don't need to have an oopmap - case arithmetic_frem_id: - case arithmetic_drem_id: - break; - // All other stubs should have oopmaps - default: - assert(oop_maps != NULL, "must have an oopmap"); - } + assert(oop_maps != NULL, "must have an oopmap"); #endif // align so printing shows nop's instead of random code at the end (SimpleStubs are aligned) diff -r c59beafffb29 -r d84ea522800e src/share/vm/graal/graalRuntime.hpp --- a/src/share/vm/graal/graalRuntime.hpp Mon May 06 21:00:20 2013 +0200 +++ b/src/share/vm/graal/graalRuntime.hpp Mon May 06 22:07:48 2013 +0200 @@ -78,8 +78,6 @@ // runtime routines needed by code code generated // by Graal. #define GRAAL_STUBS(stub, last_entry) \ - stub(arithmetic_frem) \ - stub(arithmetic_drem) \ stub(monitorenter) \ stub(monitorexit) \ stub(vm_error) \