changeset 9825:81d5d8089cda

SPARC float arithmetic
author Morris Meyer <morris.meyer@oracle.com>
date Sun, 26 May 2013 13:44:16 -0400
parents 6fa4b4933892
children cff647969dfa
files graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/FloatSPARCTest.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java
diffstat 5 files changed, 686 insertions(+), 143 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java	Sun May 26 13:44:16 2013 -0400
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2013, 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.graal.asm.sparc;
+
+import com.oracle.graal.api.code.AbstractAddress;
+import com.oracle.graal.api.code.Register;
+
+public class SPARCAddress extends AbstractAddress {
+
+    private final Register base;
+    private final Register index;
+    private final int displacement;
+
+    /**
+     * Creates an {@link SPARCAddress} with given base register,and no displacement.
+     * 
+     * @param base the base register
+     */
+    public SPARCAddress(Register base) {
+        this(base, Register.None, 0);
+    }
+
+    /**
+     * Creates an {@link SPARCAddress} with given base register, no scaling and a given
+     * displacement.
+     * 
+     * @param base the base register
+     * @param displacement the displacement
+     */
+    public SPARCAddress(Register base, int displacement) {
+        this(base, Register.None, displacement);
+    }
+
+    /**
+     * Creates an {@link SPARCAddress} with given base and index registers, scaling and
+     * displacement. This is the most general constructor.
+     * 
+     * @param base the base register
+     * @param index the index register
+     * @param displacement the displacement
+     */
+    public SPARCAddress(Register base, Register index, int displacement) {
+        this.base = base;
+        this.index = index;
+        this.displacement = displacement;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder s = new StringBuilder();
+        s.append("[");
+        String sep = "";
+        if (!getBase().equals(Register.None)) {
+            s.append(getBase());
+            sep = " + ";
+        }
+        if (!getIndex().equals(Register.None)) {
+            s.append(sep).append(getIndex()).append(" * ");
+            sep = " + ";
+        }
+        s.append("]");
+        return s.toString();
+    }
+
+    /**
+     * @return Base register that defines the start of the address computation. If not present, is
+     *         denoted by {@link Register#None}.
+     */
+    public Register getBase() {
+        return base;
+    }
+
+    /**
+     * @return Index register, the value of which is added to {@link #getBase}. If not present, is
+     *         denoted by {@link Register#None}.
+     */
+    public Register getIndex() {
+        return index;
+    }
+
+    /**
+     * @return Optional additive displacement.
+     */
+    public int getDisplacement() {
+        return displacement;
+    }
+}
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Sun May 26 13:15:51 2013 +0200
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Sun May 26 13:44:16 2013 -0400
@@ -305,7 +305,16 @@
         Save(0x3c, "save"),
         Restore(0x3d, "restore"),
         Done(0x3e, "done"),
-        Retry(0x3e, "retry");
+        Retry(0x3e, "retry"),
+
+        Ldf(0x20, "ldf"),
+        Ldfsr(0x21, "ldfsr"),
+        Ldaf(0x22, "ldaf"),
+        Lddf(0x23, "lddf"),
+        Stf(0x24, "stf"),
+        Stfsr(0x25, "stfsr"),
+        Staf(0x26, "staf"),
+        Stdf(0x27, "stdf");
 
         private final int value;
         private final String operator;
@@ -325,12 +334,31 @@
     }
 
     public enum Opfs {
+        Fmovs(0x01, "fmovs"),
+        Fmovd(0x02, "fmovd"),
+        Fmovq(0x03, "fmovq"),
+        Fnegs(0x05, "fnegs"),
+        Fnegd(0x06, "fnegd"),
+        Fnegq(0x07, "fnegq"),
+        Fabss(0x09, "fabss"),
+        Fabsd(0x0A, "fabsd"),
+        Fabsq(0x0B, "fabsq"),
         Fadds(0x41, "fadds"),
         Faddd(0x42, "faddd"),
         Faddq(0x43, "faddq"),
         Fsubs(0x45, "fsubs"),
         Fsubd(0x46, "fsubd"),
         Fsubq(0x47, "fsubq"),
+        Fmuls(0x49, "fmuls"),
+        Fmuld(0x4A, "fmuld"),
+        Fdivs(0x4C, "fdivs"),
+        Fdivd(0x4D, "fdivd"),
+        Fdivq(0x4E, "fdivq"),
+
+        Fsmuld(0x69, "fsmuld"),
+        Fmulq(0x6B, "fmulq"),
+        Fdmuldq(0x6E, "fdmulq"),
+
         Fstoi(0xD1, "fstoi"),
         Fdtoi(0xD2, "fdtoi");
 
@@ -616,6 +644,48 @@
         }
     }
 
+    public static class Fdivs extends Fmt3p {
+        public Fdivs(SPARCAssembler masm, Register src1, Register src2, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fdivs.getValue(),
+                    src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fdivd extends Fmt3p {
+        public Fdivd(SPARCAssembler masm, Register src1, Register src2, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fdivd.getValue(),
+                    src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fmuls extends Fmt3p {
+        public Fmuls(SPARCAssembler masm, Register src1, Register src2, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fmuls.getValue(),
+                    src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fmuld extends Fmt3p {
+        public Fmuld(SPARCAssembler masm, Register src1, Register src2, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fmuld.getValue(),
+                    src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fnegs extends Fmt3n {
+        public Fnegs(SPARCAssembler masm, Register src2, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fnegs.getValue(),
+                  src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fnegd extends Fmt3n {
+        public Fnegd(SPARCAssembler masm, Register src2, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fnegd.getValue(),
+                  src2.encoding(), dst.encoding());
+        }
+    }
+
     public static class Fstoi extends Fmt3n {
         public Fstoi(SPARCAssembler masm, Register src2, Register dst) {
             super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fstoi.getValue(),
@@ -655,6 +725,13 @@
         }
     }
 
+    public static class Ld extends Fmt3b {
+        public Ld(SPARCAssembler masm, SPARCAddress src, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Ldf.getValue(),
+                  src.getBase().encoding(), src.getDisplacement(), dst.encoding());
+        }
+    }
+
     public static class Membar extends Fmt3b {
         public Membar(SPARCAssembler masm, MembarMask mask) {
             super(masm, Ops.ArithOp.getValue(), 0, Op3s.Membar.getValue(), 0xf, mask.getValue());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/FloatSPARCTest.java	Sun May 26 13:44:16 2013 -0400
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2013, 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.graal.compiler.sparc.test;
+
+import java.lang.reflect.Method;
+
+import org.junit.Test;
+
+public class FloatSPARCTest extends SPARCTestBase {
+
+    @Test
+    public void testAdd() {
+        compile("testAdd2F");
+        compile("testAdd2D");
+        // compile("testAddFConst");
+        // compile("testAddConstF");
+        // compile("testAddDConst");
+        // compile("testAddConstD");
+    }
+
+    public static float testAdd2F(float a, float b) {
+        return a + b;
+    }
+
+    public static double testAdd2D(double a, double b) {
+        return a + b;
+    }
+
+    public static float testAddFConst(float a) {
+        return a + 32.0F;
+    }
+
+    public static float testAddConstF(float a) {
+        return 32.0F + a;
+    }
+
+    public static double testAddDConst(double a) {
+        return a + 32.0;
+    }
+
+    public static double testAddConstD(double a) {
+        return 32.0 + a;
+    }
+
+    @Test
+    public void testSub() {
+        compile("testSub2F");
+        compile("testSub2D");
+        // compile("testSubFConst");
+        // compile("testSubConstF");
+        // compile("testSubDConst");
+        // compile("testSubConstD");
+    }
+
+    public static float testSub2F(float a, float b) {
+        return a - b;
+    }
+
+    public static double testSub2D(double a, double b) {
+        return a - b;
+    }
+
+    public static float testSubFConst(float a) {
+        return a - 32.0F;
+    }
+
+    public static float testSubConstF(float a) {
+        return 32.0F - a;
+    }
+
+    public static double testSubDConst(double a) {
+        return a - 32.0;
+    }
+
+    public static double testSubConstD(double a) {
+        return 32.0 - a;
+    }
+
+    @Test
+    public void testMul() {
+        compile("testMul2F");
+        compile("testMul2D");
+        // compile("testMulFConst");
+        // compile("testMulConstF");
+        // compile("testMulDConst");
+        // compile("testMulConstD");
+    }
+
+    public static float testMul2F(float a, float b) {
+        return a * b;
+    }
+
+    public static double testMul2D(double a, double b) {
+        return a * b;
+    }
+
+    public static float testMulFConst(float a) {
+        return a * 32.0F;
+    }
+
+    public static float testMulConstF(float a) {
+        return 32.0F * a;
+    }
+
+    public static double testMulDConst(double a) {
+        return a * 32.0;
+    }
+
+    public static double testMulConstD(double a) {
+        return 32.0 * a;
+    }
+
+    @Test
+    public void testDiv() {
+        compile("testDiv2F");
+        compile("testDiv2D");
+        // compile("testDivFConst");
+        // compile("testDivConstF");
+        // compile("testDivDConst");
+        // compile("testDivConstD");
+    }
+
+    public static float testDiv2F(float a, float b) {
+        return a / b;
+    }
+
+    public static double testDiv2D(double a, double b) {
+        return a / b;
+    }
+
+    public static float testDivFConst(float a) {
+        return a / 32.0F;
+    }
+
+    public static float testDivConstF(float a) {
+        return 32.0F / a;
+    }
+
+    public static double testDivDConst(double a) {
+        return a / 32.0;
+    }
+
+    public static double testDivConstD(double a) {
+        return 32.0 / a;
+    }
+
+    @Test
+    public void testNeg() {
+        compile("testNeg2F");
+        compile("testNeg2D");
+    }
+
+    public static float testNeg2F(float a) {
+        return -a;
+    }
+
+    public static double testNeg2D(double a) {
+        return -a;
+    }
+
+    @Test
+    public void testRem() {
+        // need linkage to PTX remainder()
+        // compile("testRem2F");
+        // compile("testRem2D");
+    }
+
+    public static float testRem2F(float a, float b) {
+        return a % b;
+    }
+
+    public static double testRem2D(double a, double b) {
+        return a % b;
+    }
+
+    @Test
+    public void testFloatConversion() {
+        // compile("testF2I");
+        // compile("testF2L");
+        // compile("testF2D");
+        // compile("testD2I");
+        // compile("testD2L");
+        // compile("testD2F");
+    }
+
+    public static int testF2I(float a) {
+        return (int) a;
+    }
+
+    public static long testF2L(float a) {
+        return (long) a;
+    }
+
+    public static double testF2D(float a) {
+        return a;
+    }
+
+    public static int testD2I(double a) {
+        return (int) a;
+    }
+
+    public static long testD2L(double a) {
+        return (long) a;
+    }
+
+    public static float testD2F(double a) {
+        return (float) a;
+    }
+
+    public static void main(String[] args) {
+        FloatSPARCTest test = new FloatSPARCTest();
+        for (Method m : FloatSPARCTest.class.getMethods()) {
+            String name = m.getName();
+            if (m.getAnnotation(Test.class) == null && name.startsWith("test") && name.startsWith("testRem") == false) {
+                // CheckStyle: stop system..print check
+                System.out.println(name + ": \n" + new String(test.compile(name).getTargetCode()));
+                // CheckStyle: resume system..print check
+            }
+        }
+    }
+}
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Sun May 26 13:15:51 2013 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Sun May 26 13:44:16 2013 -0400
@@ -127,7 +127,10 @@
 
     @Override
     public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label) {
-        throw new InternalError("NYI");
+        switch (left.getKind().getStackKind()) {
+            default:
+                throw GraalInternalError.shouldNotReachHere("" + left.getKind());
+        }
     }
 
     @Override
@@ -269,7 +272,21 @@
 
     @Override
     public Value emitNegate(Value input) {
-        throw new InternalError("NYI");
+        Variable result = newVariable(input.getKind());
+        switch (input.getKind()) {
+            case Int:
+                append(new Op1Stack(INEG, result, input));
+                break;
+            case Float:
+                append(new Op1Stack(FNEG, result, input));
+                break;
+            case Double:
+                append(new Op1Stack(DNEG, result, input));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
     }
 
     @Override
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Sun May 26 13:15:51 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Sun May 26 13:44:16 2013 -0400
@@ -26,9 +26,17 @@
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Add;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.And;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Fadds;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Faddd;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Fdivs;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Fdivd;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Fdtoi;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Fmuls;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Fmuld;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Fnegs;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Fnegd;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Fstoi;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Fsubs;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Fsubd;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Mulx;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Or;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Sdivx;
@@ -48,29 +56,26 @@
 import com.oracle.graal.lir.LIRFrameState;
 import com.oracle.graal.lir.asm.TargetMethodAssembler;
 
-// @formatter:off
 public enum SPARCArithmetic {
     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, FREM, FAND, FOR, FXOR,
-    DADD, DSUB, DMUL, DDIV, DREM, DAND, DOR, DXOR,
-    INEG, LNEG, FNEG, DNEG,
-    I2L, L2I, I2B, I2C, I2S,
-    F2D, D2F,
-    I2F, I2D, F2I, D2I,
-    L2F, L2D, F2L, D2L,
+    FADD, FSUB, FMUL, FDIV, FREM, FAND, FOR, FXOR, DADD, DSUB, DMUL, DDIV, DREM, DAND, DOR, DXOR,
+    INEG, LNEG, FNEG, DNEG, I2L, L2I, I2B, I2C, I2S, F2D, D2F, I2F, I2D, F2I, D2I, L2F, L2D, F2L, D2L,
     MOV_I2F, MOV_L2D, MOV_F2I, MOV_D2L;
 
-
     /**
-     * Unary operation with separate source and destination operand. 
+     * Unary operation with separate source and destination operand.
      */
     public static class Unary2Op extends SPARCLIRInstruction {
-        @Opcode private final SPARCArithmetic opcode;
-        @Def({REG}) protected AllocatableValue result;
-        @Use({REG, STACK}) protected AllocatableValue x;
+        @Opcode
+        private final SPARCArithmetic opcode;
+        @Def({ REG })
+        protected AllocatableValue result;
+        @Use({ REG, STACK })
+        protected AllocatableValue x;
 
-        public Unary2Op(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x) {
+        public Unary2Op(SPARCArithmetic opcode, AllocatableValue result,
+                AllocatableValue x) {
             this.opcode = opcode;
             this.result = result;
             this.x = x;
@@ -84,14 +89,18 @@
     }
 
     /**
-     * Unary operation with single operand for source and destination. 
+     * Unary operation with single operand for source and destination.
      */
     public static class Unary1Op extends SPARCLIRInstruction {
-        @Opcode private final SPARCArithmetic opcode;
-        @Def({REG, HINT}) protected AllocatableValue result;
-        @Use({REG, STACK}) protected AllocatableValue x;
+        @Opcode
+        private final SPARCArithmetic opcode;
+        @Def({ REG, HINT })
+        protected AllocatableValue result;
+        @Use({ REG, STACK })
+        protected AllocatableValue x;
 
-        public Unary1Op(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x) {
+        public Unary1Op(SPARCArithmetic opcode, AllocatableValue result,
+                AllocatableValue x) {
             this.opcode = opcode;
             this.result = result;
             this.x = x;
@@ -104,9 +113,12 @@
     }
 
     public static class Op1Stack extends SPARCLIRInstruction {
-        @Opcode private final SPARCArithmetic opcode;
-        @Def({REG, HINT}) protected Value result;
-        @Use({REG, STACK, CONST}) protected Value x;
+        @Opcode
+        private final SPARCArithmetic opcode;
+        @Def({ REG, HINT })
+        protected Value result;
+        @Use({ REG, STACK, CONST })
+        protected Value x;
 
         public Op1Stack(SPARCArithmetic opcode, Value result, Value x) {
             this.opcode = opcode;
@@ -121,10 +133,14 @@
     }
 
     public static class Op2Stack extends SPARCLIRInstruction {
-        @Opcode private final SPARCArithmetic opcode;
-        @Def({REG, HINT}) protected Value result;
-        @Use({REG, STACK, CONST}) protected Value x;
-        @Alive({REG, STACK, CONST}) protected Value y;
+        @Opcode
+        private final SPARCArithmetic opcode;
+        @Def({ REG, HINT })
+        protected Value result;
+        @Use({ REG, STACK, CONST })
+        protected Value x;
+        @Alive({ REG, STACK, CONST })
+        protected Value y;
 
         public Op2Stack(SPARCArithmetic opcode, Value result, Value x, Value y) {
             this.opcode = opcode;
@@ -146,10 +162,14 @@
     }
 
     public static class Op2Reg extends SPARCLIRInstruction {
-        @Opcode private final SPARCArithmetic opcode;
-        @Def({REG, HINT}) protected Value result;
-        @Use({REG, STACK, CONST}) protected Value x;
-        @Alive({REG, CONST}) protected Value y;
+        @Opcode
+        private final SPARCArithmetic opcode;
+        @Def({ REG, HINT })
+        protected Value result;
+        @Use({ REG, STACK, CONST })
+        protected Value x;
+        @Alive({ REG, CONST })
+        protected Value y;
 
         public Op2Reg(SPARCArithmetic opcode, Value result, Value x, Value y) {
             this.opcode = opcode;
@@ -171,10 +191,14 @@
     }
 
     public static class ShiftOp extends SPARCLIRInstruction {
-        @Opcode private final SPARCArithmetic opcode;
-        @Def({REG, HINT}) protected Value result;
-        @Use({REG, STACK, CONST}) protected Value x;
-        @Alive({REG, CONST}) protected Value y;
+        @Opcode
+        private final SPARCArithmetic opcode;
+        @Def({ REG, HINT })
+        protected Value result;
+        @Use({ REG, STACK, CONST })
+        protected Value x;
+        @Alive({ REG, CONST })
+        protected Value y;
 
         public ShiftOp(SPARCArithmetic opcode, Value result, Value x, Value y) {
             this.opcode = opcode;
@@ -197,81 +221,108 @@
     }
 
     @SuppressWarnings("unused")
-    protected static void emit(SPARCAssembler masm, SPARCArithmetic opcode, Value result) {
+    protected static void emit(SPARCAssembler masm, SPARCArithmetic opcode,
+            Value result) {
         switch (opcode) {
-            case L2I:
-                new Sra(masm, asLongReg(result), 0, asIntReg(result));
-                break;
-            case I2C:
-                new Sll(masm, asIntReg(result), 16, asIntReg(result));
-                new Srl(masm, asIntReg(result), 16, asIntReg(result));
-                break;
-            default:
-                throw GraalInternalError.shouldNotReachHere("missing: "  + opcode);
+        case L2I:
+            new Sra(masm, asLongReg(result), 0, asIntReg(result));
+            break;
+        case I2C:
+            new Sll(masm, asIntReg(result), 16, asIntReg(result));
+            new Srl(masm, asIntReg(result), 16, asIntReg(result));
+            break;
+        default:
+            throw GraalInternalError.shouldNotReachHere("missing: " + opcode);
         }
     }
 
     @SuppressWarnings("unused")
-    public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info) {
+    public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm,
+            SPARCArithmetic opcode, Value dst, Value src1, Value src2,
+            LIRFrameState info) {
         int exceptionOffset = -1;
         if (isConstant(src1)) {
-            if (is_simm13(tasm.asIntConst(src1))) {
-                switch (opcode) {
-                case ISUB:
-                    new Add(masm, asIntReg(src2), -(tasm.asIntConst(src1)), asIntReg(dst));
-                    break;
-                case IAND:  throw new InternalError("NYI");
-                case IDIV:
-                    throw new InternalError("NYI");
-                    // new Sdivx(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
-                case FSUB:  throw new InternalError("NYI");
-                case FDIV:  throw new InternalError("NYI");
-                case DSUB:  throw new InternalError("NYI");
-                case DDIV:  throw new InternalError("NYI");
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
-                }
-            } else {
+            switch (opcode) {
+            case ISUB:
+                assert is_simm13(tasm.asIntConst(src1));
+                new Add(masm, asIntReg(src2), -(tasm.asIntConst(src1)),
+                        asIntReg(dst));
+                break;
+            case IAND:
+                throw new InternalError("NYI");
+            case IDIV:
+                assert is_simm13(tasm.asIntConst(src1));
                 throw new InternalError("NYI");
+                // new Sdivx(masm, asIntReg(src1), asIntReg(src2),
+                // asIntReg(dst));
+            case FSUB:
+                throw new InternalError("NYI");
+            case FDIV:
+                throw new InternalError("NYI");
+            case DSUB:
+                throw new InternalError("NYI");
+            case DDIV:
+                throw new InternalError("NYI");
+            default:
+                throw GraalInternalError.shouldNotReachHere();
             }
         } else if (isConstant(src2)) {
-            if (is_simm13(tasm.asIntConst(src2))) {
-                switch (opcode) {
-                case IADD:
-                    new Add(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
-                    break;
-                case ISUB:
-                    new Sub(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
-                    break;
-                case IMUL:
-                    new Mulx(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
-                    break;
-                case IAND:
-                    new And(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
-                    break;
-                case ISHL:
-                    new Sll(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
-                    break;
-                case ISHR:
-                    new Srl(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
-                    break;
-                case IUSHR:
-                    new Sra(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
-                    break;
-                case IXOR:  throw new InternalError("NYI");
-                case LXOR:  throw new InternalError("NYI");
-                case LUSHR: throw new InternalError("NYI");
-                case FADD:  throw new InternalError("NYI");
-                case FMUL:  throw new InternalError("NYI");
-                case FDIV:  throw new InternalError("NYI");
-                case DADD:  throw new InternalError("NYI");
-                case DMUL:  throw new InternalError("NYI");
-                case DDIV:  throw new InternalError("NYI");
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
-                }
-            } else {
+            switch (opcode) {
+            case IADD:
+                assert is_simm13(tasm.asIntConst(src2));
+                new Add(masm, asIntReg(src1), tasm.asIntConst(src2),
+                        asIntReg(dst));
+                break;
+            case ISUB:
+                assert is_simm13(tasm.asIntConst(src2));
+                new Sub(masm, asIntReg(src1), tasm.asIntConst(src2),
+                        asIntReg(dst));
+                break;
+            case IMUL:
+                assert is_simm13(tasm.asIntConst(src2));
+                new Mulx(masm, asIntReg(src1), tasm.asIntConst(src2),
+                        asIntReg(dst));
+                break;
+            case IAND:
+                assert is_simm13(tasm.asIntConst(src2));
+                new And(masm, asIntReg(src1), tasm.asIntConst(src2),
+                        asIntReg(dst));
+                break;
+            case ISHL:
+                assert is_simm13(tasm.asIntConst(src2));
+                new Sll(masm, asIntReg(src1), tasm.asIntConst(src2),
+                        asIntReg(dst));
+                break;
+            case ISHR:
+                assert is_simm13(tasm.asIntConst(src2));
+                new Srl(masm, asIntReg(src1), tasm.asIntConst(src2),
+                        asIntReg(dst));
+                break;
+            case IUSHR:
+                assert is_simm13(tasm.asIntConst(src2));
+                new Sra(masm, asIntReg(src1), tasm.asIntConst(src2),
+                        asIntReg(dst));
+                break;
+            case IXOR:
                 throw new InternalError("NYI");
+            case LXOR:
+                throw new InternalError("NYI");
+            case LUSHR:
+                throw new InternalError("NYI");
+            case FADD:
+                throw new InternalError("NYI");
+            case FMUL:
+                throw new InternalError("NYI");
+            case FDIV:
+                throw new InternalError("NYI");
+            case DADD:
+                throw new InternalError("NYI");
+            case DMUL:
+                throw new InternalError("NYI");
+            case DDIV:
+                throw new InternalError("NYI");
+            default:
+                throw GraalInternalError.shouldNotReachHere();
             }
         } else {
             switch (opcode) {
@@ -305,7 +356,8 @@
             case IUSHR:
                 new Sra(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
                 break;
-            case IREM:  throw new InternalError("NYI");
+            case IREM:
+                throw new InternalError("NYI");
             case LADD:
                 new Add(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
                 break;
@@ -316,7 +368,8 @@
                 new Mulx(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
                 break;
             case LDIV:
-                new Sdivx(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
+                new Sdivx(masm, asLongReg(src1), asLongReg(src2),
+                        asLongReg(dst));
                 break;
             case LAND:
                 new And(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
@@ -336,23 +389,47 @@
             case LUSHR:
                 new Sra(masm, asLongReg(src1), asLongReg(src2), asIntReg(dst));
                 break;
-            case LREM:  throw new InternalError("NYI");
+            case LREM:
+                throw new InternalError("NYI");
             case FADD:
-                new Fadds(masm, asFloatReg(src1), asFloatReg(src2), asFloatReg(dst));
+                new Fadds(masm, asFloatReg(src1), asFloatReg(src2),
+                        asFloatReg(dst));
                 break;
             case FSUB:
-                new Fsubs(masm, asFloatReg(src1), asFloatReg(src2), asFloatReg(dst));
+                new Fsubs(masm, asFloatReg(src1), asFloatReg(src2),
+                        asFloatReg(dst));
+                break;
+            case FMUL:
+                new Fmuls(masm, asFloatReg(src1), asFloatReg(src2),
+                        asFloatReg(dst));
+                break;
+            case FDIV:
+                new Fdivs(masm, asFloatReg(src1), asFloatReg(src2),
+                        asFloatReg(dst));
+                break;
+            case FREM:
+                throw new InternalError("NYI");
+            case DADD:
+                new Faddd(masm, asDoubleReg(src1), asDoubleReg(src2),
+                        asDoubleReg(dst));
                 break;
-            case FMUL:  throw new InternalError("NYI");
-            case FDIV:  throw new InternalError("NYI");
-            case FREM:  throw new InternalError("NYI");
-            case DADD:  throw new InternalError("NYI");
-            case DSUB:  throw new InternalError("NYI");
-            case DMUL:  throw new InternalError("NYI");
-            case DDIV:  throw new InternalError("NYI");
-            case DREM:  throw new InternalError("NYI");
+            case DSUB:
+                new Fsubd(masm, asDoubleReg(src1), asDoubleReg(src2),
+                        asDoubleReg(dst));
+                break;
+            case DMUL:
+                new Fmuld(masm, asDoubleReg(src1), asDoubleReg(src2),
+                        asDoubleReg(dst));
+                break;
+            case DDIV:
+                new Fdivd(masm, asDoubleReg(src1), asDoubleReg(src2),
+                        asDoubleReg(dst));
+                break;
+            case DREM:
+                throw new InternalError("NYI");
             default:
-                throw GraalInternalError.shouldNotReachHere("missing: "  + opcode);
+                throw GraalInternalError.shouldNotReachHere("missing: "
+                        + opcode);
             }
         }
 
@@ -363,36 +440,45 @@
     }
 
     @SuppressWarnings("unused")
-    public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm, SPARCArithmetic opcode,
-                            Value dst, Value src, LIRFrameState info) {
+    public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm,
+            SPARCArithmetic opcode, Value dst, Value src, LIRFrameState info) {
         int exceptionOffset = -1;
         if (isRegister(src)) {
             switch (opcode) {
-                case I2L:
-                    new Sra(masm, asIntReg(src), 0, asLongReg(dst));
-                    break;
-                case I2B:
-                    new Sll(masm, asIntReg(src), 24, asIntReg(src));
-                    new Srl(masm, asIntReg(dst), 24, asIntReg(src));
-                    break;
-                case I2F:
-                    new Fstoi(masm, asIntReg(src), asFloatReg(dst));
-                    break;
-                case I2D:
-                    new Fdtoi(masm, asIntReg(src), asDoubleReg(dst));
-                    break;
-                default:
-                    throw GraalInternalError.shouldNotReachHere("missing: "  + opcode);
+            case I2L:
+                new Sra(masm, asIntReg(src), 0, asLongReg(dst));
+                break;
+            case I2B:
+                new Sll(masm, asIntReg(src), 24, asIntReg(src));
+                new Srl(masm, asIntReg(dst), 24, asIntReg(src));
+                break;
+            case I2F:
+                new Fstoi(masm, asIntReg(src), asFloatReg(dst));
+                break;
+            case I2D:
+                new Fdtoi(masm, asIntReg(src), asDoubleReg(dst));
+                break;
+            case FNEG:
+                new Fnegs(masm, asFloatReg(src), asFloatReg(dst));
+                break;
+            case DNEG:
+                new Fnegd(masm, asDoubleReg(src), asDoubleReg(dst));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere("missing: "
+                        + opcode);
             }
         } else if (isConstant(src)) {
             switch (opcode) {
-                default:
-                    throw GraalInternalError.shouldNotReachHere("missing: "  + opcode);
+            default:
+                throw GraalInternalError.shouldNotReachHere("missing: "
+                        + opcode);
             }
         } else {
             switch (opcode) {
-                default:
-                    throw GraalInternalError.shouldNotReachHere("missing: "  + opcode);
+            default:
+                throw GraalInternalError.shouldNotReachHere("missing: "
+                        + opcode);
             }
         }
 
@@ -402,19 +488,34 @@
         }
     }
 
-    private static final int max13 =  ((1 << 12) - 1);
+    private static final int max13 = ((1 << 12) - 1);
     private static final int min13 = -(1 << 12);
 
     private static boolean is_simm13(int src) {
         return min13 <= src && src <= max13;
     }
 
-    private static void verifyKind(SPARCArithmetic opcode, Value result, Value x, Value y) {
-        if (((opcode.name().startsWith("I") && result.getKind() == Kind.Int && x.getKind().getStackKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int)
-            || (opcode.name().startsWith("L") && result.getKind() == Kind.Long && x.getKind() == Kind.Long && y.getKind() == Kind.Long)
-            || (opcode.name().startsWith("F") && result.getKind() == Kind.Float && x.getKind() == Kind.Float && y.getKind() == Kind.Float)
-            || (opcode.name().startsWith("D") && result.getKind() == Kind.Double && x.getKind() == Kind.Double && y.getKind() == Kind.Double)) == false) {
-                throw GraalInternalError.shouldNotReachHere("opcode: "  + opcode.name() + " x: " + x.getKind() + " y: " + y.getKind());
+    private static void verifyKind(SPARCArithmetic opcode, Value result,
+                                   Value x, Value y) {
+        String name = opcode.name();
+        if (((name.startsWith("I") && result.getKind() == Kind.Int
+                && x.getKind().getStackKind() == Kind.Int
+                && y.getKind().getStackKind() == Kind.Int)
+                || (name.startsWith("L")
+                        && result.getKind() == Kind.Long
+                        && x.getKind() == Kind.Long
+                        && y.getKind() == Kind.Long)
+                || (name.startsWith("F")
+                        && result.getKind() == Kind.Float
+                        && x.getKind() == Kind.Float
+                        && y.getKind() == Kind.Float)
+                || (name.startsWith("D")
+                        && result.getKind() == Kind.Double
+                        && x.getKind() == Kind.Double
+                        && y.getKind() == Kind.Double)) == false) {
+            throw GraalInternalError.shouldNotReachHere("opcode: "
+                    + opcode.name() + " x: " + x.getKind() + " y: "
+                    + y.getKind());
         }
     }
 }