changeset 4280:c9ab0ffadddd

Unify and simplify conversion LIR instructions
author Christian Wimmer <Christian.Wimmer@Oracle.com>
date Thu, 12 Jan 2012 13:46:47 -0800
parents cdcd26f86af5
children 62cb0e636094
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/AMD64ConvertOpcode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java
diffstat 5 files changed, 73 insertions(+), 224 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFIOpcode.java	Thu Jan 12 13:46:26 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * 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 static com.oracle.max.cri.ci.CiValueUtil.*;
-
-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.util.*;
-
-public enum AMD64ConvertFIOpcode implements LIROpcode {
-    F2I, D2I;
-
-    public LIRInstruction create(CiValue result, CiValue x) {
-        CiValue[] inputs = new CiValue[] {x};
-        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), input(0));
-            }
-        };
-    }
-
-    private void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue x) {
-        AMD64ConvertFSlowPath slowPath;
-        switch (this) {
-            case F2I:
-                masm.cvttss2sil(asIntReg(result), asFloatReg(x));
-                slowPath = new AMD64ConvertFSlowPath(masm, asIntReg(result), asFloatReg(x), false, false);
-                break;
-            case D2I:
-                masm.cvttsd2sil(asIntReg(result), asDoubleReg(x));
-                slowPath = new AMD64ConvertFSlowPath(masm, asIntReg(result), asDoubleReg(x), true, false);
-                break;
-            default:
-                throw Util.shouldNotReachHere();
-        }
-        tasm.slowPaths.add(slowPath);
-
-        masm.cmp32(asIntReg(result), Integer.MIN_VALUE);
-        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	Thu Jan 12 13:46:26 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
- * 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 static com.oracle.max.cri.ci.CiValueUtil.*;
-
-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.util.*;
-
-public enum AMD64ConvertFLOpcode implements LIROpcode {
-    F2L, D2L;
-
-    public LIRInstruction create(CiValue result, CiValue x, CiValue scratch) {
-        CiValue[] inputs = new CiValue[] {x};
-        CiValue[] temps = new CiValue[] {scratch};
-        CiValue[] outputs = new CiValue[] {result};
-
-        return new AMD64LIRInstruction(this, outputs, null, inputs, LIRInstruction.NO_OPERANDS, temps) {
-            @Override
-            public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                emit(tasm, masm, output(0), input(0), temp(0));
-            }
-        };
-    }
-
-    private void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue x, CiValue scratch) {
-        AMD64ConvertFSlowPath slowPath;
-        switch (this) {
-            case F2L:
-                masm.cvttss2siq(asLongReg(result), asFloatReg(x));
-                slowPath = new AMD64ConvertFSlowPath(masm, asLongReg(result), asFloatReg(x), false, true);
-                break;
-            case D2L:
-                masm.cvttsd2siq(asLongReg(result), asDoubleReg(x));
-                slowPath = new AMD64ConvertFSlowPath(masm, asLongReg(result), asDoubleReg(x), true, true);
-                break;
-            default:
-                throw Util.shouldNotReachHere();
-        }
-        tasm.slowPaths.add(slowPath);
-
-        CiRegister tmp = asLongReg(scratch);
-        masm.movq(tmp, java.lang.Long.MIN_VALUE);
-        masm.cmpq(asLongReg(result), tmp);
-        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/AMD64ConvertFSlowPath.java	Thu Jan 12 13:46:26 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
- * 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/AMD64ConvertOpcode.java	Thu Jan 12 13:46:26 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertOpcode.java	Thu Jan 12 13:46:47 2012 -0800
@@ -26,7 +26,9 @@
 
 import java.util.*;
 
+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.*;
@@ -35,8 +37,8 @@
 public enum AMD64ConvertOpcode implements LIROpcode {
     I2L, L2I, I2B, I2C, I2S,
     F2D, D2F,
-    I2F, I2D,
-    L2F, L2D,
+    I2F, I2D, F2I, D2I,
+    L2F, L2D, F2L, D2L,
     MOV_I2F, MOV_L2D, MOV_F2I, MOV_D2L;
 
     public LIRInstruction create(CiValue result, CiValue x) {
@@ -84,6 +86,22 @@
             case I2D: masm.cvtsi2sdl(asDoubleReg(result), asIntReg(x)); break;
             case L2F: masm.cvtsi2ssq(asFloatReg(result), asLongReg(x)); break;
             case L2D: masm.cvtsi2sdq(asDoubleReg(result), asLongReg(x)); break;
+            case F2I:
+                masm.cvttss2sil(asIntReg(result), asFloatReg(x));
+                emitFixup(tasm, masm, result, x);
+                break;
+            case D2I:
+                masm.cvttsd2sil(asIntReg(result), asDoubleReg(x));
+                emitFixup(tasm, masm, result, x);
+                break;
+            case F2L:
+                masm.cvttss2siq(asLongReg(result), asFloatReg(x));
+                emitFixup(tasm, masm, result, x);
+                break;
+            case D2L:
+                masm.cvttsd2siq(asLongReg(result), asDoubleReg(x));
+                emitFixup(tasm, masm, result, x);
+                break;
             case MOV_I2F: masm.movdl(asFloatReg(result), asIntReg(x)); break;
             case MOV_L2D: masm.movdq(asDoubleReg(result), asLongReg(x)); break;
             case MOV_F2I: masm.movdl(asIntReg(result), asFloatReg(x)); break;
@@ -91,4 +109,55 @@
             default: throw Util.shouldNotReachHere();
         }
     }
+
+    private static void emitFixup(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue x) {
+        FixupSlowPath slowPath = new FixupSlowPath(result, x);
+        tasm.slowPaths.add(slowPath);
+        switch (result.kind) {
+            case Int:  masm.cmpl(asIntReg(result),  Integer.MIN_VALUE); break;
+            case Long: masm.cmpq(asLongReg(result), tasm.asLongConstRef(CiConstant.forLong(java.lang.Long.MIN_VALUE))); break;
+            default:   throw Util.shouldNotReachHere();
+        }
+        masm.jcc(ConditionFlag.equal, slowPath.start);
+        masm.bind(slowPath.continuation);
+    }
+
+    private static class FixupSlowPath extends AMD64SlowPath {
+        public final Label start = new Label();
+        public final Label continuation = new Label();
+        private final CiValue result;
+        private final CiValue x;
+
+        public FixupSlowPath(CiValue result, CiValue x) {
+            this.result = result;
+            this.x = x;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            masm.bind(start);
+            switch (x.kind) {
+                case Float:  masm.ucomiss(asFloatReg(x),  tasm.asFloatConstRef(CiConstant.FLOAT_0)); break;
+                case Double: masm.ucomisd(asDoubleReg(x), tasm.asDoubleConstRef(CiConstant.DOUBLE_0)); break;
+                default:     throw Util.shouldNotReachHere();
+            }
+            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
+            switch (result.kind) {
+                case Int:  masm.decrementl(asIntReg(result),  1); break;
+                case Long: masm.decrementq(asLongReg(result), 1); break;
+                default:   throw Util.shouldNotReachHere();
+            }
+            masm.jmp(continuation);
+
+            // input is NaN -> return 0
+            masm.bind(nan);
+            masm.xorptr(asRegister(result), asRegister(result));
+            masm.jmp(continuation);
+        }
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java	Thu Jan 12 13:46:26 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java	Thu Jan 12 13:46:47 2012 -0800
@@ -27,8 +27,6 @@
 import static com.oracle.max.graal.compiler.target.amd64.AMD64ArithmeticOpcode.*;
 import static com.oracle.max.graal.compiler.target.amd64.AMD64CompareOpcode.*;
 import static com.oracle.max.graal.compiler.target.amd64.AMD64CompareToIntOpcode.*;
-import static com.oracle.max.graal.compiler.target.amd64.AMD64ConvertFIOpcode.*;
-import static com.oracle.max.graal.compiler.target.amd64.AMD64ConvertFLOpcode.*;
 import static com.oracle.max.graal.compiler.target.amd64.AMD64ConvertOpcode.*;
 import static com.oracle.max.graal.compiler.target.amd64.AMD64DivOpcode.*;
 import static com.oracle.max.graal.compiler.target.amd64.AMD64LogicFloatOpcode.*;
@@ -429,8 +427,8 @@
             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, input, newVariable(CiKind.Long))); break;
-            case D2L: append(D2L.create(result, input, newVariable(CiKind.Long))); break;
+            case F2L: append(F2L.create(result, input)); break;
+            case D2L: append(D2L.create(result, input)); 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;