changeset 4261:57b0da88576a

implement F2I, D2I, F2L, D2L compiler stubs as ordinary slow paths
author Lukas Stadler <lukas.stadler@jku.at>
date Wed, 11 Jan 2012 12:13:33 +0100
parents 78379b4203ec
children 744dade427b8
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFIOpcode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFLOpcode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFSlowPath.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java
diffstat 4 files changed, 117 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFIOpcode.java	Tue Jan 10 13:24:00 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFIOpcode.java	Wed Jan 11 12:13:33 2012 +0100
@@ -24,41 +24,46 @@
 
 import static com.oracle.max.cri.ci.CiValueUtil.*;
 
-import com.oracle.max.asm.*;
 import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.max.asm.target.amd64.*;
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.graal.compiler.asm.*;
 import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.stub.*;
 import com.oracle.max.graal.compiler.util.*;
 
 public enum AMD64ConvertFIOpcode implements LIROpcode {
     F2I, D2I;
 
-    public LIRInstruction create(Variable result, final CompilerStub stub, Variable input) {
+    public LIRInstruction create(Variable result, Variable input) {
         CiValue[] inputs = new CiValue[] {input};
         CiValue[] outputs = new CiValue[] {result};
 
         return new AMD64LIRInstruction(this, outputs, null, inputs, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) {
             @Override
             public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                emit(tasm, masm, output(0), stub, input(0));
+                emit(tasm, masm, output(0), input(0));
             }
         };
     }
 
-    private void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CompilerStub stub, CiValue input) {
+    private void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue input) {
+        AMD64ConvertFSlowPath slowPath;
         switch (this) {
-            case F2I: masm.cvttss2sil(asIntReg(result), asFloatReg(input)); break;
-            case D2I: masm.cvttsd2sil(asIntReg(result), asDoubleReg(input)); break;
-            default: throw Util.shouldNotReachHere();
+            case F2I:
+                masm.cvttss2sil(asIntReg(result), asFloatReg(input));
+                slowPath = new AMD64ConvertFSlowPath(masm, asIntReg(result), asFloatReg(input), false, false);
+                break;
+            case D2I:
+                masm.cvttsd2sil(asIntReg(result), asDoubleReg(input));
+                slowPath = new AMD64ConvertFSlowPath(masm, asIntReg(result), asFloatReg(input), true, false);
+                break;
+            default:
+                throw Util.shouldNotReachHere();
         }
+        tasm.compilation.lir().slowPaths.add(slowPath);
 
-        Label endLabel = new Label();
         masm.cmp32(asIntReg(result), Integer.MIN_VALUE);
-        masm.jcc(ConditionFlag.notEqual, endLabel);
-        AMD64CallOpcode.callStub(tasm, masm, stub, null, result, input);
-        masm.bind(endLabel);
+        masm.jcc(ConditionFlag.equal, slowPath.start);
+        masm.bind(slowPath.continuation);
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFLOpcode.java	Tue Jan 10 13:24:00 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFLOpcode.java	Wed Jan 11 12:13:33 2012 +0100
@@ -24,19 +24,17 @@
 
 import static com.oracle.max.cri.ci.CiValueUtil.*;
 
-import com.oracle.max.asm.*;
 import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.max.asm.target.amd64.*;
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.graal.compiler.asm.*;
 import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.stub.*;
 import com.oracle.max.graal.compiler.util.*;
 
 public enum AMD64ConvertFLOpcode implements LIROpcode {
     F2L, D2L;
 
-    public LIRInstruction create(Variable result, final CompilerStub stub, Variable input, Variable scratch) {
+    public LIRInstruction create(Variable result, Variable input, Variable scratch) {
         CiValue[] inputs = new CiValue[] {input};
         CiValue[] temps = new CiValue[] {scratch};
         CiValue[] outputs = new CiValue[] {result};
@@ -44,25 +42,31 @@
         return new AMD64LIRInstruction(this, outputs, null, inputs, LIRInstruction.NO_OPERANDS, temps) {
             @Override
             public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                emit(tasm, masm, output(0), stub, input(0), temp(0));
+                emit(tasm, masm, output(0), input(0), temp(0));
             }
         };
     }
 
-    private void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CompilerStub stub, CiValue input, CiValue scratch) {
-        CiRegister dst = asLongReg(result);
-        CiRegister tmp = asLongReg(scratch);
+    private void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue input, CiValue scratch) {
+        AMD64ConvertFSlowPath slowPath;
         switch (this) {
-            case F2L: masm.cvttss2siq(dst, asFloatReg(input)); break;
-            case D2L: masm.cvttsd2siq(dst, asDoubleReg(input)); break;
-            default: throw Util.shouldNotReachHere();
+            case F2L:
+                masm.cvttss2siq(asLongReg(result), asFloatReg(input));
+                slowPath = new AMD64ConvertFSlowPath(masm, asIntReg(result), asFloatReg(input), false, true);
+                break;
+            case D2L:
+                masm.cvttsd2siq(asLongReg(result), asDoubleReg(input));
+                slowPath = new AMD64ConvertFSlowPath(masm, asIntReg(result), asFloatReg(input), true, true);
+                break;
+            default:
+                throw Util.shouldNotReachHere();
         }
+        tasm.compilation.lir().slowPaths.add(slowPath);
 
-        Label endLabel = new Label();
+        CiRegister tmp = asLongReg(scratch);
         masm.movq(tmp, java.lang.Long.MIN_VALUE);
-        masm.cmpq(dst, tmp);
-        masm.jcc(ConditionFlag.notEqual, endLabel);
-        AMD64CallOpcode.callStub(tasm, masm, stub, null, result, input);
-        masm.bind(endLabel);
+        masm.cmpq(asLongReg(result), tmp);
+        masm.jcc(ConditionFlag.equal, slowPath.start);
+        masm.bind(slowPath.continuation);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFSlowPath.java	Wed Jan 11 12:13:33 2012 +0100
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.compiler.target.amd64;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.asm.target.amd64.AMD64Assembler.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.compiler.asm.*;
+import com.oracle.max.graal.compiler.lir.*;
+
+class AMD64ConvertFSlowPath implements LIR.SlowPath {
+
+    public final Label start = new Label();
+    public final Label continuation = new Label();
+
+    private final CiRegister result;
+    private final CiRegister input;
+    private final AMD64MacroAssembler masm;
+    private final boolean inputIsDouble;
+    private final boolean resultIsLong;
+
+    public AMD64ConvertFSlowPath(AMD64MacroAssembler masm, CiRegister result, CiRegister input, boolean inputIsDouble, boolean resultIsLong) {
+        this.masm = masm;
+        this.result = result;
+        this.input = input;
+        this.inputIsDouble = inputIsDouble;
+        this.resultIsLong = resultIsLong;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm) {
+        masm.bind(start);
+        if (inputIsDouble) {
+            masm.ucomisd(input, tasm.asDoubleConstRef(CiConstant.DOUBLE_0));
+        } else {
+            masm.ucomiss(input, tasm.asFloatConstRef(CiConstant.FLOAT_0));
+        }
+        Label nan = new Label();
+        masm.jcc(ConditionFlag.parity, nan);
+        masm.jcc(ConditionFlag.below, continuation);
+
+        // input is > 0 -> return maxInt
+        // result register already contains 0x80000000, so subtracting 1 gives 0x7fffffff
+        if (resultIsLong) {
+            masm.decrementq(result, 1);
+        } else {
+            masm.decrementl(result, 1);
+        }
+        masm.jmp(continuation);
+
+        // input is NaN -> return 0
+        masm.bind(nan);
+        masm.xorptr(result, result);
+        masm.jmp(continuation);
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java	Tue Jan 10 13:24:00 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java	Wed Jan 11 12:13:33 2012 +0100
@@ -424,12 +424,12 @@
             case D2F: append(D2F.create(result, input)); break;
             case I2F: append(I2F.create(result, input)); break;
             case I2D: append(I2D.create(result, input)); break;
-            case F2I: append(F2I.create(result, stubFor(CompilerStub.Id.f2i), input)); break;
-            case D2I: append(D2I.create(result, stubFor(CompilerStub.Id.d2i), input)); break;
+            case F2I: append(F2I.create(result, input)); break;
+            case D2I: append(D2I.create(result, input)); break;
             case L2F: append(L2F.create(result, input)); break;
             case L2D: append(L2D.create(result, input)); break;
-            case F2L: append(F2L.create(result, stubFor(CompilerStub.Id.f2l), input, newVariable(CiKind.Long))); break;
-            case D2L: append(D2L.create(result, stubFor(CompilerStub.Id.d2l), input, newVariable(CiKind.Long))); break;
+            case F2L: append(F2L.create(result, input, newVariable(CiKind.Long))); break;
+            case D2L: append(D2L.create(result, input, newVariable(CiKind.Long))); break;
             case MOV_I2F: append(MOV_I2F.create(result, input)); break;
             case MOV_L2D: append(MOV_L2D.create(result, input)); break;
             case MOV_F2I: append(MOV_F2I.create(result, input)); break;