changeset 9581:d84ea522800e

replaced arithmetic_[fd]rem stubs with inline compiled code (GRAAL-81)
author Doug Simon <doug.simon@oracle.com>
date Mon, 06 May 2013 22:07:48 +0200
parents c59beafffb29
children 7df076e74e8e
files graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java src/cpu/x86/vm/graalRuntime_x86.cpp src/share/vm/graal/graalCompilerToVM.cpp src/share/vm/graal/graalRuntime.cpp src/share/vm/graal/graalRuntime.hpp
diffstat 10 files changed, 123 insertions(+), 91 deletions(-) [+]
line wrap: on
line diff
--- 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);
--- 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);
     }
--- 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();
--- 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),
--- 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;
--- 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) {
--- 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;
--- 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));
--- 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)
--- 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)                \