changeset 22693:f04f2d2b2c42

[SPARC] Remove JavaKind dependency from SPARC backend, clearing up SPARCArithmetic
author Stefan Anzinger <stefan.anzinger@oracle.com>
date Wed, 23 Sep 2015 15:42:58 +0200
parents f87ae6a74d88
children ce6eba1c6b9f
files graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRKindTool.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRKindTool.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotStrategySwitchOp.java graal/com.oracle.graal.lir.jtt/src/com/oracle/graal/lir/jtt/ConstantStackCastTest.java graal/com.oracle.graal.lir.jtt/src/com/oracle/graal/lir/jtt/StackMoveTest.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFloatCompareOp.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFrameMap.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCOP3Op.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCOPFOp.java
diffstat 27 files changed, 1329 insertions(+), 1858 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Wed Sep 23 15:42:58 2015 +0200
@@ -83,7 +83,6 @@
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fabss;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Faddd;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fadds;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fandd;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdivd;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdivs;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdtoi;
@@ -92,9 +91,7 @@
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fitod;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fitos;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmovd;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmovdcc;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmovs;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmovscc;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmuld;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmuls;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fnegd;
@@ -140,9 +137,10 @@
 import jdk.internal.jvmci.code.RegisterConfig;
 import jdk.internal.jvmci.code.TargetDescription;
 import jdk.internal.jvmci.meta.JavaConstant;
-import jdk.internal.jvmci.meta.JavaKind;
+import jdk.internal.jvmci.meta.PlatformKind;
 import jdk.internal.jvmci.sparc.SPARC;
 import jdk.internal.jvmci.sparc.SPARC.CPUFeature;
+import jdk.internal.jvmci.sparc.SPARCKind;
 
 import com.oracle.graal.asm.Assembler;
 import com.oracle.graal.asm.Label;
@@ -251,60 +249,60 @@
         }
     }
 
+    private static final int COMMUTATIVE = 1;
+    private static final int BINARY = 2;
+    private static final int UNARY = 4;
+    private static final int VOID_IN = 8;
+
     public static enum Op3s {
         // @formatter:off
-
-        Add(0x00, "add", ArithOp),
-        And(0x01, "and", ArithOp),
-        Or(0x02, "or", ArithOp),
-        Xor(0x03, "xor", ArithOp),
-        Sub(0x04, "sub", ArithOp),
-        Andn(0x05, "andn", ArithOp),
-        Orn(0x06, "orn", ArithOp),
-        Xnor(0x07, "xnor", ArithOp),
-        Addc(0x08, "addc", ArithOp),
-        Mulx(0x09, "mulx", ArithOp),
-        Umul(0x0A, "umul", ArithOp),
-        Smul(0x0B, "smul", ArithOp),
-        Subc(0x0C, "subc", ArithOp),
-        Udivx(0x0D, "udivx", ArithOp),
-        Udiv(0x0E, "udiv", ArithOp),
-        Sdiv(0x0F, "sdiv", ArithOp),
-
-        Addcc(0x10, "addcc", ArithOp),
-        Andcc(0x11, "andcc", ArithOp),
-        Orcc(0x12, "orcc", ArithOp),
-        Xorcc(0x13, "xorcc", ArithOp),
-        Subcc(0x14, "subcc", ArithOp),
-        Andncc(0x15, "andncc", ArithOp),
-        Orncc(0x16, "orncc", ArithOp),
-        Xnorcc(0x17, "xnorcc", ArithOp),
-        Addccc(0x18, "addccc", ArithOp),
-
-        Umulcc(0x1A, "umulcc", ArithOp),
-        Smulcc(0x1B, "smulcc", ArithOp),
-        Subccc(0x1C, "subccc", ArithOp),
-        Udivcc(0x1E, "udivcc", ArithOp),
-        Sdivcc(0x1F, "sdivcc", ArithOp),
-
-        Taddcc(0x20, "taddcc", ArithOp),
-        Tsubcc(0x21, "tsubcc", ArithOp),
-        Taddcctv(0x22, "taddcctv", ArithOp),
-        Tsubcctv(0x23, "tsubcctv", ArithOp),
-        Mulscc(0x24, "mulscc", ArithOp),
-        Sll(0x25, "sll", ArithOp),
-        Sllx(0x25, "sllx", ArithOp),
-        Srl(0x26, "srl", ArithOp),
-        Srlx(0x26, "srlx", ArithOp),
-        Sra(0x27, "srax", ArithOp),
-        Srax(0x27, "srax", ArithOp),
+        Add(0x00, "add", ArithOp, BINARY | COMMUTATIVE),
+        And(0x01, "and", ArithOp, BINARY | COMMUTATIVE),
+        Or(0x02, "or", ArithOp, BINARY | COMMUTATIVE),
+        Xor(0x03, "xor", ArithOp, BINARY | COMMUTATIVE),
+        Sub(0x04, "sub", ArithOp, BINARY),
+        Andn(0x05, "andn", ArithOp, BINARY | COMMUTATIVE),
+        Orn(0x06, "orn", ArithOp, BINARY | COMMUTATIVE),
+        Xnor(0x07, "xnor", ArithOp, BINARY | COMMUTATIVE),
+        Addc(0x08, "addc", ArithOp, BINARY | COMMUTATIVE),
+        Mulx(0x09, "mulx", ArithOp, BINARY | COMMUTATIVE),
+        Umul(0x0A, "umul", ArithOp, BINARY | COMMUTATIVE),
+        Smul(0x0B, "smul", ArithOp, BINARY | COMMUTATIVE),
+        Subc(0x0C, "subc", ArithOp, BINARY),
+        Udivx(0x0D, "udivx", ArithOp, BINARY),
+        Udiv(0x0E, "udiv", ArithOp, BINARY),
+        Sdiv(0x0F, "sdiv", ArithOp, BINARY),
+
+        Addcc(0x10, "addcc", ArithOp, BINARY | COMMUTATIVE),
+        Andcc(0x11, "andcc", ArithOp, BINARY | COMMUTATIVE),
+        Orcc(0x12, "orcc", ArithOp, BINARY | COMMUTATIVE),
+        Xorcc(0x13, "xorcc", ArithOp, BINARY | COMMUTATIVE),
+        Subcc(0x14, "subcc", ArithOp, BINARY | COMMUTATIVE),
+        Andncc(0x15, "andncc", ArithOp, BINARY | COMMUTATIVE),
+        Orncc(0x16, "orncc", ArithOp, BINARY | COMMUTATIVE),
+        Xnorcc(0x17, "xnorcc", ArithOp, BINARY | COMMUTATIVE),
+        Addccc(0x18, "addccc", ArithOp, BINARY | COMMUTATIVE),
+
+        Umulcc(0x1A, "umulcc", ArithOp, BINARY | COMMUTATIVE),
+        Smulcc(0x1B, "smulcc", ArithOp, BINARY | COMMUTATIVE),
+        Subccc(0x1C, "subccc", ArithOp, BINARY),
+        Udivcc(0x1E, "udivcc", ArithOp, BINARY),
+        Sdivcc(0x1F, "sdivcc", ArithOp, BINARY),
+
+        Mulscc(0x24, "mulscc", ArithOp, BINARY | COMMUTATIVE),
+        Sll(0x25, "sll", ArithOp, BINARY),
+        Sllx(0x25, "sllx", ArithOp, BINARY),
+        Srl(0x26, "srl", ArithOp, BINARY),
+        Srlx(0x26, "srlx", ArithOp, BINARY),
+        Sra(0x27, "srax", ArithOp, BINARY),
+        Srax(0x27, "srax", ArithOp, BINARY),
         Membar(0x28, "membar", ArithOp),
 
         Flushw(0x2B, "flushw", ArithOp),
         Movcc(0x2C, "movcc", ArithOp),
-        Sdivx(0x2D, "sdivx", ArithOp),
-        Popc(0x2E, "popc", ArithOp),
-        Movr(0x2F, "movr", ArithOp),
+        Sdivx(0x2D, "sdivx", ArithOp, BINARY),
+        Popc(0x2E, "popc", ArithOp, UNARY),
+        Movr(0x2F, "movr", ArithOp, BINARY),
 
         Fpop1(0b11_0100, "fpop1", ArithOp),
         Fpop2(0b11_0101, "fpop2", ArithOp),
@@ -369,11 +367,17 @@
         private final int value;
         private final String operator;
         private final Ops op;
+        private final int flags;
 
         private Op3s(int value, String name, Ops op) {
+            this(value, name, op, 0);
+        }
+
+        private Op3s(int value, String name, Ops op, int flags) {
             this.value = value;
             this.operator = name;
             this.op = op;
+            this.flags = flags;
         }
 
         public int getValue() {
@@ -400,82 +404,91 @@
                     return false;
             }
         }
+
+        public boolean isBinary() {
+            return (flags & BINARY) != 0;
+        }
+
+        public boolean isUnary() {
+            return (flags & UNARY) != 0;
+        }
+
+        public boolean isCommutative() {
+            return (flags & COMMUTATIVE) != 0;
+        }
     }
 
     public static enum Opfs {
         // @formatter:off
 
-        Fmovs(0b0_0000_0001, "fmovs", Fpop1),
-        Fmovd(0b0_0000_0010, "fmovd", Fpop1),
-        Fmovq(0b0_0000_0011, "fmovq", Fpop1),
-        Fmovscc(0b00_0001, "fmovscc", Fpop2),
-        Fmovdcc(0b00_0010, "fmovdcc", Fpop2),
-        Fnegs(0x05, "fnegs", Fpop1),
-        Fnegd(0x06, "fnegd", Fpop1),
-        Fnegq(0x07, "fnegq", Fpop1),
-        Fabss(0x09, "fabss", Fpop1),
-        Fabsd(0x0A, "fabsd", Fpop1),
-        Fabsq(0x0B, "fabsq", Fpop1),
+        Fmovs(0b0_0000_0001, "fmovs", Fpop1, UNARY),
+        Fmovd(0b0_0000_0010, "fmovd", Fpop1, UNARY),
+        Fmovq(0b0_0000_0011, "fmovq", Fpop1, UNARY),
+        Fnegs(0x05, "fnegs", Fpop1, UNARY),
+        Fnegd(0x06, "fnegd", Fpop1, UNARY),
+        Fnegq(0x07, "fnegq", Fpop1, UNARY),
+        Fabss(0x09, "fabss", Fpop1, UNARY),
+        Fabsd(0x0A, "fabsd", Fpop1, UNARY),
+        Fabsq(0x0B, "fabsq", Fpop1, UNARY),
 
         // start VIS1
-        Fpadd32(0x52, "fpadd32", Impdep1),
-        Fzerod(0x60, "fzerod", Impdep1),
-        Fzeros(0x61, "fzeros", Impdep1),
-        Fnot2d(0x66, "fnot1d", Impdep1),
-        Fsrc2d(0x78, "fsrc2d", Impdep1),
-        Fsrc2s(0x79, "fsrc2s", Impdep1),
-        Fandd(0b0_0111_0000, "fandd", Impdep1),
-        Fands(0b0_0111_0001, "fands", Impdep1),
+        Fpadd32(0x52, "fpadd32", Impdep1, BINARY | COMMUTATIVE),
+        Fzerod(0x60, "fzerod", Impdep1, VOID_IN),
+        Fzeros(0x61, "fzeros", Impdep1, VOID_IN),
+        Fsrc2d(0x78, "fsrc2d", Impdep1, UNARY),
+        Fsrc2s(0x79, "fsrc2s", Impdep1, UNARY),
         // end VIS1
 
         // start VIS3
-        Movdtox(0x110, "movdtox", Impdep1),
-        Movstouw(0x111, "movstouw", Impdep1),
-        Movstosw(0x113, "movstosw", Impdep1),
-        Movxtod(0x118, "movxtod", Impdep1),
-        Movwtos(0b1_0001_1001, "movwtos", Impdep1),
-        UMulxhi(0b0_0001_0110, "umulxhi", Impdep1),
+        Movdtox(0x110, "movdtox", Impdep1, UNARY),
+        Movstouw(0x111, "movstouw", Impdep1, UNARY),
+        Movstosw(0x113, "movstosw", Impdep1, UNARY),
+        Movxtod(0x118, "movxtod", Impdep1, UNARY),
+        Movwtos(0b1_0001_1001, "movwtos", Impdep1, UNARY),
+        UMulxhi(0b0_0001_0110, "umulxhi", Impdep1, BINARY | COMMUTATIVE),
         // end VIS3
 
-        Fadds(0x41, "fadds", Fpop1),
-        Faddd(0x42, "faddd", Fpop1),
-        Fsubs(0x45, "fsubs", Fpop1),
-        Fsubd(0x46, "fsubd", Fpop1),
-        Fmuls(0x49, "fmuls", Fpop1),
-        Fmuld(0x4A, "fmuld", Fpop1),
-        Fdivs(0x4D, "fdivs", Fpop1),
-        Fdivd(0x4E, "fdivd", Fpop1),
-
-        Fsqrts(0x29, "fsqrts", Fpop1),
-        Fsqrtd(0x2A, "fsqrtd", Fpop1),
-
-        Fsmuld(0x69, "fsmuld", Fpop1),
-
-        Fstoi(0xD1, "fstoi", Fpop1),
-        Fdtoi(0xD2, "fdtoi", Fpop1),
-        Fstox(0x81, "fstox", Fpop1),
-        Fdtox(0x82, "fdtox", Fpop1),
-        Fxtos(0x84, "fxtos", Fpop1),
-        Fxtod(0x88, "fxtod", Fpop1),
-        Fitos(0xC4, "fitos", Fpop1),
-        Fdtos(0xC6, "fdtos", Fpop1),
-        Fitod(0xC8, "fitod", Fpop1),
-        Fstod(0xC9, "fstod", Fpop1),
-
-
-        Fcmps(0x51, "fcmps", Fpop2),
-        Fcmpd(0x52, "fcmpd", Fpop2);
+        Fadds(0x41, "fadds", Fpop1, BINARY | COMMUTATIVE),
+        Faddd(0x42, "faddd", Fpop1, BINARY | COMMUTATIVE),
+        Fsubs(0x45, "fsubs", Fpop1, BINARY),
+        Fsubd(0x46, "fsubd", Fpop1, BINARY),
+        Fmuls(0x49, "fmuls", Fpop1, BINARY | COMMUTATIVE),
+        Fmuld(0x4A, "fmuld", Fpop1, BINARY | COMMUTATIVE),
+        Fdivs(0x4D, "fdivs", Fpop1, BINARY),
+        Fdivd(0x4E, "fdivd", Fpop1, BINARY),
+
+        Fsqrts(0x29, "fsqrts", Fpop1, UNARY),
+        Fsqrtd(0x2A, "fsqrtd", Fpop1, UNARY),
+
+        Fsmuld(0x69, "fsmuld", Fpop1, BINARY | COMMUTATIVE),
+
+        Fstoi(0xD1, "fstoi", Fpop1, UNARY),
+        Fdtoi(0xD2, "fdtoi", Fpop1, UNARY),
+        Fstox(0x81, "fstox", Fpop1, UNARY),
+        Fdtox(0x82, "fdtox", Fpop1, UNARY),
+        Fxtos(0x84, "fxtos", Fpop1, UNARY),
+        Fxtod(0x88, "fxtod", Fpop1, UNARY),
+        Fitos(0xC4, "fitos", Fpop1, UNARY),
+        Fdtos(0xC6, "fdtos", Fpop1, UNARY),
+        Fitod(0xC8, "fitod", Fpop1, UNARY),
+        Fstod(0xC9, "fstod", Fpop1, UNARY),
+
+
+        Fcmps(0x51, "fcmps", Fpop2, BINARY),
+        Fcmpd(0x52, "fcmpd", Fpop2, BINARY);
 
         // @formatter:on
 
         private final int value;
         private final String operator;
         private final Op3s op3;
-
-        private Opfs(int value, String op, Op3s op3) {
+        private final int flags;
+
+        private Opfs(int value, String op, Op3s op3, int flags) {
             this.value = value;
             this.operator = op;
             this.op3 = op3;
+            this.flags = flags;
         }
 
         public int getValue() {
@@ -485,6 +498,38 @@
         public String getOperator() {
             return operator;
         }
+
+        public boolean isBinary() {
+            return (flags & BINARY) != 0;
+        }
+
+        public boolean isUnary() {
+            return (flags & UNARY) != 0;
+        }
+
+        public boolean isCommutative() {
+            return (flags & COMMUTATIVE) != 0;
+        }
+    }
+
+    public static enum OpfLow {
+        Fmovscc(0b00_0001, "fmovscc", Fpop2),
+        Fmovdcc(0b00_0010, "fmovdcc", Fpop2);
+
+        private final int value;
+        private final String operator;
+        private final Op3s op3;
+
+        private OpfLow(int value, String op, Op3s op3) {
+            this.value = value;
+            this.operator = op;
+            this.op3 = op3;
+        }
+
+        @Override
+        public String toString() {
+            return operator;
+        }
     }
 
     public enum Annul {
@@ -575,19 +620,15 @@
             return operator;
         }
 
-        public static CC forKind(JavaKind kind) {
-            boolean isInt = kind == JavaKind.Boolean || kind == JavaKind.Byte || kind == JavaKind.Char || kind == JavaKind.Short || kind == JavaKind.Int;
-            boolean isFloat = kind == JavaKind.Float || kind == JavaKind.Double;
-            boolean isLong = kind == JavaKind.Long || kind == JavaKind.Object;
-            assert isInt || isFloat || isLong;
-            if (isLong) {
+        public static CC forKind(PlatformKind kind) {
+            if (kind.equals(SPARCKind.DWORD)) {
                 return Xcc;
-            } else if (isInt) {
+            } else if (kind.equals(SPARCKind.WORD)) {
                 return Icc;
-            } else if (isFloat) {
+            } else if (kind.equals(SPARCKind.SINGLE) || kind.equals(SPARCKind.DOUBLE)) {
                 return Fcc0;
             } else {
-                throw new InternalError();
+                throw new IllegalArgumentException("Unknown kind: " + kind);
             }
         }
     }
@@ -829,10 +870,15 @@
         private static final BitSpec op2 = new ContinousBitSpec(24, 22, "op2");
         private static final BitSpec op3 = new ContinousBitSpec(24, 19, "op3");
         private static final BitSpec opf = new ContinousBitSpec(13, 5, "opf");
+        private static final BitSpec opfLow = new ContinousBitSpec(10, 5, "opfLow");
+        private static final BitSpec opfCC = new ContinousBitSpec(13, 11, "opfCC");
+        private static final BitSpec opfCond = new ContinousBitSpec(17, 14, "opfCond");
         private static final BitSpec rd = new ContinousBitSpec(29, 25, "rd");
         private static final BitSpec rs1 = new ContinousBitSpec(18, 14, "rs1");
         private static final BitSpec rs2 = new ContinousBitSpec(4, 0, "rs2");
         private static final BitSpec simm13 = new ContinousBitSpec(12, 0, true, "simm13");
+        private static final BitSpec shcnt32 = new ContinousBitSpec(4, 0, "shcnt32");
+        private static final BitSpec shcnt64 = new ContinousBitSpec(5, 0, "shcnt64");
         private static final BitSpec imm22 = new ContinousBitSpec(21, 0, "imm22");
         private static final BitSpec immAsi = new ContinousBitSpec(12, 5, "immASI");
         private static final BitSpec i = new ContinousBitSpec(13, 13, "i");
@@ -841,6 +887,7 @@
         private static final BitSpec disp30 = new ContinousBitSpec(29, 0, true, "disp30");
         private static final BitSpec a = new ContinousBitSpec(29, 29, "a");
         private static final BitSpec p = new ContinousBitSpec(19, 19, "p");
+        private static final BitSpec x = new ContinousBitSpec(12, 12, "x");
         private static final BitSpec cond = new ContinousBitSpec(28, 25, "cond");
         private static final BitSpec rcond = new ContinousBitSpec(27, 25, "rcond");
         private static final BitSpec cc = new ContinousBitSpec(21, 20, "cc");
@@ -848,6 +895,12 @@
         private static final BitSpec d16hi = new ContinousBitSpec(21, 20, "d16hi");
         private static final BitSpec d16lo = new ContinousBitSpec(13, 0, "d16lo");
         private static final BitSpec d16 = new CompositeBitSpec(d16hi, d16lo);
+        // Movcc
+        private static final BitSpec movccLo = new ContinousBitSpec(12, 11, "cc_lo");
+        private static final BitSpec movccHi = new ContinousBitSpec(18, 18, "cc_hi");
+        private static final BitSpec movccCond = new ContinousBitSpec(17, 14, "cond");
+        private static final BitSpec simm11 = new ContinousBitSpec(10, 0, true, "simm11");
+
         // CBCond
         private static final BitSpec cLo = new ContinousBitSpec(27, 25, "cLo");
         private static final BitSpec cHi = new ContinousBitSpec(29, 29, "cHi");
@@ -868,7 +921,7 @@
         public abstract boolean valueFits(int value);
     }
 
-    public static class ContinousBitSpec extends BitSpec {
+    public static final class ContinousBitSpec extends BitSpec {
         private final int hiBit;
         private final int lowBit;
         private final int width;
@@ -925,7 +978,7 @@
         }
     }
 
-    public static class CompositeBitSpec extends BitSpec {
+    public static final class CompositeBitSpec extends BitSpec {
         private final BitSpec left;
         private final int leftWidth;
         private final BitSpec right;
@@ -996,7 +1049,7 @@
     /**
      * Represents a prefix tree of {@link BitSpec} objects to find the most accurate SPARCOp.
      */
-    public static class BitKeyIndex {
+    public static final class BitKeyIndex {
         private final BitSpec spec;
         private final Map<Integer, BitKeyIndex> nodes;
         private SPARCOp op;
@@ -1083,6 +1136,9 @@
     public static final Bpr BPR = new Bpr();
     public static final Br BR = new Br();
     public static final Sethi SETHI = new Sethi();
+    public static final FMOVcc FMOVSCC = new FMOVcc(OpfLow.Fmovscc);
+    public static final FMOVcc FMOVDCC = new FMOVcc(OpfLow.Fmovdcc);
+    public static final MOVicc MOVicc = new MOVicc();
     public static final OpfOp OPF = new OpfOp();
     public static final Op3Op OP3 = new Op3Op();
     public static final SPARCOp LDST = new SPARCOp(Ops.LdstOp);
@@ -1216,7 +1272,7 @@
         public abstract boolean isConditional(int inst);
     }
 
-    public static class Bpcc extends ControlTransferOp {
+    public static final class Bpcc extends ControlTransferOp {
         public Bpcc(Op2s op2) {
             super(Ops.BranchOp, op2, true, BitSpec.disp19);
         }
@@ -1242,7 +1298,7 @@
         }
     }
 
-    public static class Br extends ControlTransferOp {
+    public static final class Br extends ControlTransferOp {
         public Br() {
             super(Ops.BranchOp, Op2s.Br, true, BitSpec.disp22);
         }
@@ -1259,7 +1315,7 @@
         }
     }
 
-    public static class Bpr extends ControlTransferOp {
+    public static final class Bpr extends ControlTransferOp {
         private static final BitKey CBCOND_KEY = new BitKey(BitSpec.cbcond, 0);
 
         public Bpr() {
@@ -1371,26 +1427,26 @@
         }
     }
 
-    public static class Sethi extends Op2Op {
+    public static final class Sethi extends Op2Op {
         public Sethi() {
             super(Ops.BranchOp, Op2s.Sethi);
         }
 
-        public Register getRS1(int word) {
+        public static Register getRS1(int word) {
             int regNum = BitSpec.rs1.getBits(word);
             return SPARC.cpuRegisters[regNum];
         }
 
-        public int getImm22(int word) {
+        public static int getImm22(int word) {
             return BitSpec.imm22.getBits(word);
         }
 
-        public boolean isNop(int inst) {
+        public static boolean isNop(int inst) {
             return getRS1(inst).equals(g0) && getImm22(inst) == 0;
         }
     }
 
-    public static class Op3Op extends SPARCOp {
+    public static final class Op3Op extends SPARCOp {
         public Op3Op() {
             super(ArithOp);
         }
@@ -1400,42 +1456,157 @@
             return OP3S[ArithOp.value & 1][BitSpec.op3.getBits(inst)];
         }
 
-        public void emit(SPARCMacroAssembler masm, Op3s opcode, Register rs1, Register rs2, Register rd) {
+        public static void emit(SPARCMacroAssembler masm, Op3s opcode, Register rs1, Register rs2, Register rd) {
             int instruction = setBits(0, opcode, rs1, rd);
             instruction = BitSpec.rs2.setBits(instruction, rs2.encoding);
             instruction = BitSpec.i.setBits(instruction, 0);
             masm.emitInt(instruction);
         }
 
-        public void emit(SPARCMacroAssembler masm, Op3s opcode, Register rs1, int simm13, Register rd) {
+        public static void emit(SPARCMacroAssembler masm, Op3s opcode, Register rs1, int simm13, Register rd) {
             int instruction = setBits(0, opcode, rs1, rd);
             instruction = BitSpec.i.setBits(instruction, 1);
-            instruction = BitSpec.simm13.setBits(instruction, simm13);
+            BitSpec immediateSpec;
+            switch (opcode) {
+                case Sllx:
+                case Srlx:
+                case Srax:
+                    immediateSpec = BitSpec.shcnt64;
+                    break;
+                case Sll:
+                case Srl:
+                case Sra:
+                    immediateSpec = BitSpec.shcnt32;
+                    break;
+                default:
+                    immediateSpec = BitSpec.simm13;
+                    break;
+            }
+            instruction = immediateSpec.setBits(instruction, simm13);
             masm.emitInt(instruction);
         }
 
         private static int setBits(int instruction, Op3s op3, Register rs1, Register rd) {
             assert op3.op.equals(ArithOp);
             int tmp = BitSpec.op3.setBits(instruction, op3.value);
+            switch (op3) {
+                case Sllx:
+                case Srlx:
+                case Srax:
+                    tmp = BitSpec.x.setBits(tmp, 1);
+                    break;
+            }
             tmp = BitSpec.op.setBits(tmp, op3.op.value);
             tmp = BitSpec.rd.setBits(tmp, rd.encoding);
             return BitSpec.rs1.setBits(tmp, rs1.encoding);
         }
     }
 
-    public static class OpfOp extends SPARCOp {
-        public OpfOp() {
+    /**
+     * Used for interfacing FP and GP conditional move instructions.
+     */
+    public interface CMOV {
+        void emit(SPARCMacroAssembler masm, ConditionFlag condition, CC cc, Register rs2, Register rd);
+
+        void emit(SPARCMacroAssembler masm, ConditionFlag condition, CC cc, int simm11, Register rd);
+    }
+
+    public static final class MOVicc extends SPARCOp implements CMOV {
+        private static final Op3s op3 = Movcc;
+
+        public MOVicc() {
             super(ArithOp);
         }
 
-        public void emit(SPARCMacroAssembler masm, Opfs opf, Register rs1, Register rs2, Register rd) {
+        public void emit(SPARCMacroAssembler masm, ConditionFlag condition, CC cc, Register rs2, Register rd) {
+            int inst = setBits(0, condition, cc, rd);
+            inst = BitSpec.rs2.setBits(inst, rs2.encoding());
+            masm.emitInt(inst);
+        }
+
+        public void emit(SPARCMacroAssembler masm, ConditionFlag condition, CC cc, int simm11, Register rd) {
+            int inst = setBits(0, condition, cc, rd);
+            inst = BitSpec.i.setBits(inst, 1);
+            inst = BitSpec.simm11.setBits(inst, simm11);
+            masm.emitInt(inst);
+        }
+
+        protected int setBits(int word, ConditionFlag condition, CC cc, Register rd) {
+            int inst = super.setBits(word);
+            inst = BitSpec.rd.setBits(inst, rd.encoding());
+            inst = BitSpec.op3.setBits(inst, op3.value);
+            inst = BitSpec.movccCond.setBits(inst, condition.value);
+            inst = BitSpec.movccLo.setBits(inst, cc.value);
+            return BitSpec.movccHi.setBits(inst, cc.isFloat ? 0 : 1);
+        }
+
+        @Override
+        protected List<BitKey[]> getKeys() {
+            List<BitKey[]> keys = super.getKeys();
+            keys.add(new BitKey[]{new BitKey(BitSpec.op3, op3.value)});
+            return keys;
+        }
+    }
+
+    public static final class FMOVcc extends SPARCOp implements CMOV {
+        private OpfLow opfLow;
+
+        public FMOVcc(OpfLow opfLow) {
+            super(ArithOp);
+            this.opfLow = opfLow;
+        }
+
+        public void emit(SPARCMacroAssembler masm, ConditionFlag condition, CC cc, Register rs2, Register rd) {
+            int inst = setBits(0);
+            inst = BitSpec.rd.setBits(inst, rd.encoding());
+            inst = BitSpec.op3.setBits(inst, opfLow.op3.value);
+            inst = BitSpec.opfCond.setBits(inst, condition.value);
+            inst = BitSpec.opfCC.setBits(inst, cc.value);
+            inst = BitSpec.opfLow.setBits(inst, opfLow.value);
+            inst = BitSpec.rs2.setBits(inst, rs2.encoding());
+            masm.emitInt(inst);
+        }
+
+        public void emit(SPARCMacroAssembler masm, ConditionFlag condition, CC cc, int simm11, Register rd) {
+            throw new IllegalArgumentException("FMOVCC cannot be used with immediate value");
+        }
+
+        @Override
+        protected List<BitKey[]> getKeys() {
+            List<BitKey[]> keys = super.getKeys();
+            keys.add(new BitKey[]{new BitKey(BitSpec.op3, opfLow.op3.value)});
+            keys.add(new BitKey[]{new BitKey(BitSpec.opfLow, opfLow.value)});
+            return keys;
+        }
+    }
+
+    public static final class OpfOp extends SPARCOp {
+
+        private BitKey[] op3Keys;
+
+        public OpfOp(BitKey... op3Keys) {
+            super(ArithOp);
+            this.op3Keys = op3Keys;
+        }
+
+        public OpfOp() {
+            // @formatter:off
+            this(new BitKey[]{
+                            new BitKey(BitSpec.op3, Op3s.Fpop1.value),
+                            new BitKey(BitSpec.op3, Op3s.Fpop2.value),
+                            new BitKey(BitSpec.op3, Op3s.Impdep1.value),
+                            new BitKey(BitSpec.op3, Op3s.Impdep2.value)});
+            // @formatter:on
+        }
+
+        public static void emit(SPARCMacroAssembler masm, Opfs opf, Register rs1, Register rs2, Register rd) {
             int instruction = setBits(0, opf, rs1, rs2);
             instruction = BitSpec.rd.setBits(instruction, rd.encoding);
             instruction = BitSpec.i.setBits(instruction, 0);
             masm.emitInt(instruction);
         }
 
-        public void emitFcmp(SPARCMacroAssembler masm, Opfs opf, CC cc, Register rs1, Register rs2) {
+        public static void emitFcmp(SPARCMacroAssembler masm, Opfs opf, CC cc, Register rs1, Register rs2) {
             assert opf.equals(Opfs.Fcmpd) || opf.equals(Opfs.Fcmps) : opf;
             int instruction = setBits(0, opf, rs1, rs2);
             instruction = BitSpec.fcc.setBits(instruction, cc.value);
@@ -1453,12 +1624,7 @@
         @Override
         protected List<BitKey[]> getKeys() {
             List<BitKey[]> keys = super.getKeys();
-            // @formatter:off
-            keys.add(new BitKey[]{
-                            new BitKey(BitSpec.op3, Op3s.Fpop1.value),
-                            new BitKey(BitSpec.op3, Op3s.Fpop2.value),
-                            new BitKey(BitSpec.op3, Op3s.Impdep1.value),
-                            new BitKey(BitSpec.op3, Op3s.Impdep2.value)});
+            keys.add(op3Keys);
             // @formatter:on
             return keys;
         }
@@ -2072,11 +2238,11 @@
     }
 
     public void fmovdcc(ConditionFlag cond, CC cc, Register rs2, Register rd) {
-        fmovcc(cond, cc, rs2, rd, Fmovdcc.value);
+        fmovcc(cond, cc, rs2, rd, OpfLow.Fmovdcc.value);
     }
 
     public void fmovscc(ConditionFlag cond, CC cc, Register rs2, Register rd) {
-        fmovcc(cond, cc, rs2, rd, Fmovscc.value);
+        fmovcc(cond, cc, rs2, rd, OpfLow.Fmovscc.value);
     }
 
     private void fmovcc(ConditionFlag cond, CC cc, Register rs2, Register rd, int opfLow) {
@@ -2228,10 +2394,6 @@
         op3(Srlx, rs1, shcnt64, rd);
     }
 
-    public void fandd(Register rs1, Register rs2, Register rd) {
-        op3(Impdep1, Fandd, rs1, rs2, rd);
-    }
-
     public void sub(Register rs1, Register rs2, Register rd) {
         op3(Sub, rs1, rs2, rd);
     }
@@ -2545,7 +2707,7 @@
         int delaySlotAbsolute = i + INSTRUCTION_SIZE;
         int nextInst = getInt(delaySlotAbsolute);
         SPARCOp nextOp = getSPARCOp(nextInst);
-        if (nextOp instanceof Sethi && ((Sethi) nextOp).isNop(nextInst)) {
+        if (nextOp instanceof Sethi && Sethi.isNop(nextInst)) {
             int inst = getInt(i);
             SPARCOp op = getSPARCOp(inst);
             if (op instanceof ControlTransferOp && ((ControlTransferOp) op).hasDelaySlot() && ((ControlTransferOp) op).isAnnulable(inst)) {
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Wed Sep 23 15:42:58 2015 +0200
@@ -23,86 +23,53 @@
 
 package com.oracle.graal.compiler.sparc;
 
+import static com.oracle.graal.asm.sparc.SPARCAssembler.FMOVDCC;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.FMOVSCC;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.MOVicc;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.Fcc0;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Add;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Addcc;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.And;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Mulx;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sdivx;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sllx;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sra;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Srax;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Srl;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Sub;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Subcc;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Udivx;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.Xnor;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Faddd;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fadds;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fcmpd;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fcmps;
-import static com.oracle.graal.lir.LIRValueUtil.asConstantValue;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdivd;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdivs;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fdtos;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fitod;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fitos;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmuld;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fmuls;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fnegd;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fnegs;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fstod;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.Fxtod;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.UMulxhi;
 import static com.oracle.graal.lir.LIRValueUtil.asJavaConstant;
 import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.B2I;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.B2L;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.D2F;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.D2I;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.D2L;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.DADD;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.DDIV;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.DMUL;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.DNEG;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.DSUB;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.F2D;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.F2I;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.F2L;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.FADD;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.FDIV;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.FMUL;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.FNEG;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.FSUB;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.I2D;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.I2F;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.I2L;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.IADD;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.IADDCC;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.IAND;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.IDIV;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.IMUL;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.IMULCC;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.INEG;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.INOT;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.IOR;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.IREM;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.ISHL;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.ISHR;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.ISUB;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.ISUBCC;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.IUMUL;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.IUREM;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.IUSHR;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.IXOR;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.L2D;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.L2F;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.L2I;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.LADD;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.LADDCC;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.LAND;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.LDIV;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.LMUL;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.LNEG;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.LNOT;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.LOR;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.LREM;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.LSHL;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.LSHR;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.LSUB;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.LSUBCC;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.LUDIV;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.LUMUL;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.LUREM;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.LUSHR;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.LXOR;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.S2I;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.S2L;
 import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.BSF;
 import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.IBSR;
-import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.IPOPCNT;
 import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.LBSR;
-import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.LPOPCNT;
-import static com.oracle.graal.lir.sparc.SPARCMathIntrinsicOp.IntrinsicOpcode.ABS;
-import static com.oracle.graal.lir.sparc.SPARCMathIntrinsicOp.IntrinsicOpcode.SQRT;
+import static jdk.internal.jvmci.code.CodeUtil.mask;
 import static jdk.internal.jvmci.code.ValueUtil.isStackSlotValue;
-import static jdk.internal.jvmci.meta.JavaKind.Char;
+import static jdk.internal.jvmci.meta.JavaConstant.forLong;
+import static jdk.internal.jvmci.sparc.SPARC.g0;
+import static jdk.internal.jvmci.sparc.SPARCKind.DOUBLE;
+import static jdk.internal.jvmci.sparc.SPARCKind.DWORD;
+import static jdk.internal.jvmci.sparc.SPARCKind.SINGLE;
+import static jdk.internal.jvmci.sparc.SPARCKind.WORD;
 import jdk.internal.jvmci.code.CallingConvention;
-import jdk.internal.jvmci.code.CodeUtil;
 import jdk.internal.jvmci.code.StackSlotValue;
 import jdk.internal.jvmci.common.JVMCIError;
 import jdk.internal.jvmci.meta.AllocatableValue;
@@ -114,9 +81,11 @@
 import jdk.internal.jvmci.meta.Value;
 import jdk.internal.jvmci.sparc.SPARC;
 import jdk.internal.jvmci.sparc.SPARC.CPUFeature;
+import jdk.internal.jvmci.sparc.SPARCKind;
 
 import com.oracle.graal.asm.sparc.SPARCAssembler;
 import com.oracle.graal.asm.sparc.SPARCAssembler.CC;
+import com.oracle.graal.asm.sparc.SPARCAssembler.CMOV;
 import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Op3s;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Opfs;
@@ -138,12 +107,13 @@
 import com.oracle.graal.lir.gen.SpillMoveFactoryBase;
 import com.oracle.graal.lir.sparc.SPARCAddressValue;
 import com.oracle.graal.lir.sparc.SPARCArithmetic;
-import com.oracle.graal.lir.sparc.SPARCArithmetic.BinaryRegConst;
-import com.oracle.graal.lir.sparc.SPARCArithmetic.BinaryRegReg;
 import com.oracle.graal.lir.sparc.SPARCArithmetic.MulHighOp;
+import com.oracle.graal.lir.sparc.SPARCArithmetic.MulHighOp.MulHigh;
 import com.oracle.graal.lir.sparc.SPARCArithmetic.RemOp;
+import com.oracle.graal.lir.sparc.SPARCArithmetic.RemOp.Rem;
+import com.oracle.graal.lir.sparc.SPARCArithmetic.SPARCIMulccOp;
 import com.oracle.graal.lir.sparc.SPARCArithmetic.SPARCLMulccOp;
-import com.oracle.graal.lir.sparc.SPARCArithmetic.Unary2Op;
+import com.oracle.graal.lir.sparc.SPARCArithmetic.FloatConvertOp;
 import com.oracle.graal.lir.sparc.SPARCArrayEqualsOp;
 import com.oracle.graal.lir.sparc.SPARCBitManipulationOp;
 import com.oracle.graal.lir.sparc.SPARCByteSwapOp;
@@ -158,7 +128,6 @@
 import com.oracle.graal.lir.sparc.SPARCImmediateAddressValue;
 import com.oracle.graal.lir.sparc.SPARCJumpOp;
 import com.oracle.graal.lir.sparc.SPARCLoadConstantTableBaseOp;
-import com.oracle.graal.lir.sparc.SPARCMathIntrinsicOp;
 import com.oracle.graal.lir.sparc.SPARCMove;
 import com.oracle.graal.lir.sparc.SPARCMove.LoadAddressOp;
 import com.oracle.graal.lir.sparc.SPARCMove.LoadDataAddressOp;
@@ -169,6 +138,7 @@
 import com.oracle.graal.lir.sparc.SPARCMove.NullCheckOp;
 import com.oracle.graal.lir.sparc.SPARCMove.StackLoadAddressOp;
 import com.oracle.graal.lir.sparc.SPARCOP3Op;
+import com.oracle.graal.lir.sparc.SPARCOPFOp;
 import com.oracle.graal.phases.util.Providers;
 
 /**
@@ -258,6 +228,22 @@
         }
     }
 
+    /**
+     * The SPARC backend only uses WORD and DWORD values in registers because except to the ld/st
+     * instructions no instruction deals either with 32 or 64 bits. This function converts small
+     * integer kinds to WORD.
+     */
+    @Override
+    public LIRKind toRegisterKind(LIRKind kind) {
+        switch ((SPARCKind) kind.getPlatformKind()) {
+            case BYTE:
+            case HWORD:
+                return kind.changeType(SPARCKind.WORD);
+            default:
+                return kind;
+        }
+    }
+
     protected LIRInstruction createStackMove(AllocatableValue result, AllocatableValue input) {
         return new SPARCMove.Move(result, input);
     }
@@ -329,25 +315,25 @@
             right = loadNonConst(y);
             actualCondition = cond;
         }
-        JavaKind actualCmpKind = (JavaKind) cmpKind;
-        if (actualCmpKind.isNumericInteger()) {
+        SPARCKind actualCmpKind = (SPARCKind) cmpKind;
+        if (actualCmpKind.isInteger()) {
             actualCmpKind = toSPARCCmpKind(actualCmpKind);
             append(new SPARCControlFlow.CompareBranchOp(canonicalizeForCompare(left, cmpKind, actualCmpKind), canonicalizeForCompare(right, cmpKind, actualCmpKind), actualCondition, trueDestination,
                             falseDestination, actualCmpKind, unorderedIsTrue, trueDestinationProbability));
-        } else if (actualCmpKind.isNumericFloat()) {
-            emitFloatCompare(cmpKind, x, y, Fcc0);
-            ConditionFlag cf = SPARCControlFlow.fromCondition(Fcc0, cond, unorderedIsTrue);
+        } else if (actualCmpKind.isFloat()) {
+            emitFloatCompare(actualCmpKind, x, y, Fcc0);
+            ConditionFlag cf = SPARCControlFlow.fromCondition(false, cond, unorderedIsTrue);
             append(new SPARCControlFlow.BranchOp(cf, trueDestination, falseDestination, actualCmpKind, trueDestinationProbability));
+        } else {
+            throw JVMCIError.shouldNotReachHere();
         }
     }
 
-    private static JavaKind toSPARCCmpKind(JavaKind actualCmpKind) {
-        // TODO: Change to PlatformKind
-        assert actualCmpKind.isNumericInteger();
-        if (actualCmpKind.getByteCount() <= 4) {
-            return JavaKind.Int;
+    private static SPARCKind toSPARCCmpKind(SPARCKind actualCmpKind) {
+        if (actualCmpKind.isInteger() && actualCmpKind.getSizeInBytes() <= 4) {
+            return SPARCKind.WORD;
         } else {
-            return JavaKind.Long;
+            return actualCmpKind;
         }
     }
 
@@ -359,7 +345,7 @@
             int fromBytes = from.getSizeInBytes() * 8;
             int toBytes = to.getSizeInBytes() * 8;
             assert from.getSizeInBytes() <= v.getPlatformKind().getSizeInBytes();
-            if (from == to && !v.getPlatformKind().equals(JavaKind.Char)) {
+            if (from == to) {
                 return v;
             } else {
                 return emitSignExtend(v, fromBytes, toBytes);
@@ -369,22 +355,22 @@
 
     @Override
     public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, LIRKind cmpLIRKind, double overflowProbability) {
-        JavaKind cmpKind = (JavaKind) cmpLIRKind.getPlatformKind();
+        SPARCKind cmpKind = (SPARCKind) cmpLIRKind.getPlatformKind();
         append(new BranchOp(ConditionFlag.OverflowSet, overflow, noOverflow, cmpKind, overflowProbability));
     }
 
     @Override
     public void emitIntegerTestBranch(Value left, Value right, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) {
         emitIntegerTest(left, right);
-        append(new BranchOp(ConditionFlag.Equal, trueDestination, falseDestination, ((JavaKind) left.getPlatformKind()).getStackKind(), trueDestinationProbability));
+        append(new BranchOp(ConditionFlag.Equal, trueDestination, falseDestination, (SPARCKind) left.getPlatformKind(), trueDestinationProbability));
     }
 
     private void emitIntegerTest(Value a, Value b) {
-        assert ((JavaKind) a.getPlatformKind()).isNumericInteger();
+        assert ((SPARCKind) a.getPlatformKind()).isInteger();
         if (LIRValueUtil.isVariable(b)) {
-            append(new SPARCOP3Op(Op3s.Andcc, load(b), loadNonConst(a)));
+            append(SPARCOP3Op.newBinaryVoid(Op3s.Andcc, load(b), loadNonConst(a)));
         } else {
-            append(new SPARCOP3Op(Op3s.Andcc, load(a), loadNonConst(b)));
+            append(SPARCOP3Op.newBinaryVoid(Op3s.Andcc, load(a), loadNonConst(b)));
         }
     }
 
@@ -400,38 +386,30 @@
 
     @Override
     public Variable emitConditionalMove(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
-        boolean mirrored = emitCompare(cmpKind, left, right);
-        CC conditionFlags;
+        // Emit compare
+        SPARCKind cmpSPARCKind = (SPARCKind) cmpKind;
+        boolean mirrored = emitCompare(cmpSPARCKind, left, right);
+
+        // Emit move
         Value actualTrueValue = trueValue;
         Value actualFalseValue = falseValue;
-        // TODO: (sa) Review this loadSimm11 if it is really necessary
-        switch ((JavaKind) left.getLIRKind().getPlatformKind()) {
-            case Byte:
-            case Short:
-            case Char:
-            case Int:
-                conditionFlags = CC.Icc;
-                actualTrueValue = loadSimm11(trueValue);
-                actualFalseValue = loadSimm11(falseValue);
-                break;
-            case Object:
-            case Long:
-                conditionFlags = CC.Xcc;
-                actualTrueValue = loadSimm11(trueValue);
-                actualFalseValue = loadSimm11(falseValue);
-                break;
-            case Float:
-            case Double:
-                conditionFlags = CC.Fcc0;
-                actualTrueValue = load(trueValue); // Floats cannot be immediate at all
-                actualFalseValue = load(falseValue);
-                break;
-            default:
-                throw JVMCIError.shouldNotReachHere();
+        SPARCKind valueKind = (SPARCKind) trueValue.getPlatformKind();
+        CMOV cmove;
+        if (valueKind.isFloat()) {
+            actualTrueValue = load(trueValue); // Floats cannot be immediate at all
+            actualFalseValue = load(falseValue);
+            cmove = valueKind.equals(SINGLE) ? FMOVSCC : FMOVDCC;
+        } else if (valueKind.isInteger()) {
+            actualTrueValue = loadSimm11(trueValue);
+            actualFalseValue = loadSimm11(falseValue);
+            cmove = MOVicc;
+        } else {
+            throw JVMCIError.shouldNotReachHere();
         }
         Variable result = newVariable(trueValue.getLIRKind());
-        ConditionFlag finalCondition = SPARCControlFlow.fromCondition(conditionFlags, mirrored ? cond.mirror() : cond, unorderedIsTrue);
-        append(new CondMoveOp(result, conditionFlags, finalCondition, actualTrueValue, actualFalseValue));
+        ConditionFlag finalCondition = SPARCControlFlow.fromCondition(cmpSPARCKind.isInteger(), mirrored ? cond.mirror() : cond, unorderedIsTrue);
+        CC cc = CC.forKind(toSPARCCmpKind(cmpSPARCKind));
+        append(new CondMoveOp(cmove, cc, finalCondition, actualTrueValue, actualFalseValue, result));
         return result;
     }
 
@@ -444,22 +422,22 @@
      * @param b the right operand of the comparison
      * @return true if the left and right operands were switched, false otherwise
      */
-    protected boolean emitCompare(PlatformKind cmpKind, Value a, Value b) {
+    protected boolean emitCompare(SPARCKind cmpKind, Value a, Value b) {
         boolean mirrored;
-        JavaKind cmpJavaKind = (JavaKind) cmpKind;
-        if (cmpJavaKind.isNumericInteger()) { // Integer case
-            mirrored = emitIntegerCompare(cmpJavaKind, a, b);
-        } else if (cmpJavaKind.isNumericFloat()) { // Float case
+        if (cmpKind.isInteger()) { // Integer case
+            mirrored = emitIntegerCompare(cmpKind, a, b);
+        } else if (cmpKind.isFloat()) { // Float case
             mirrored = false; // No mirroring done on floats
-            emitFloatCompare(cmpJavaKind, a, b, Fcc0);
+            emitFloatCompare(cmpKind, a, b, Fcc0);
         } else {
             throw JVMCIError.shouldNotReachHere();
         }
         return mirrored;
     }
 
-    private boolean emitIntegerCompare(JavaKind cmpJavaKind, Value a, Value b) {
+    private boolean emitIntegerCompare(SPARCKind cmpKind, Value a, Value b) {
         boolean mirrored;
+        assert cmpKind.isInteger();
         Value left;
         Value right;
         if (LIRValueUtil.isVariable(b)) {
@@ -471,28 +449,26 @@
             right = loadNonConst(b);
             mirrored = false;
         }
-        int compareBits = cmpJavaKind.getBitCount();
+        int compareBytes = cmpKind.getSizeInBytes();
         // SPARC compares 32 or 64 bits
-        if (compareBits < JavaKind.Int.getBitCount()) {
-            if (cmpJavaKind.equals(Char)) { // Char needs zero extend
-                left = emitZeroExtend(left, compareBits, 32);
-                right = emitZeroExtend(right, compareBits, 32);
-            } else {
-                left = emitSignExtend(left, compareBits, 32);
-                right = emitSignExtend(right, compareBits, 32);
-            }
+        if (compareBytes < left.getPlatformKind().getSizeInBytes()) {
+            left = emitSignExtend(left, compareBytes * 8, DWORD.getSizeInBytes() * 8);
         }
-        append(new SPARCOP3Op(Subcc, left, right));
+        if (compareBytes < right.getPlatformKind().getSizeInBytes()) {
+            right = emitSignExtend(right, compareBytes * 8, DWORD.getSizeInBytes() * 8);
+        }
+        append(SPARCOP3Op.newBinaryVoid(Subcc, left, right));
         return mirrored;
     }
 
-    private void emitFloatCompare(PlatformKind cmpJavaKind, Value a, Value b, CC cc) {
+    private void emitFloatCompare(SPARCKind cmpJavaKind, Value a, Value b, CC cc) {
         Opfs floatCompareOpcode;
-        switch ((JavaKind) cmpJavaKind) {
-            case Double:
+        assert cmpJavaKind.isFloat();
+        switch (cmpJavaKind) {
+            case DOUBLE:
                 floatCompareOpcode = Fcmpd;
                 break;
-            case Float:
+            case SINGLE:
                 floatCompareOpcode = Fcmps;
                 break;
             default:
@@ -505,25 +481,9 @@
     public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) {
         emitIntegerTest(left, right);
         Variable result = newVariable(trueValue.getLIRKind());
-        JavaKind kind = ((JavaKind) left.getPlatformKind()).getStackKind();
-        CC conditionCode;
-        switch (kind) {
-            case Object:
-            case Long:
-                conditionCode = CC.Xcc;
-                break;
-            case Int:
-            case Short:
-            case Char:
-            case Byte:
-                conditionCode = CC.Icc;
-                break;
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-        ConditionFlag flag = SPARCControlFlow.fromCondition(conditionCode, Condition.EQ, false);
-        // TODO: (sa) Review this loadSimm11 if it is really necessary
-        append(new CondMoveOp(result, conditionCode, flag, loadSimm11(trueValue), loadSimm11(falseValue)));
+        ConditionFlag flag = SPARCControlFlow.fromCondition(true, Condition.EQ, false);
+        CC cc = CC.forKind(left.getPlatformKind());
+        append(new CondMoveOp(MOVicc, cc, flag, loadSimm11(trueValue), loadSimm11(falseValue), result));
         return result;
     }
 
@@ -565,26 +525,27 @@
 
     @Override
     public Variable emitBitCount(Value operand) {
-        Variable result = newVariable(LIRKind.combine(operand).changeType(JavaKind.Int));
-        if (operand.getPlatformKind() == JavaKind.Long) {
-            append(new SPARCBitManipulationOp(LPOPCNT, result, asAllocatable(operand), this));
-        } else {
-            append(new SPARCBitManipulationOp(IPOPCNT, result, asAllocatable(operand), this));
+        Variable result = newVariable(LIRKind.combine(operand).changeType(SPARCKind.WORD));
+        Value usedOperand = operand;
+        if (operand.getPlatformKind() == SPARCKind.WORD) { // Zero extend
+            usedOperand = newVariable(operand.getLIRKind());
+            append(new SPARCOP3Op(Op3s.Srl, operand, SPARC.g0.asValue(), usedOperand));
         }
+        append(new SPARCOP3Op(Op3s.Popc, SPARC.g0.asValue(), usedOperand, result));
         return result;
     }
 
     @Override
     public Variable emitBitScanForward(Value operand) {
-        Variable result = newVariable(LIRKind.combine(operand).changeType(JavaKind.Int));
+        Variable result = newVariable(LIRKind.combine(operand).changeType(SPARCKind.WORD));
         append(new SPARCBitManipulationOp(BSF, result, asAllocatable(operand), this));
         return result;
     }
 
     @Override
     public Variable emitBitScanReverse(Value operand) {
-        Variable result = newVariable(LIRKind.combine(operand).changeType(JavaKind.Int));
-        if (operand.getPlatformKind() == JavaKind.Long) {
+        Variable result = newVariable(LIRKind.combine(operand).changeType(SPARCKind.WORD));
+        if (operand.getPlatformKind() == SPARCKind.DWORD) {
             append(new SPARCBitManipulationOp(LBSR, result, asAllocatable(operand), this));
         } else {
             append(new SPARCBitManipulationOp(IBSR, result, asAllocatable(operand), this));
@@ -595,14 +556,38 @@
     @Override
     public Value emitMathAbs(Value input) {
         Variable result = newVariable(LIRKind.combine(input));
-        append(new SPARCMathIntrinsicOp(ABS, result, asAllocatable(input)));
+        SPARCKind kind = (SPARCKind) input.getPlatformKind();
+        Opfs opf;
+        switch (kind) {
+            case SINGLE:
+                opf = Opfs.Fabss;
+                break;
+            case DOUBLE:
+                opf = Opfs.Fabsd;
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere("Input kind: " + kind);
+        }
+        append(new SPARCOPFOp(opf, g0.asValue(), input, result));
         return result;
     }
 
     @Override
     public Value emitMathSqrt(Value input) {
         Variable result = newVariable(LIRKind.combine(input));
-        append(new SPARCMathIntrinsicOp(SQRT, result, asAllocatable(input)));
+        SPARCKind kind = (SPARCKind) input.getPlatformKind();
+        Opfs opf;
+        switch (kind) {
+            case SINGLE:
+                opf = Opfs.Fsqrts;
+                break;
+            case DOUBLE:
+                opf = Opfs.Fsqrtd;
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere("Input kind: " + kind);
+        }
+        append(new SPARCOPFOp(opf, g0.asValue(), input, result));
         return result;
     }
 
@@ -615,174 +600,151 @@
 
     @Override
     public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length) {
-        Variable result = newVariable(LIRKind.value(JavaKind.Int));
+        Variable result = newVariable(LIRKind.value(SPARCKind.WORD));
         append(new SPARCArrayEqualsOp(this, kind, result, load(array1), load(array2), asAllocatable(length)));
         return result;
     }
 
     @Override
     public Value emitNegate(Value input) {
-        switch (((JavaKind) input.getPlatformKind()).getStackKind()) {
-            case Long:
-                return emitUnary(LNEG, input);
-            case Int:
-                return emitUnary(INEG, input);
-            case Float:
-                return emitUnary(FNEG, input);
-            case Double:
-                return emitUnary(DNEG, input);
-            default:
-                throw JVMCIError.shouldNotReachHere();
+        PlatformKind inputKind = input.getPlatformKind();
+        if (isNumericInteger(inputKind)) {
+            return emitUnary(Sub, input);
+        } else {
+            return emitUnary(inputKind.equals(DOUBLE) ? Fnegd : Fnegs, input);
         }
     }
 
     @Override
     public Value emitNot(Value input) {
-        switch (((JavaKind) input.getPlatformKind()).getStackKind()) {
-            case Int:
-                return emitUnary(INOT, input);
-            case Long:
-                return emitUnary(LNOT, input);
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
+        return emitUnary(Xnor, input);
     }
 
-    private Variable emitUnary(SPARCArithmetic op, Value input) {
+    private Variable emitUnary(Opfs opf, Value input) {
         Variable result = newVariable(LIRKind.combine(input));
-        append(new Unary2Op(op, result, load(input)));
+        append(new SPARCOPFOp(opf, g0.asValue(), input, result));
+        return result;
+    }
+
+    private Variable emitUnary(Op3s op3, Value input) {
+        Variable result = newVariable(LIRKind.combine(input));
+        append(SPARCOP3Op.newUnary(op3, input, result));
         return result;
     }
 
-    private Variable emitBinary(LIRKind resultKind, SPARCArithmetic op, boolean commutative, Value a, Value b) {
-        return emitBinary(resultKind, op, commutative, a, b, null);
+    private Variable emitBinary(LIRKind resultKind, Opfs opf, Value a, Value b) {
+        return emitBinary(resultKind, opf, a, b, null);
     }
 
-    private Variable emitBinary(LIRKind resultKind, SPARCArithmetic op, boolean commutative, Value a, Value b, LIRFrameState state) {
-        if (isJavaConstant(b) && canInlineConstant(asJavaConstant(b))) {
-            return emitBinaryConst(resultKind, op, load(a), asConstantValue(b), state);
-        } else if (commutative && isJavaConstant(a) && canInlineConstant(asJavaConstant(a))) {
-            return emitBinaryConst(resultKind, op, load(b), asConstantValue(a), state);
+    private Variable emitBinary(LIRKind resultKind, Opfs opf, Value a, Value b, LIRFrameState state) {
+        Variable result = newVariable(resultKind);
+        if (opf.isCommutative() && isJavaConstant(a) && canInlineConstant(asJavaConstant(a))) {
+            append(new SPARCOPFOp(opf, b, a, result, state));
         } else {
-            return emitBinaryVar(resultKind, op, load(a), load(b), state);
+            append(new SPARCOPFOp(opf, a, b, result, state));
         }
+        return result;
     }
 
-    private Variable emitBinaryConst(LIRKind resultKind, SPARCArithmetic op, AllocatableValue a, ConstantValue b, LIRFrameState state) {
-        switch (op) {
-            case IADD:
-            case LADD:
-            case ISUB:
-            case LSUB:
-            case IAND:
-            case LAND:
-            case IOR:
-            case LOR:
-            case IXOR:
-            case LXOR:
-            case IMUL:
-            case LMUL:
-                if (canInlineConstant(b.getJavaConstant())) {
-                    Variable result = newVariable(resultKind);
-                    append(new BinaryRegConst(op, result, a, b.getJavaConstant(), state));
-                    return result;
-                }
-                break;
-        }
-        return emitBinaryVar(resultKind, op, a, asAllocatable(b), state);
+    private Variable emitBinary(LIRKind resultKind, Op3s op3, Value a, int b) {
+        return emitBinary(resultKind, op3, a, new ConstantValue(LIRKind.value(WORD), JavaConstant.forInt(b)));
+    }
+
+    private Variable emitBinary(LIRKind resultKind, Op3s op3, Value a, Value b) {
+        return emitBinary(resultKind, op3, a, b, null);
     }
 
-    private Variable emitBinaryVar(LIRKind resultKind, SPARCArithmetic op, AllocatableValue a, AllocatableValue b, LIRFrameState state) {
+    private Variable emitBinary(LIRKind resultKind, Op3s op3, Value a, Value b, LIRFrameState state) {
         Variable result = newVariable(resultKind);
-        append(new BinaryRegReg(op, result, a, b, state));
+        if (op3.isCommutative() && isJavaConstant(a) && canInlineConstant(asJavaConstant(a))) {
+            append(new SPARCOP3Op(op3, load(b), a, result, state));
+        } else {
+            append(new SPARCOP3Op(op3, load(a), b, result, state));
+        }
         return result;
     }
 
     @Override
     protected boolean isNumericInteger(PlatformKind kind) {
-        return ((JavaKind) kind).isNumericInteger();
+        return ((SPARCKind) kind).isInteger();
     }
 
     @Override
     public Variable emitAdd(LIRKind resultKind, Value a, Value b, boolean setFlags) {
-        switch (((JavaKind) a.getPlatformKind()).getStackKind()) {
-            case Int:
-                return emitBinary(resultKind, setFlags ? IADDCC : IADD, true, a, b);
-            case Long:
-                return emitBinary(resultKind, setFlags ? LADDCC : LADD, true, a, b);
-            case Float:
-                return emitBinary(resultKind, FADD, true, a, b);
-            case Double:
-                return emitBinary(resultKind, DADD, true, a, b);
-            default:
-                throw JVMCIError.shouldNotReachHere();
+        if (isNumericInteger(a.getPlatformKind())) {
+            return emitBinary(resultKind, setFlags ? Addcc : Add, a, b);
+        } else {
+            boolean isDouble = a.getPlatformKind().equals(DOUBLE);
+            return emitBinary(resultKind, isDouble ? Faddd : Fadds, a, b);
         }
     }
 
     @Override
     public Variable emitSub(LIRKind resultKind, Value a, Value b, boolean setFlags) {
-        switch (((JavaKind) a.getPlatformKind()).getStackKind()) {
-            case Int:
-                return emitBinary(resultKind, setFlags ? ISUBCC : ISUB, false, a, b);
-            case Long:
-                return emitBinary(resultKind, setFlags ? LSUBCC : LSUB, false, a, b);
-            case Float:
-                return emitBinary(resultKind, FSUB, false, a, b);
-            case Double:
-                return emitBinary(resultKind, DSUB, false, a, b);
-            default:
-                throw JVMCIError.shouldNotReachHere("missing: " + a.getPlatformKind());
+        if (isNumericInteger(a.getPlatformKind())) {
+            return emitBinary(resultKind, setFlags ? Subcc : Sub, a, b);
+        } else {
+            boolean isDouble = a.getPlatformKind().equals(DOUBLE);
+            return emitBinary(resultKind, isDouble ? Opfs.Fsubd : Opfs.Fsubs, a, b);
         }
     }
 
     @Override
     public Variable emitMul(Value a, Value b, boolean setFlags) {
         LIRKind resultKind = LIRKind.combine(a, b);
-        switch (((JavaKind) a.getPlatformKind()).getStackKind()) {
-            case Int:
-                return emitBinary(resultKind, setFlags ? IMULCC : IMUL, true, a, b);
-            case Long:
-                if (setFlags) {
-                    Variable result = newVariable(LIRKind.combine(a, b));
+        PlatformKind aKind = a.getPlatformKind();
+        if (isNumericInteger(aKind)) {
+            if (setFlags) {
+                Variable result = newVariable(LIRKind.combine(a, b));
+                if (aKind == DWORD) {
                     append(new SPARCLMulccOp(result, load(a), load(b), this));
-                    return result;
+                } else if (aKind == WORD) {
+                    append(new SPARCIMulccOp(result, load(a), load(b)));
                 } else {
-                    return emitBinary(resultKind, LMUL, true, a, b);
+                    throw JVMCIError.shouldNotReachHere();
                 }
-            case Float:
-                return emitBinary(resultKind, FMUL, true, a, b);
-            case Double:
-                return emitBinary(resultKind, DMUL, true, a, b);
-            default:
-                throw JVMCIError.shouldNotReachHere("missing: " + a.getPlatformKind());
+                return result;
+            } else {
+                return emitBinary(resultKind, setFlags ? Op3s.Mulscc : Op3s.Mulx, a, b);
+            }
+        } else {
+            boolean isDouble = a.getPlatformKind().equals(DOUBLE);
+            return emitBinary(resultKind, isDouble ? Fmuld : Fmuls, a, b);
         }
     }
 
     @Override
     public Value emitMulHigh(Value a, Value b) {
-        switch (((JavaKind) a.getPlatformKind()).getStackKind()) {
-            case Int:
-                return emitMulHigh(IMUL, a, b);
-            case Long:
-                return emitMulHigh(LMUL, a, b);
+        MulHigh opcode;
+        switch (((SPARCKind) a.getPlatformKind())) {
+            case WORD:
+                opcode = MulHigh.IMUL;
+                break;
+            case DWORD:
+                opcode = MulHigh.LMUL;
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+        return emitMulHigh(opcode, a, b);
+    }
+
+    @Override
+    public Value emitUMulHigh(Value a, Value b) {
+        switch (((SPARCKind) a.getPlatformKind())) {
+            case WORD:
+                Value aExtended = emitBinary(LIRKind.combine(a), Srl, a, 0);
+                Value bExtended = emitBinary(LIRKind.combine(b), Srl, b, 0);
+                Value result = emitBinary(LIRKind.combine(a, b), Mulx, aExtended, bExtended);
+                return emitBinary(LIRKind.combine(a, b), Srax, result, WORD.getSizeInBits());
+            case DWORD:
+                return emitBinary(LIRKind.combine(a, b), UMulxhi, a, b);
             default:
                 throw JVMCIError.shouldNotReachHere();
         }
     }
 
-    @Override
-    public Value emitUMulHigh(Value a, Value b) {
-        switch (((JavaKind) a.getPlatformKind()).getStackKind()) {
-            case Int:
-                return emitMulHigh(IUMUL, a, b);
-            case Long:
-                return emitMulHigh(LUMUL, a, b);
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    private Value emitMulHigh(SPARCArithmetic opcode, Value a, Value b) {
+    private Value emitMulHigh(MulHigh opcode, Value a, Value b) {
         Variable result = newVariable(LIRKind.combine(a, b));
         MulHighOp mulHigh = new MulHighOp(opcode, load(a), load(b), result, newVariable(LIRKind.combine(a, b)));
         append(mulHigh);
@@ -792,55 +754,63 @@
     @Override
     public Value emitDiv(Value a, Value b, LIRFrameState state) {
         LIRKind resultKind = LIRKind.combine(a, b);
-        switch (((JavaKind) a.getPlatformKind()).getStackKind()) {
-            case Int:
-                return emitBinary(resultKind, IDIV, false, a, b, state);
-            case Long:
-                return emitBinary(resultKind, LDIV, false, a, b, state);
-            case Float:
-                return emitBinary(resultKind, FDIV, false, a, b, state);
-            case Double:
-                return emitBinary(resultKind, DDIV, false, a, b, state);
-            default:
-                throw JVMCIError.shouldNotReachHere("missing: " + a.getPlatformKind());
+        PlatformKind aKind = a.getPlatformKind();
+        PlatformKind bKind = b.getPlatformKind();
+        if (isJavaConstant(b) && asJavaConstant(b).isDefaultForKind()) { // Div by zero
+            Value zero = SPARC.g0.asValue(LIRKind.value(SPARCKind.WORD));
+            return emitBinary(resultKind, Op3s.Sdivx, zero, zero, state);
+        } else if (isNumericInteger(aKind)) {
+            Value fixedA = emitSignExtend(a, aKind.getSizeInBytes() * 8, 64);
+            Value fixedB = emitSignExtend(b, bKind.getSizeInBytes() * 8, 64);
+            return emitBinary(resultKind, Op3s.Sdivx, fixedA, fixedB, state);
+        } else {
+            boolean isDouble = a.getPlatformKind().equals(DOUBLE);
+            return emitBinary(resultKind, isDouble ? Opfs.Fdivd : Opfs.Fdivs, a, b, state);
         }
     }
 
     @Override
     public Value emitRem(Value a, Value b, LIRFrameState state) {
         Variable result = newVariable(LIRKind.combine(a, b));
+        Value aLoaded;
+        Value bLoaded;
         Variable q1; // Intermediate values
         Variable q2;
         Variable q3;
         Variable q4;
-        switch (((JavaKind) a.getPlatformKind()).getStackKind()) {
-            case Int:
-                append(new RemOp(IREM, result, load(a), loadNonConst(b), state, this));
+        SPARCKind aKind = (SPARCKind) a.getPlatformKind();
+        switch (aKind) {
+            case WORD:
+                q1 = emitBinary(result.getLIRKind(), Sra, a, g0.asValue(LIRKind.value(WORD)));
+                q2 = emitBinary(q1.getLIRKind(), Sdivx, q1, b, state);
+                q3 = emitBinary(q2.getLIRKind(), Op3s.Mulx, q2, b);
+                result = emitSub(q1, q3, false);
                 break;
-            case Long:
-                append(new RemOp(LREM, result, load(a), loadNonConst(b), state, this));
+            case DWORD:
+                aLoaded = load(a); // Reuse the loaded value
+                q1 = emitBinary(result.getLIRKind(), Sdivx, aLoaded, b, state);
+                q2 = emitBinary(result.getLIRKind(), Mulx, q1, b);
+                result = emitSub(aLoaded, q2, false);
                 break;
-            case Float:
-                q1 = newVariable(LIRKind.value(JavaKind.Float));
-                append(new BinaryRegReg(FDIV, q1, a, b, state));
-                q2 = newVariable(LIRKind.value(JavaKind.Float));
-                append(new Unary2Op(F2I, q2, q1));
-                q3 = newVariable(LIRKind.value(JavaKind.Float));
-                append(new Unary2Op(I2F, q3, q2));
-                q4 = newVariable(LIRKind.value(JavaKind.Float));
-                append(new BinaryRegReg(FMUL, q4, q3, b));
-                append(new BinaryRegReg(FSUB, result, a, q4));
+            case SINGLE:
+                aLoaded = load(a);
+                bLoaded = load(b);
+                q1 = emitBinary(result.getLIRKind(), Fdivs, aLoaded, bLoaded, state);
+                q2 = newVariable(LIRKind.value(aKind));
+                append(new FloatConvertOp(FloatConvertOp.FloatConvert.F2I, q1, q2));
+                q3 = emitUnary(Fitos, q2);
+                q4 = emitBinary(LIRKind.value(aKind), Fmuls, q3, bLoaded);
+                result = emitSub(aLoaded, q4, false);
                 break;
-            case Double:
-                q1 = newVariable(LIRKind.value(JavaKind.Double));
-                append(new BinaryRegReg(DDIV, q1, a, b, state));
-                q2 = newVariable(LIRKind.value(JavaKind.Double));
-                append(new Unary2Op(D2L, q2, q1));
-                q3 = newVariable(LIRKind.value(JavaKind.Double));
-                append(new Unary2Op(L2D, q3, q2));
-                q4 = newVariable(LIRKind.value(JavaKind.Double));
-                append(new BinaryRegReg(DMUL, q4, q3, b));
-                append(new BinaryRegReg(DSUB, result, a, q4));
+            case DOUBLE:
+                aLoaded = load(a);
+                bLoaded = load(b);
+                q1 = emitBinary(result.getLIRKind(), Fdivd, aLoaded, bLoaded, state);
+                q2 = newVariable(LIRKind.value(aKind));
+                append(new FloatConvertOp(FloatConvertOp.FloatConvert.D2L, q1, q2));
+                q3 = emitUnary(Fxtod, q2);
+                q4 = emitBinary(result.getLIRKind(), Fmuld, q3, bLoaded);
+                result = emitSub(aLoaded, q4, false);
                 break;
             default:
                 throw JVMCIError.shouldNotReachHere("missing: " + a.getPlatformKind());
@@ -851,124 +821,111 @@
     @Override
     public Value emitURem(Value a, Value b, LIRFrameState state) {
         Variable result = newVariable(LIRKind.combine(a, b));
-        switch (((JavaKind) a.getPlatformKind()).getStackKind()) {
-            case Int:
-                append(new RemOp(IUREM, result, load(a), load(b), state, this));
+        Variable scratch1 = newVariable(LIRKind.combine(a, b));
+        Variable scratch2 = newVariable(LIRKind.combine(a, b));
+        Rem opcode;
+        switch (((SPARCKind) a.getPlatformKind())) {
+            case WORD:
+                opcode = Rem.IUREM;
                 break;
-            case Long:
-                append(new RemOp(LUREM, result, load(a), loadNonConst(b), state, this));
+            case DWORD:
+                opcode = Rem.LUREM;
                 break;
             default:
                 throw JVMCIError.shouldNotReachHere();
         }
+        append(new RemOp(opcode, result, load(a), load(b), scratch1, scratch2, state));
         return result;
 
     }
 
     @Override
     public Value emitUDiv(Value a, Value b, LIRFrameState state) {
-        SPARCArithmetic op;
         Value actualA = a;
         Value actualB = b;
-        switch (((JavaKind) a.getPlatformKind()).getStackKind()) {
-            case Int:
-                op = LUDIV;
+        switch (((SPARCKind) a.getPlatformKind())) {
+            case WORD:
                 actualA = emitZeroExtend(actualA, 32, 64);
                 actualB = emitZeroExtend(actualB, 32, 64);
                 break;
-            case Long:
-                op = LUDIV;
+            case DWORD:
                 break;
             default:
                 throw JVMCIError.shouldNotReachHere();
         }
-        return emitBinary(LIRKind.combine(actualA, actualB), op, false, actualA, actualB, state);
+        return emitBinary(LIRKind.combine(actualA, actualB), Udivx, actualA, actualB, state);
     }
 
     @Override
     public Variable emitAnd(Value a, Value b) {
         LIRKind resultKind = LIRKind.combine(a, b);
-        switch (((JavaKind) a.getPlatformKind()).getStackKind()) {
-            case Int:
-                return emitBinary(resultKind, IAND, true, a, b);
-            case Long:
-                return emitBinary(resultKind, LAND, true, a, b);
-
-            default:
-                throw JVMCIError.shouldNotReachHere("missing: " + a.getPlatformKind());
-        }
+        return emitBinary(resultKind, Op3s.And, a, b);
     }
 
     @Override
     public Variable emitOr(Value a, Value b) {
         LIRKind resultKind = LIRKind.combine(a, b);
-        switch (((JavaKind) a.getPlatformKind()).getStackKind()) {
-            case Int:
-                return emitBinary(resultKind, IOR, true, a, b);
-            case Long:
-                return emitBinary(resultKind, LOR, true, a, b);
-            default:
-                throw JVMCIError.shouldNotReachHere("missing: " + a.getPlatformKind());
-        }
+        return emitBinary(resultKind, Op3s.Or, a, b);
     }
 
     @Override
     public Variable emitXor(Value a, Value b) {
         LIRKind resultKind = LIRKind.combine(a, b);
-        switch (((JavaKind) a.getPlatformKind()).getStackKind()) {
-            case Int:
-                return emitBinary(resultKind, IXOR, true, a, b);
-            case Long:
-                return emitBinary(resultKind, LXOR, true, a, b);
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    private Variable emitShift(SPARCArithmetic op, Value a, Value b) {
-        Variable result = newVariable(LIRKind.combine(a, b).changeType(a.getPlatformKind()));
-        if (isJavaConstant(b) && canInlineConstant(asJavaConstant(b))) {
-            append(new BinaryRegConst(op, result, load(a), asJavaConstant(b), null));
-        } else {
-            append(new BinaryRegReg(op, result, load(a), load(b)));
-        }
-        return result;
+        return emitBinary(resultKind, Op3s.Xor, a, b);
     }
 
     @Override
     public Variable emitShl(Value a, Value b) {
-        switch (((JavaKind) a.getPlatformKind()).getStackKind()) {
-            case Int:
-                return emitShift(ISHL, a, b);
-            case Long:
-                return emitShift(LSHL, a, b);
+        SPARCKind aKind = (SPARCKind) a.getPlatformKind();
+        LIRKind resultKind = LIRKind.combine(a, b).changeType(aKind);
+        Op3s op;
+        switch (aKind) {
+            case WORD:
+                op = Op3s.Sll;
+                break;
+            case DWORD:
+                op = Op3s.Sllx;
+                break;
             default:
                 throw JVMCIError.shouldNotReachHere();
         }
+        return emitBinary(resultKind, op, a, b);
     }
 
     @Override
     public Variable emitShr(Value a, Value b) {
-        switch (((JavaKind) a.getPlatformKind()).getStackKind()) {
-            case Int:
-                return emitShift(ISHR, a, b);
-            case Long:
-                return emitShift(LSHR, a, b);
+        SPARCKind aKind = (SPARCKind) a.getPlatformKind();
+        LIRKind resultKind = LIRKind.combine(a, b).changeType(aKind);
+        Op3s op;
+        switch (aKind) {
+            case WORD:
+                op = Op3s.Sra;
+                break;
+            case DWORD:
+                op = Op3s.Srax;
+                break;
             default:
                 throw JVMCIError.shouldNotReachHere();
         }
+        return emitBinary(resultKind, op, a, b);
     }
 
     @Override
     public Variable emitUShr(Value a, Value b) {
-        switch (((JavaKind) a.getPlatformKind()).getStackKind()) {
-            case Int:
-                return emitShift(IUSHR, a, b);
-            case Long:
-                return emitShift(LUSHR, a, b);
+        SPARCKind aKind = (SPARCKind) a.getPlatformKind();
+        LIRKind resultKind = LIRKind.combine(a, b).changeType(aKind);
+        Op3s op;
+        switch (aKind) {
+            case WORD:
+                op = Op3s.Srl;
+                break;
+            case DWORD:
+                op = Op3s.Srlx;
+                break;
             default:
                 throw JVMCIError.shouldNotReachHere();
         }
+        return emitBinary(resultKind, op, a, b);
     }
 
     private AllocatableValue emitConvertMove(LIRKind kind, AllocatableValue input) {
@@ -977,78 +934,86 @@
         return result;
     }
 
-    private AllocatableValue emitConvert2Op(LIRKind kind, SPARCArithmetic op, AllocatableValue input) {
-        Variable result = newVariable(kind);
-        append(new Unary2Op(op, result, input));
-        return result;
-    }
-
     @Override
     public Value emitFloatConvert(FloatConvert op, Value inputVal) {
         AllocatableValue input = asAllocatable(inputVal);
+        Value result;
         switch (op) {
             case D2F:
-                return emitConvert2Op(LIRKind.combine(inputVal).changeType(JavaKind.Float), D2F, input);
+                result = newVariable(LIRKind.combine(inputVal).changeType(SINGLE));
+                append(new SPARCOPFOp(Fdtos, inputVal, result));
+                break;
             case F2D:
-                return emitConvert2Op(LIRKind.combine(inputVal).changeType(JavaKind.Double), F2D, input);
+                result = newVariable(LIRKind.combine(inputVal).changeType(DOUBLE));
+                append(new SPARCOPFOp(Fstod, inputVal, result));
+                break;
             case I2F: {
-                AllocatableValue intEncodedFloatReg = newVariable(LIRKind.combine(input).changeType(JavaKind.Float));
+                AllocatableValue intEncodedFloatReg = newVariable(LIRKind.combine(input).changeType(SINGLE));
+                result = newVariable(intEncodedFloatReg.getLIRKind());
                 moveBetweenFpGp(intEncodedFloatReg, input);
-                AllocatableValue convertedFloatReg = newVariable(intEncodedFloatReg.getLIRKind());
-                append(new Unary2Op(I2F, convertedFloatReg, intEncodedFloatReg));
-                return convertedFloatReg;
+                append(new SPARCOPFOp(Fitos, intEncodedFloatReg, result));
+                break;
             }
             case I2D: {
                 // Unfortunately we must do int -> float -> double because fitod has float
                 // and double encoding in one instruction
-                AllocatableValue convertedFloatReg = newVariable(LIRKind.combine(input).changeType(JavaKind.Float));
+                AllocatableValue convertedFloatReg = newVariable(LIRKind.combine(input).changeType(SINGLE));
+                result = newVariable(LIRKind.combine(input).changeType(DOUBLE));
                 moveBetweenFpGp(convertedFloatReg, input);
-                AllocatableValue convertedDoubleReg = newVariable(LIRKind.combine(input).changeType(JavaKind.Double));
-                append(new Unary2Op(I2D, convertedDoubleReg, convertedFloatReg));
-                return convertedDoubleReg;
+                append(new SPARCOPFOp(Fitod, convertedFloatReg, result));
+                break;
             }
             case L2D: {
-                AllocatableValue longEncodedDoubleReg = newVariable(LIRKind.combine(input).changeType(JavaKind.Double));
+                AllocatableValue longEncodedDoubleReg = newVariable(LIRKind.combine(input).changeType(DOUBLE));
                 moveBetweenFpGp(longEncodedDoubleReg, input);
                 AllocatableValue convertedDoubleReg = newVariable(longEncodedDoubleReg.getLIRKind());
-                append(new Unary2Op(L2D, convertedDoubleReg, longEncodedDoubleReg));
-                return convertedDoubleReg;
+                append(new SPARCOPFOp(Fxtod, longEncodedDoubleReg, convertedDoubleReg));
+                result = convertedDoubleReg;
+                break;
             }
             case D2I: {
-                AllocatableValue convertedFloatReg = emitConvert2Op(LIRKind.combine(input).changeType(JavaKind.Float), D2I, input);
-                AllocatableValue convertedIntReg = newVariable(LIRKind.combine(convertedFloatReg).changeType(JavaKind.Int));
+                AllocatableValue convertedFloatReg = newVariable(LIRKind.combine(input).changeType(SINGLE));
+                append(new SPARCArithmetic.FloatConvertOp(FloatConvertOp.FloatConvert.D2I, input, convertedFloatReg));
+                AllocatableValue convertedIntReg = newVariable(LIRKind.combine(convertedFloatReg).changeType(WORD));
                 moveBetweenFpGp(convertedIntReg, convertedFloatReg);
-                return convertedIntReg;
+                result = convertedIntReg;
+                break;
             }
             case F2L: {
-                AllocatableValue convertedDoubleReg = emitConvert2Op(LIRKind.combine(input).changeType(JavaKind.Double), F2L, input);
-                AllocatableValue convertedLongReg = newVariable(LIRKind.combine(convertedDoubleReg).changeType(JavaKind.Long));
+                AllocatableValue convertedDoubleReg = newVariable(LIRKind.combine(input).changeType(DOUBLE));
+                append(new SPARCArithmetic.FloatConvertOp(FloatConvertOp.FloatConvert.F2L, input, convertedDoubleReg));
+                AllocatableValue convertedLongReg = newVariable(LIRKind.combine(convertedDoubleReg).changeType(DWORD));
                 moveBetweenFpGp(convertedLongReg, convertedDoubleReg);
-                return convertedLongReg;
+                result = convertedLongReg;
+                break;
             }
             case F2I: {
-                AllocatableValue convertedFloatReg = emitConvert2Op(LIRKind.combine(input).changeType(JavaKind.Float), F2I, input);
-                AllocatableValue convertedIntReg = newVariable(LIRKind.combine(convertedFloatReg).changeType(JavaKind.Int));
+                AllocatableValue convertedFloatReg = newVariable(LIRKind.combine(input).changeType(SINGLE));
+                append(new SPARCArithmetic.FloatConvertOp(FloatConvertOp.FloatConvert.F2I, input, convertedFloatReg));
+                AllocatableValue convertedIntReg = newVariable(LIRKind.combine(convertedFloatReg).changeType(WORD));
                 moveBetweenFpGp(convertedIntReg, convertedFloatReg);
-                return convertedIntReg;
+                result = convertedIntReg;
+                break;
             }
             case D2L: {
-                AllocatableValue convertedDoubleReg = emitConvert2Op(LIRKind.combine(input).changeType(JavaKind.Double), D2L, input);
-                AllocatableValue convertedLongReg = newVariable(LIRKind.combine(convertedDoubleReg).changeType(JavaKind.Long));
+                AllocatableValue convertedDoubleReg = newVariable(LIRKind.combine(input).changeType(DOUBLE));
+                append(new SPARCArithmetic.FloatConvertOp(FloatConvertOp.FloatConvert.D2L, input, convertedDoubleReg));
+                AllocatableValue convertedLongReg = newVariable(LIRKind.combine(convertedDoubleReg).changeType(DWORD));
                 moveBetweenFpGp(convertedLongReg, convertedDoubleReg);
-                return convertedLongReg;
+                result = convertedLongReg;
+                break;
             }
             case L2F: {
-                // long -> double -> float see above
-                AllocatableValue convertedDoubleReg = newVariable(LIRKind.combine(input).changeType(JavaKind.Double));
+                AllocatableValue convertedDoubleReg = newVariable(LIRKind.combine(input).changeType(DOUBLE));
+                result = newVariable(LIRKind.combine(input).changeType(SINGLE));
                 moveBetweenFpGp(convertedDoubleReg, input);
-                AllocatableValue convertedFloatReg = newVariable(LIRKind.combine(input).changeType(JavaKind.Float));
-                append(new Unary2Op(L2F, convertedFloatReg, convertedDoubleReg));
-                return convertedFloatReg;
+                append(new SPARCOPFOp(Opfs.Fxtos, convertedDoubleReg, result));
+                break;
             }
             default:
                 throw JVMCIError.shouldNotReachHere();
         }
+        return result;
     }
 
     private void moveBetweenFpGp(AllocatableValue dst, AllocatableValue src) {
@@ -1056,7 +1021,7 @@
         if (getArchitecture().getFeatures().contains(CPUFeature.VIS3)) {
             tempSlot = AllocatableValue.ILLEGAL;
         } else {
-            tempSlot = getTempSlot(LIRKind.value(JavaKind.Long));
+            tempSlot = getTempSlot(LIRKind.value(DWORD));
         }
         append(new MoveFpGp(dst, src, tempSlot));
     }
@@ -1074,8 +1039,11 @@
 
     @Override
     public Value emitNarrow(Value inputVal, int bits) {
-        if (inputVal.getPlatformKind() == JavaKind.Long && bits <= 32) {
-            return emitConvert2Op(LIRKind.combine(inputVal).changeType(JavaKind.Int), L2I, asAllocatable(inputVal));
+        if (inputVal.getPlatformKind() == DWORD && bits <= 32) {
+            LIRKind resultKind = LIRKind.combine(inputVal).changeType(WORD);
+            Variable result = newVariable(resultKind);
+            emitMove(result, inputVal);
+            return result;
         } else {
             return inputVal;
         }
@@ -1083,34 +1051,32 @@
 
     @Override
     public Value emitSignExtend(Value inputVal, int fromBits, int toBits) {
-        assert fromBits <= toBits && toBits <= 64;
+        assert fromBits <= toBits && toBits <= DWORD.getSizeInBits();
+        LIRKind shiftKind = LIRKind.value(WORD);
+        LIRKind resultKind = LIRKind.combine(inputVal).changeType(toBits > 32 ? DWORD : WORD);
+        Value result;
+        int shiftCount = DWORD.getSizeInBits() - fromBits;
         if (fromBits == toBits) {
-            return inputVal;
-        } else if (toBits > 32) {
-            // sign extend to 64 bits
-            switch (fromBits) {
-                case 8:
-                    return emitConvert2Op(LIRKind.combine(inputVal).changeType(JavaKind.Long), B2L, asAllocatable(inputVal));
-                case 16:
-                    return emitConvert2Op(LIRKind.combine(inputVal).changeType(JavaKind.Long), S2L, asAllocatable(inputVal));
-                case 32:
-                    return emitConvert2Op(LIRKind.combine(inputVal).changeType(JavaKind.Long), I2L, asAllocatable(inputVal));
-                default:
-                    throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
+            result = inputVal;
+        } else if (isJavaConstant(inputVal)) {
+            JavaConstant javaConstant = asJavaConstant(inputVal);
+            long constant;
+            if (javaConstant.isNull()) {
+                constant = 0;
+            } else {
+                constant = javaConstant.asLong();
             }
+            return new ConstantValue(resultKind, JavaConstant.forLong((constant << shiftCount) >> shiftCount));
+        } else if (fromBits == WORD.getSizeInBits() && toBits == DWORD.getSizeInBits()) {
+            result = newVariable(resultKind);
+            append(new SPARCOP3Op(Sra, inputVal, SPARC.g0.asValue(LIRKind.value(WORD)), result));
         } else {
-            // sign extend to 32 bits (smaller values are internally represented as 32 bit values)
-            switch (fromBits) {
-                case 8:
-                    return emitConvert2Op(LIRKind.combine(inputVal).changeType(JavaKind.Int), B2I, asAllocatable(inputVal));
-                case 16:
-                    return emitConvert2Op(LIRKind.combine(inputVal).changeType(JavaKind.Int), S2I, asAllocatable(inputVal));
-                case 32:
-                    return inputVal;
-                default:
-                    throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
-            }
+            Variable tmp = newVariable(resultKind.changeType(DWORD));
+            result = newVariable(resultKind);
+            append(new SPARCOP3Op(Sllx, inputVal, new ConstantValue(shiftKind, JavaConstant.forInt(shiftCount)), tmp));
+            append(new SPARCOP3Op(Srax, tmp, new ConstantValue(shiftKind, JavaConstant.forInt(shiftCount)), result));
         }
+        return result;
     }
 
     @Override
@@ -1118,83 +1084,34 @@
         assert fromBits <= toBits && toBits <= 64;
         if (fromBits == toBits) {
             return inputVal;
-        } else if (fromBits > 32) {
-            assert inputVal.getPlatformKind() == JavaKind.Long;
-            Variable result = newVariable(LIRKind.combine(inputVal).changeType(JavaKind.Long));
-            long mask = CodeUtil.mask(fromBits);
-            append(new BinaryRegConst(SPARCArithmetic.LAND, result, asAllocatable(inputVal), JavaConstant.forLong(mask), null));
-            return result;
+        }
+        Variable result = newVariable(LIRKind.combine(inputVal).changeType(toBits > WORD.getSizeInBits() ? DWORD : WORD));
+        if (fromBits == 32) {
+            append(new SPARCOP3Op(Srl, inputVal, g0.asValue(), result));
         } else {
-            assert inputVal.getPlatformKind() == JavaKind.Int || inputVal.getPlatformKind() == JavaKind.Short || inputVal.getPlatformKind() == JavaKind.Byte ||
-                            inputVal.getPlatformKind() == JavaKind.Char : inputVal.getPlatformKind();
-            Variable result = newVariable(LIRKind.combine(inputVal).changeType(JavaKind.Int));
-            long mask = CodeUtil.mask(fromBits);
-            JavaConstant constant = JavaConstant.forInt((int) mask);
-            if (fromBits == 32) {
-                append(new BinaryRegConst(IUSHR, result, inputVal, JavaConstant.forInt(0)));
-            } else if (canInlineConstant(constant)) {
-                append(new BinaryRegConst(SPARCArithmetic.IAND, result, asAllocatable(inputVal), constant, null));
-            } else {
-                Variable maskVar = newVariable(LIRKind.combine(inputVal).changeType(JavaKind.Int));
-                emitMoveConstant(maskVar, constant);
-                append(new BinaryRegReg(IAND, result, maskVar, asAllocatable(inputVal)));
-            }
-            if (toBits > 32) {
-                Variable longResult = newVariable(LIRKind.combine(inputVal).changeType(JavaKind.Long));
-                emitMove(longResult, result);
-                return longResult;
-            } else {
-                return result;
-            }
+            Value mask = emitConstant(LIRKind.value(DWORD), forLong(mask(fromBits)));
+            append(new SPARCOP3Op(And, inputVal, mask, result));
         }
+        return result;
     }
 
     @Override
     public AllocatableValue emitReinterpret(LIRKind to, Value inputVal) {
-        JavaKind from = (JavaKind) inputVal.getPlatformKind();
+        SPARCKind fromKind = (SPARCKind) inputVal.getPlatformKind();
+        SPARCKind toKind = (SPARCKind) to.getPlatformKind();
         AllocatableValue input = asAllocatable(inputVal);
         Variable result = newVariable(to);
         // These cases require a move between CPU and FPU registers:
-        switch ((JavaKind) to.getPlatformKind()) {
-            case Int:
-                switch (from) {
-                    case Float:
-                    case Double:
-                        moveBetweenFpGp(result, input);
-                        return result;
-                }
-                break;
-            case Long:
-                switch (from) {
-                    case Float:
-                    case Double:
-                        moveBetweenFpGp(result, input);
-                        return result;
-                }
-                break;
-            case Float:
-                switch (from) {
-                    case Int:
-                    case Long:
-                        moveBetweenFpGp(result, input);
-                        return result;
-                }
-                break;
-            case Double:
-                switch (from) {
-                    case Int:
-                    case Long:
-                        moveBetweenFpGp(result, input);
-                        return result;
-                }
-                break;
+        if (fromKind.isFloat() != toKind.isFloat()) {
+            moveBetweenFpGp(result, input);
+            return result;
+        } else {
+            // Otherwise, just emit an ordinary move instruction.
+            // Instructions that move or generate 32-bit register values also set the upper 32
+            // bits of the register to zero.
+            // Consequently, there is no need for a special zero-extension move.
+            return emitConvertMove(to, input);
         }
-
-        // Otherwise, just emit an ordinary move instruction.
-        // Instructions that move or generate 32-bit register values also set the upper 32
-        // bits of the register to zero.
-        // Consequently, there is no need for a special zero-extension move.
-        return emitConvertMove(to, input);
     }
 
     @Override
@@ -1219,12 +1136,12 @@
 
     public void emitNullCheck(Value address, LIRFrameState state) {
         PlatformKind kind = address.getPlatformKind();
-        assert kind == JavaKind.Object || kind == JavaKind.Long : address + " - " + kind + " not an object!";
+        assert kind == DWORD : address + " - " + kind + " not an object!";
         append(new NullCheckOp(asAddressValue(address), state));
     }
 
     public void emitLoadConstantTableBase() {
-        constantTableBase = newVariable(LIRKind.value(JavaKind.Long));
+        constantTableBase = newVariable(LIRKind.value(DWORD));
         int nextPosition = getResult().getLIR().getLIRforBlock(getCurrentBlock()).size();
         NoOp placeHolder = append(new NoOp(getCurrentBlock(), nextPosition));
         loadConstantTableBaseOp = new SPARCLoadConstantTableBaseOp(constantTableBase, placeHolder);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRKindTool.java	Wed Sep 23 15:42:58 2015 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015, 2015, 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;
+
+import jdk.internal.jvmci.common.JVMCIError;
+import jdk.internal.jvmci.meta.LIRKind;
+import jdk.internal.jvmci.sparc.SPARCKind;
+
+import com.oracle.graal.compiler.common.spi.LIRKindTool;
+
+public class SPARCLIRKindTool implements LIRKindTool {
+
+    public LIRKind getIntegerKind(int bits) {
+        if (bits <= 8) {
+            return LIRKind.value(SPARCKind.BYTE);
+        } else if (bits <= 16) {
+            return LIRKind.value(SPARCKind.HWORD);
+        } else if (bits <= 32) {
+            return LIRKind.value(SPARCKind.WORD);
+        } else {
+            assert bits <= 64;
+            return LIRKind.value(SPARCKind.DWORD);
+        }
+    }
+
+    public LIRKind getFloatingKind(int bits) {
+        switch (bits) {
+            case 32:
+                return LIRKind.value(SPARCKind.SINGLE);
+            case 64:
+                return LIRKind.value(SPARCKind.DOUBLE);
+            default:
+                throw JVMCIError.shouldNotReachHere();
+        }
+    }
+
+    public LIRKind getObjectKind() {
+        return LIRKind.reference(SPARCKind.DWORD);
+    }
+
+    public LIRKind getWordKind() {
+        return LIRKind.value(SPARCKind.DWORD);
+    }
+}
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java	Wed Sep 23 15:42:58 2015 +0200
@@ -23,12 +23,16 @@
 
 package com.oracle.graal.compiler.sparc;
 
+import static jdk.internal.jvmci.sparc.SPARCKind.BYTE;
+import static jdk.internal.jvmci.sparc.SPARCKind.DWORD;
+import static jdk.internal.jvmci.sparc.SPARCKind.HWORD;
+import static jdk.internal.jvmci.sparc.SPARCKind.WORD;
 import jdk.internal.jvmci.code.CallingConvention;
 import jdk.internal.jvmci.common.JVMCIError;
-import jdk.internal.jvmci.meta.JavaKind;
 import jdk.internal.jvmci.meta.JavaType;
 import jdk.internal.jvmci.meta.LIRKind;
 import jdk.internal.jvmci.meta.Value;
+import jdk.internal.jvmci.sparc.SPARCKind;
 
 import com.oracle.graal.compiler.gen.NodeLIRBuilder;
 import com.oracle.graal.compiler.match.ComplexMatchResult;
@@ -88,33 +92,32 @@
 
     private ComplexMatchResult emitSignExtendMemory(Access access, int fromBits, int toBits) {
         assert fromBits <= toBits && toBits <= 64;
-        JavaKind toKind = null;
-        JavaKind fromKind = null;
+        SPARCKind toKind = null;
+        SPARCKind fromKind = null;
         if (fromBits == toBits) {
             return null;
-        } else if (toBits > 32) {
-            toKind = JavaKind.Long;
-        } else if (toBits > 16) {
-            toKind = JavaKind.Int;
-        } else {
-            toKind = JavaKind.Short;
+        } else if (toBits > WORD.getSizeInBits()) {
+            toKind = DWORD;
+        } else if (toBits > HWORD.getSizeInBits()) {
+            toKind = WORD;
+        } else if (toBits > BYTE.getSizeInBits()) {
+            toKind = HWORD;
         }
         switch (fromBits) {
             case 8:
-                fromKind = JavaKind.Byte;
+                fromKind = BYTE;
                 break;
             case 16:
-                fromKind = JavaKind.Short;
+                fromKind = HWORD;
                 break;
             case 32:
-                fromKind = JavaKind.Int;
+                fromKind = WORD;
                 break;
             default:
                 throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
         }
-
-        JavaKind localFromKind = fromKind;
-        JavaKind localToKind = toKind;
+        SPARCKind localFromKind = fromKind;
+        SPARCKind localToKind = toKind;
         return builder -> {
             Value v = getLIRGeneratorTool().emitSignExtendLoad(LIRKind.value(localFromKind), operand(access.getAddress()), getState(access));
             return getLIRGeneratorTool().emitReinterpret(LIRKind.value(localToKind), v);
@@ -123,33 +126,32 @@
 
     private ComplexMatchResult emitZeroExtendMemory(Access access, int fromBits, int toBits) {
         assert fromBits <= toBits && toBits <= 64;
-        JavaKind toKind = null;
-        JavaKind fromKind = null;
+        SPARCKind toKind = null;
+        SPARCKind fromKind = null;
         if (fromBits == toBits) {
             return null;
-        } else if (toBits > 32) {
-            toKind = JavaKind.Long;
-        } else if (toBits > 16) {
-            toKind = JavaKind.Int;
-        } else {
-            toKind = JavaKind.Short;
+        } else if (toBits > WORD.getSizeInBits()) {
+            toKind = DWORD;
+        } else if (toBits > HWORD.getSizeInBits()) {
+            toKind = WORD;
+        } else if (toBits > BYTE.getSizeInBits()) {
+            toKind = HWORD;
         }
         switch (fromBits) {
             case 8:
-                fromKind = JavaKind.Byte;
+                fromKind = BYTE;
                 break;
             case 16:
-                fromKind = JavaKind.Short;
+                fromKind = HWORD;
                 break;
             case 32:
-                fromKind = JavaKind.Int;
+                fromKind = WORD;
                 break;
             default:
                 throw JVMCIError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
         }
-
-        JavaKind localFromKind = fromKind;
-        JavaKind localToKind = toKind;
+        SPARCKind localFromKind = fromKind;
+        SPARCKind localToKind = toKind;
         return builder -> {
             // Loads are always zero extending load
             Value v = getLIRGeneratorTool().emitLoad(LIRKind.value(localFromKind), operand(access.getAddress()), getState(access));
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java	Wed Sep 23 15:42:58 2015 +0200
@@ -494,7 +494,7 @@
 
         for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
             Value paramValue = params[param.index()];
-            assert paramValue.getLIRKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp()));
+            assert paramValue.getLIRKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp())) : paramValue + " " + getLIRGeneratorTool().getLIRKind(param.stamp());
             setResult(param, gen.emitMove(paramValue));
         }
     }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java	Wed Sep 23 15:42:58 2015 +0200
@@ -25,8 +25,8 @@
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.REG;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.STACK;
 import static jdk.internal.jvmci.sparc.SPARC.g0;
+import static jdk.internal.jvmci.sparc.SPARCKind.DWORD;
 import jdk.internal.jvmci.code.Register;
-import jdk.internal.jvmci.meta.JavaKind;
 import jdk.internal.jvmci.meta.LIRKind;
 import jdk.internal.jvmci.meta.Value;
 
@@ -63,7 +63,7 @@
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
 
         // Restore the thread register when coming back from the runtime.
-        SPARCMove.move(crb, masm, thread.asValue(LIRKind.value(JavaKind.Long)), threadTemp, SPARCDelayedControlTransfer.DUMMY);
+        SPARCMove.move(crb, masm, thread.asValue(LIRKind.value(DWORD)), threadTemp, SPARCDelayedControlTransfer.DUMMY);
 
         // Reset last Java frame, last Java PC and flags.
         masm.stx(g0, new SPARCAddress(thread, threadLastJavaSpOffset));
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java	Wed Sep 23 15:42:58 2015 +0200
@@ -26,9 +26,9 @@
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.STACK;
 import static jdk.internal.jvmci.code.ValueUtil.asRegister;
 import static jdk.internal.jvmci.sparc.SPARC.STACK_BIAS;
+import static jdk.internal.jvmci.sparc.SPARCKind.DWORD;
 import jdk.internal.jvmci.code.Register;
 import jdk.internal.jvmci.meta.AllocatableValue;
-import jdk.internal.jvmci.meta.JavaKind;
 import jdk.internal.jvmci.meta.LIRKind;
 import jdk.internal.jvmci.meta.Value;
 
@@ -69,6 +69,6 @@
         masm.stx(scratchRegister, new SPARCAddress(thread, threadLastJavaSpOffset));
 
         // Save the thread register when calling out to the runtime.
-        SPARCMove.move(crb, masm, threadTemp, thread.asValue(LIRKind.value(JavaKind.Long)), getDelayedControlTransfer());
+        SPARCMove.move(crb, masm, threadTemp, thread.asValue(LIRKind.value(DWORD)), getDelayedControlTransfer());
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerOp.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerOp.java	Wed Sep 23 15:42:58 2015 +0200
@@ -26,7 +26,7 @@
 import static jdk.internal.jvmci.code.ValueUtil.asRegister;
 import jdk.internal.jvmci.code.Register;
 import jdk.internal.jvmci.meta.AllocatableValue;
-import jdk.internal.jvmci.meta.JavaKind;
+import jdk.internal.jvmci.sparc.SPARCKind;
 
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler;
 import com.oracle.graal.lir.LIRInstructionClass;
@@ -56,7 +56,7 @@
 
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-        Register addrRegister = asRegister(address, JavaKind.Long);
+        Register addrRegister = asRegister(address, SPARCKind.DWORD);
         masm.jmp(addrRegister);
         masm.restoreWindow();
     }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Wed Sep 23 15:42:58 2015 +0200
@@ -66,6 +66,8 @@
 import static jdk.internal.jvmci.sparc.SPARC.g3;
 import static jdk.internal.jvmci.sparc.SPARC.g4;
 import static jdk.internal.jvmci.sparc.SPARC.g5;
+import static jdk.internal.jvmci.sparc.SPARCKind.DWORD;
+import static jdk.internal.jvmci.sparc.SPARCKind.WORD;
 
 import java.util.Map;
 
@@ -91,6 +93,7 @@
 import jdk.internal.jvmci.meta.PlatformKind;
 import jdk.internal.jvmci.meta.Value;
 import jdk.internal.jvmci.sparc.SPARC;
+import jdk.internal.jvmci.sparc.SPARCKind;
 
 import com.oracle.graal.compiler.common.calc.Condition;
 import com.oracle.graal.compiler.common.spi.ForeignCallLinkage;
@@ -103,7 +106,6 @@
 import com.oracle.graal.hotspot.debug.BenchmarkCounters;
 import com.oracle.graal.hotspot.meta.HotSpotProviders;
 import com.oracle.graal.hotspot.meta.HotSpotRegistersProvider;
-import com.oracle.graal.hotspot.nodes.type.DefaultHotSpotLIRKindTool;
 import com.oracle.graal.hotspot.stubs.Stub;
 import com.oracle.graal.lir.LIRFrameState;
 import com.oracle.graal.lir.LIRInstruction;
@@ -131,7 +133,7 @@
     private LIRFrameState currentRuntimeCallInfo;
 
     public SPARCHotSpotLIRGenerator(HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) {
-        this(new DefaultHotSpotLIRKindTool(providers.getCodeCache().getTarget().arch.getWordKind()), providers, config, cc, lirGenRes);
+        this(new SPARCHotSpotLIRKindTool(), providers, config, cc, lirGenRes);
     }
 
     protected SPARCHotSpotLIRGenerator(LIRKindTool lirKindTool, HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) {
@@ -210,7 +212,7 @@
         if (linkage.destroysRegisters() || hotspotLinkage.needsJavaFrameAnchor()) {
             HotSpotRegistersProvider registers = getProviders().getRegisters();
             Register thread = registers.getThreadRegister();
-            Value threadTemp = newVariable(LIRKind.value(JavaKind.Long));
+            Value threadTemp = newVariable(LIRKind.value(SPARCKind.DWORD));
             Register stackPointer = registers.getStackPointerRegister();
             Variable spScratch = newVariable(LIRKind.value(target().arch.getWordKind()));
             append(new SPARCHotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), thread, stackPointer, threadTemp, spScratch));
@@ -310,7 +312,7 @@
     public Variable emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) {
         LIRKind kind = newValue.getLIRKind();
         assert kind.equals(expectedValue.getLIRKind());
-        JavaKind memKind = (JavaKind) kind.getPlatformKind();
+        SPARCKind memKind = (SPARCKind) kind.getPlatformKind();
         Variable result = newVariable(newValue.getLIRKind());
         append(new CompareAndSwapOp(result, asAllocatable(address), asAllocatable(expectedValue), asAllocatable(newValue)));
         return emitConditionalMove(memKind, expectedValue, result, Condition.EQ, true, trueValue, falseValue);
@@ -355,13 +357,13 @@
     }
 
     @Override
-    protected boolean emitCompare(PlatformKind cmpKind, Value a, Value b) {
+    protected boolean emitCompare(SPARCKind cmpKind, Value a, Value b) {
         Value localA = a;
         Value localB = b;
         if (isConstantValue(a)) {
             Constant c = asConstant(a);
             if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(c)) {
-                localA = SPARC.g0.asValue(LIRKind.value(JavaKind.Int));
+                localA = SPARC.g0.asValue(LIRKind.value(WORD));
             } else if (c instanceof HotSpotObjectConstant) {
                 localA = load(localA);
             }
@@ -369,7 +371,7 @@
         if (isConstantValue(b)) {
             Constant c = asConstant(b);
             if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(c)) {
-                localB = SPARC.g0.asValue(LIRKind.value(JavaKind.Int));
+                localB = SPARC.g0.asValue(LIRKind.value(WORD));
             } else if (c instanceof HotSpotObjectConstant) {
                 localB = load(localB);
             }
@@ -380,18 +382,18 @@
     @Override
     public Value emitCompress(Value pointer, CompressEncoding encoding, boolean nonNull) {
         LIRKind inputKind = pointer.getLIRKind();
-        assert inputKind.getPlatformKind() == JavaKind.Long || inputKind.getPlatformKind() == JavaKind.Object;
+        assert inputKind.getPlatformKind() == DWORD : inputKind;
         if (inputKind.isReference(0)) {
             // oop
-            Variable result = newVariable(LIRKind.reference(JavaKind.Int));
+            Variable result = newVariable(LIRKind.reference(WORD));
             append(new SPARCHotSpotMove.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull));
             return result;
         } else {
             // metaspace pointer
-            Variable result = newVariable(LIRKind.value(JavaKind.Int));
+            Variable result = newVariable(LIRKind.value(WORD));
             AllocatableValue base = Value.ILLEGAL;
             if (encoding.base != 0) {
-                base = emitLoadConstant(LIRKind.value(JavaKind.Long), JavaConstant.forLong(encoding.base));
+                base = emitLoadConstant(LIRKind.value(DWORD), JavaConstant.forLong(encoding.base));
             }
             append(new SPARCHotSpotMove.CompressPointer(result, asAllocatable(pointer), base, encoding, nonNull));
             return result;
@@ -401,18 +403,18 @@
     @Override
     public Value emitUncompress(Value pointer, CompressEncoding encoding, boolean nonNull) {
         LIRKind inputKind = pointer.getLIRKind();
-        assert inputKind.getPlatformKind() == JavaKind.Int;
+        assert inputKind.getPlatformKind() == WORD;
         if (inputKind.isReference(0)) {
             // oop
-            Variable result = newVariable(LIRKind.reference(JavaKind.Long));
+            Variable result = newVariable(LIRKind.reference(DWORD));
             append(new SPARCHotSpotMove.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull));
             return result;
         } else {
             // metaspace pointer
-            Variable result = newVariable(LIRKind.value(JavaKind.Long));
+            Variable result = newVariable(LIRKind.value(DWORD));
             AllocatableValue base = Value.ILLEGAL;
             if (encoding.base != 0) {
-                base = emitLoadConstant(LIRKind.value(JavaKind.Long), JavaConstant.forLong(encoding.base));
+                base = emitLoadConstant(LIRKind.value(DWORD), JavaConstant.forLong(encoding.base));
             }
             append(new SPARCHotSpotMove.UncompressPointer(result, asAllocatable(pointer), base, encoding, nonNull));
             return result;
@@ -450,7 +452,6 @@
         StackSlotValue[] savedRegisterLocations = new StackSlotValue[savedRegisters.length];
         for (int i = 0; i < savedRegisters.length; i++) {
             PlatformKind kind = target().arch.getLargestStorableKind(savedRegisters[i].getRegisterCategory());
-            assert kind != JavaKind.Illegal;
             VirtualStackSlot spillSlot = getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(kind));
             savedRegisterLocations[i] = spillSlot;
         }
@@ -529,7 +530,7 @@
     @Override
     public void emitNullCheck(Value address, LIRFrameState state) {
         PlatformKind kind = address.getPlatformKind();
-        if (kind == JavaKind.Int) {
+        if (kind == WORD) {
             CompressEncoding encoding = config.getOopEncoding();
             Value uncompressed = emitUncompress(address, encoding, false);
             append(new NullCheckOp(asAddressValue(uncompressed), state));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRKindTool.java	Wed Sep 23 15:42:58 2015 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, 2015, 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.hotspot.sparc;
+
+import jdk.internal.jvmci.meta.LIRKind;
+import jdk.internal.jvmci.sparc.SPARCKind;
+
+import com.oracle.graal.compiler.sparc.SPARCLIRKindTool;
+import com.oracle.graal.hotspot.nodes.type.HotSpotLIRKindTool;
+
+public class SPARCHotSpotLIRKindTool extends SPARCLIRKindTool implements HotSpotLIRKindTool {
+
+    public LIRKind getNarrowOopKind() {
+        return LIRKind.reference(SPARCKind.WORD);
+    }
+
+    public LIRKind getNarrowPointerKind() {
+        return LIRKind.value(SPARCKind.WORD);
+    }
+}
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Wed Sep 23 15:42:58 2015 +0200
@@ -32,9 +32,9 @@
 import jdk.internal.jvmci.code.RegisterValue;
 import jdk.internal.jvmci.hotspot.HotSpotResolvedJavaMethod;
 import jdk.internal.jvmci.meta.AllocatableValue;
-import jdk.internal.jvmci.meta.JavaKind;
 import jdk.internal.jvmci.meta.LIRKind;
 import jdk.internal.jvmci.meta.Value;
+import jdk.internal.jvmci.sparc.SPARCKind;
 
 import com.oracle.graal.compiler.common.spi.ForeignCallLinkage;
 import com.oracle.graal.compiler.gen.DebugInfoBuilder;
@@ -70,7 +70,7 @@
 
     @Override
     protected DebugInfoBuilder createDebugInfoBuilder(StructuredGraph graph, NodeValueMap nodeValueMap) {
-        HotSpotLockStack lockStack = new HotSpotLockStack(gen.getResult().getFrameMapBuilder(), LIRKind.value(JavaKind.Long));
+        HotSpotLockStack lockStack = new HotSpotLockStack(gen.getResult().getFrameMapBuilder(), LIRKind.value(SPARCKind.DWORD));
         return new HotSpotDebugInfoBuilder(nodeValueMap, lockStack);
     }
 
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java	Wed Sep 23 15:42:58 2015 +0200
@@ -25,9 +25,9 @@
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.REG;
 import static jdk.internal.jvmci.code.ValueUtil.asRegister;
 import static jdk.internal.jvmci.sparc.SPARC.i7;
+import static jdk.internal.jvmci.sparc.SPARCKind.DWORD;
 import jdk.internal.jvmci.code.Register;
 import jdk.internal.jvmci.meta.AllocatableValue;
-import jdk.internal.jvmci.meta.JavaKind;
 
 import com.oracle.graal.asm.sparc.SPARCAssembler;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler;
@@ -53,7 +53,7 @@
 
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-        Register addrRegister = asRegister(address, JavaKind.Long);
+        Register addrRegister = asRegister(address, DWORD);
         masm.sub(addrRegister, SPARCAssembler.PC_RETURN_OFFSET, i7);
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotStrategySwitchOp.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotStrategySwitchOp.java	Wed Sep 23 15:42:58 2015 +0200
@@ -66,7 +66,7 @@
             if (keyConstants[index] instanceof HotSpotMetaspaceConstant) {
                 HotSpotMetaspaceConstant constant = (HotSpotMetaspaceConstant) keyConstants[index];
                 CC conditionCode = constant.isCompressed() ? CC.Icc : CC.Xcc;
-                ConditionFlag conditionFlag = SPARCControlFlow.fromCondition(conditionCode, condition, false);
+                ConditionFlag conditionFlag = SPARCControlFlow.fromCondition(true, condition, false);
                 LabelHint hint = requestHint(masm, target);
 
                 // Load constant takes one instruction
--- a/graal/com.oracle.graal.lir.jtt/src/com/oracle/graal/lir/jtt/ConstantStackCastTest.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.lir.jtt/src/com/oracle/graal/lir/jtt/ConstantStackCastTest.java	Wed Sep 23 15:42:58 2015 +0200
@@ -24,13 +24,15 @@
 
 import static com.oracle.graal.lir.LIRValueUtil.asJavaConstant;
 import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant;
-import jdk.internal.jvmci.amd64.AMD64Kind;
 import jdk.internal.jvmci.code.StackSlotValue;
 import jdk.internal.jvmci.common.JVMCIError;
 import jdk.internal.jvmci.meta.JavaConstant;
+import jdk.internal.jvmci.meta.JavaKind;
 import jdk.internal.jvmci.meta.LIRKind;
+import jdk.internal.jvmci.meta.PlatformKind;
 import jdk.internal.jvmci.meta.Value;
 
+import org.junit.Before;
 import org.junit.Test;
 
 import com.oracle.graal.lir.ConstantValue;
@@ -41,15 +43,20 @@
  * Tests move from a constant to a wider stack slot (e.g. byte constant to integer stack slot).
  */
 public class ConstantStackCastTest extends LIRTest {
+    private static PlatformKind byteKind;
+    private static final LoadConstantStackSpec stackCopyByte = new LoadConstantStackSpec();
+
+    @Before
+    public void setup() {
+        // Necessary to get the PlatformKind on which we're currently running on
+        byteKind = getBackend().getTarget().arch.getPlatformKind(JavaKind.Byte);
+        stackCopyByte.dstKind = getBackend().getTarget().getLIRKind(JavaKind.Int);
+        stackCopyByte.srcKind = getBackend().getTarget().getLIRKind(JavaKind.Byte);
+    }
 
     private static class LoadConstantStackSpec extends LIRTestSpecification {
-        protected final LIRKind dstKind;
-        protected final LIRKind srcKind;
-
-        public LoadConstantStackSpec(LIRKind dstKind, LIRKind srcKind) {
-            this.dstKind = dstKind;
-            this.srcKind = srcKind;
-        }
+        LIRKind dstKind;
+        LIRKind srcKind;
 
         @Override
         public void generate(LIRGeneratorTool gen, Value value) {
@@ -69,19 +76,16 @@
         }
 
         private static ConstantValue getConstant(LIRKind srcKind, JavaConstant c) {
-
-            switch ((AMD64Kind) srcKind.getPlatformKind()) {
-                case BYTE:
-                    JavaConstant byteConst = JavaConstant.forByte((byte) c.asInt());
-                    return new ConstantValue(srcKind, byteConst);
-                default:
-                    throw JVMCIError.shouldNotReachHere("Kind not supported: " + srcKind);
+            if (srcKind.getPlatformKind() == byteKind) {
+                JavaConstant byteConst = JavaConstant.forByte((byte) c.asInt());
+                return new ConstantValue(srcKind, byteConst);
+            } else {
+                throw JVMCIError.shouldNotReachHere("Kind not supported: " + srcKind);
             }
         }
+
     }
 
-    private static final LoadConstantStackSpec stackCopyByte = new LoadConstantStackSpec(LIRKind.value(AMD64Kind.DWORD), LIRKind.value(AMD64Kind.BYTE));
-
     @LIRIntrinsic
     public static byte testCopyByte(@SuppressWarnings("unused") LoadConstantStackSpec spec, byte value) {
         return value;
--- a/graal/com.oracle.graal.lir.jtt/src/com/oracle/graal/lir/jtt/StackMoveTest.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.lir.jtt/src/com/oracle/graal/lir/jtt/StackMoveTest.java	Wed Sep 23 15:42:58 2015 +0200
@@ -22,11 +22,13 @@
  */
 package com.oracle.graal.lir.jtt;
 
-import jdk.internal.jvmci.amd64.AMD64Kind;
 import jdk.internal.jvmci.code.StackSlotValue;
+import jdk.internal.jvmci.meta.JavaKind;
 import jdk.internal.jvmci.meta.LIRKind;
+import jdk.internal.jvmci.meta.PlatformKind;
 import jdk.internal.jvmci.meta.Value;
 
+import org.junit.Before;
 import org.junit.Test;
 
 import com.oracle.graal.lir.Variable;
@@ -34,6 +36,15 @@
 import com.oracle.graal.lir.gen.LIRGeneratorTool;
 
 public class StackMoveTest extends LIRTest {
+    private static PlatformKind byteKind;
+    private static PlatformKind shortKind;
+
+    @Before
+    public void setUp() {
+        byteKind = getBackend().getTarget().arch.getPlatformKind(JavaKind.Byte);
+        shortKind = getBackend().getTarget().arch.getPlatformKind(JavaKind.Short);
+    }
+
     private static class StackCopySpec extends LIRTestSpecification {
         @Override
         public void generate(LIRGeneratorTool gen, Value a) {
@@ -184,7 +195,7 @@
     private static final LIRTestSpecification shortStackCopy = new StackCopySpec() {
         @Override
         protected LIRKind getLIRKind(Value value) {
-            return LIRKind.value(AMD64Kind.WORD);
+            return LIRKind.value(shortKind);
         }
     };
 
@@ -218,7 +229,7 @@
     private static final LIRTestSpecification byteStackCopy = new StackCopySpec() {
         @Override
         protected LIRKind getLIRKind(Value value) {
-            return LIRKind.value(AMD64Kind.BYTE);
+            return LIRKind.value(byteKind);
         }
     };
 
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Wed Sep 23 15:42:58 2015 +0200
@@ -41,13 +41,14 @@
 import static jdk.internal.jvmci.code.ValueUtil.asRegister;
 import static jdk.internal.jvmci.code.ValueUtil.isRegister;
 import static jdk.internal.jvmci.sparc.SPARC.g0;
+import static jdk.internal.jvmci.sparc.SPARCKind.DOUBLE;
+import static jdk.internal.jvmci.sparc.SPARCKind.DWORD;
+import static jdk.internal.jvmci.sparc.SPARCKind.SINGLE;
+import static jdk.internal.jvmci.sparc.SPARCKind.WORD;
 import jdk.internal.jvmci.code.Register;
 import jdk.internal.jvmci.common.JVMCIError;
 import jdk.internal.jvmci.meta.AllocatableValue;
-import jdk.internal.jvmci.meta.JavaConstant;
-import jdk.internal.jvmci.meta.JavaKind;
 import jdk.internal.jvmci.meta.LIRKind;
-import jdk.internal.jvmci.meta.PlatformKind;
 import jdk.internal.jvmci.meta.Value;
 import jdk.internal.jvmci.sparc.SPARC;
 
@@ -62,159 +63,79 @@
 import com.oracle.graal.lir.asm.CompilationResultBuilder;
 import com.oracle.graal.lir.gen.LIRGeneratorTool;
 
-public enum SPARCArithmetic {
-    // @formatter:off
-    IADD, ISUB, IMUL, IUMUL, IDIV, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR,
-    LADD, LSUB, LMUL, LUMUL, LDIV, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR,
-    IADDCC, ISUBCC, IMULCC,
-    LADDCC, LSUBCC, LMULCC,
-    FADD, FSUB, FMUL, FDIV, FREM, FAND, FOR, FXOR,
-    DADD, DSUB, DMUL, DDIV, DREM, DAND, DOR, DXOR,
-    INEG, LNEG, FNEG, DNEG, INOT, LNOT,
-    L2I, B2I, S2I, B2L, S2L, I2L,
-    F2D, D2F,
-    I2F, I2D, F2I, D2I,
-    L2F, L2D, F2L, D2L;
-    // @formatter:on
+public class SPARCArithmetic {
+    public static final class FloatConvertOp extends SPARCLIRInstruction {
+        public static final LIRInstructionClass<FloatConvertOp> TYPE = LIRInstructionClass.create(FloatConvertOp.class);
+        public static final SizeEstimate SIZE = SizeEstimate.create(5);
 
-    /**
-     * Unary operation with separate source and destination operand.
-     */
-    public static final class Unary2Op extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
-        public static final LIRInstructionClass<Unary2Op> TYPE = LIRInstructionClass.create(Unary2Op.class);
-        public static final SizeEstimate SIZE_1 = SizeEstimate.create(1);
-        public static final SizeEstimate SIZE_5 = SizeEstimate.create(5);
+        @Opcode private final FloatConvert opcode;
+        @Def({REG, HINT}) protected Value result;
+        @Use({REG}) protected Value x;
 
-        @Opcode private final SPARCArithmetic opcode;
-        @Def({REG, HINT}) protected AllocatableValue result;
-        @Use({REG}) protected AllocatableValue x;
-
-        public Unary2Op(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x) {
-            super(TYPE);
-            this.opcode = opcode;
-            this.result = result;
-            this.x = x;
+        public enum FloatConvert {
+            F2I,
+            D2I,
+            F2L,
+            D2L
         }
 
-        @Override
-        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            emitUnary(crb, masm, opcode, result, x, null, getDelayedControlTransfer());
+        public FloatConvertOp(FloatConvert opcode, Value x, Value result) {
+            super(TYPE, SIZE);
+            this.opcode = opcode;
+            this.x = x;
+            this.result = result;
         }
 
         @Override
-        public SizeEstimate estimateSize() {
+        protected void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            Label notOrdered = new Label();
             switch (opcode) {
                 case F2L:
+                    masm.fcmp(Fcc0, Fcmps, asRegister(x, SINGLE), asRegister(x, SINGLE));
+                    masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN);
+                    masm.fstox(asRegister(x, SINGLE), asRegister(result, DOUBLE));
+                    masm.fxtod(asRegister(result), asRegister(result));
+                    masm.fsubd(asRegister(result, DOUBLE), asRegister(result, DOUBLE), asRegister(result, DOUBLE));
+                    masm.bind(notOrdered);
+                    break;
                 case F2I:
+                    masm.fcmp(Fcc0, Fcmps, asRegister(x, SINGLE), asRegister(x, SINGLE));
+                    masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN);
+                    masm.fstoi(asRegister(x, SINGLE), asRegister(result, SINGLE));
+                    masm.fitos(asRegister(result, SINGLE), asRegister(result, SINGLE));
+                    masm.fsubs(asRegister(result, SINGLE), asRegister(result, SINGLE), asRegister(result, SINGLE));
+                    masm.bind(notOrdered);
+                    break;
                 case D2L:
+                    masm.fcmp(Fcc0, Fcmpd, asRegister(x, DOUBLE), asRegister(x, DOUBLE));
+                    masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN);
+                    masm.fdtox(asRegister(x, DOUBLE), asRegister(result, DOUBLE));
+                    masm.fxtod(asRegister(result, DOUBLE), asRegister(result, DOUBLE));
+                    masm.fsubd(asRegister(result, DOUBLE), asRegister(result, DOUBLE), asRegister(result, DOUBLE));
+                    masm.bind(notOrdered);
+                    break;
                 case D2I:
-                    return SIZE_5;
+                    masm.fcmp(Fcc0, Fcmpd, asRegister(x, DOUBLE), asRegister(x, DOUBLE));
+                    masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN);
+                    masm.fdtoi(asRegister(x, DOUBLE), asRegister(result, SINGLE));
+                    masm.fitos(asRegister(result, SINGLE), asRegister(result, SINGLE));
+                    masm.fsubs(asRegister(result, SINGLE), asRegister(result, SINGLE), asRegister(result, SINGLE));
+                    masm.bind(notOrdered);
+                    break;
                 default:
-                    return SIZE_1;
+                    throw JVMCIError.shouldNotReachHere("missing: " + opcode);
             }
         }
     }
 
     /**
-     * Binary operation with two operands. The first source operand is combined with the
-     * destination. The second source operand must be a register.
-     */
-    public static final class BinaryRegReg extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
-        public static final LIRInstructionClass<BinaryRegReg> TYPE = LIRInstructionClass.create(BinaryRegReg.class);
-        public static final SizeEstimate SIZE_1 = SizeEstimate.create(1);
-        public static final SizeEstimate SIZE_3 = SizeEstimate.create(3);
-        public static final SizeEstimate SIZE_7 = SizeEstimate.create(7);
-
-        @Opcode private final SPARCArithmetic opcode;
-        @Def({REG}) protected Value result;
-        @Use({REG}) protected Value x;
-        @Alive({REG}) protected Value y;
-        @State LIRFrameState state;
-
-        public BinaryRegReg(SPARCArithmetic opcode, Value result, Value x, Value y) {
-            this(opcode, result, x, y, null);
-        }
-
-        public BinaryRegReg(SPARCArithmetic opcode, Value result, Value x, Value y, LIRFrameState state) {
-            super(TYPE);
-            this.opcode = opcode;
-            this.result = result;
-            this.x = x;
-            this.y = y;
-            this.state = state;
-        }
-
-        @Override
-        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            emitRegReg(crb, masm, opcode, result, x, y, state, getDelayedControlTransfer());
-        }
-
-        @Override
-        public void verify() {
-            super.verify();
-            verifyKind(opcode, result.getPlatformKind(), x.getPlatformKind(), y.getPlatformKind());
-        }
-
-        @Override
-        public SizeEstimate estimateSize() {
-            switch (opcode) {
-                case IMULCC:
-                    return SIZE_7;
-                case IUDIV:
-                case IDIV:
-                    return SIZE_3;
-                default:
-                    return SIZE_1;
-            }
-        }
-    }
-
-    /**
-     * Binary operation with single source/destination operand and one constant.
-     */
-    public static final class BinaryRegConst extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
-        public static final LIRInstructionClass<BinaryRegConst> TYPE = LIRInstructionClass.create(BinaryRegConst.class);
-        public static final SizeEstimate SIZE = SizeEstimate.create(1);
-
-        @Opcode private final SPARCArithmetic opcode;
-        @Def({REG}) protected AllocatableValue result;
-        @Use({REG}) protected Value x;
-        @State protected LIRFrameState state;
-        protected JavaConstant y;
-
-        public BinaryRegConst(SPARCArithmetic opcode, AllocatableValue result, Value x, JavaConstant y) {
-            this(opcode, result, x, y, null);
-        }
-
-        public BinaryRegConst(SPARCArithmetic opcode, AllocatableValue result, Value x, JavaConstant y, LIRFrameState state) {
-            super(TYPE, SIZE);
-            this.opcode = opcode;
-            this.result = result;
-            this.x = x;
-            this.y = y;
-            this.state = state;
-        }
-
-        @Override
-        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            emitRegConstant(crb, masm, opcode, result, x, y, null, getDelayedControlTransfer());
-        }
-
-        @Override
-        public void verify() {
-            super.verify();
-            verifyKind(opcode, result.getPlatformKind(), x.getPlatformKind(), y.getJavaKind());
-        }
-    }
-
-    /**
      * Special LIR instruction as it requires a bunch of scratch registers.
      */
     public static final class RemOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
         public static final LIRInstructionClass<RemOp> TYPE = LIRInstructionClass.create(RemOp.class);
         public static final SizeEstimate SIZE = SizeEstimate.create(4);
 
-        @Opcode private final SPARCArithmetic opcode;
+        @Opcode private final Rem opcode;
         @Def({REG}) protected Value result;
         @Alive({REG, CONST}) protected Value x;
         @Alive({REG, CONST}) protected Value y;
@@ -222,26 +143,105 @@
         @Temp({REG}) protected Value scratch2;
         @State protected LIRFrameState state;
 
-        public RemOp(SPARCArithmetic opcode, Value result, Value x, Value y, LIRFrameState state, LIRGeneratorTool gen) {
+        public enum Rem {
+            IUREM,
+            LUREM
+        }
+
+        public RemOp(Rem opcode, Value result, Value x, Value y, Value scratch1, Value scratch2, LIRFrameState state) {
             super(TYPE, SIZE);
             this.opcode = opcode;
             this.result = result;
             this.x = x;
             this.y = y;
-            this.scratch1 = gen.newVariable(LIRKind.combine(x, y));
-            this.scratch2 = gen.newVariable(LIRKind.combine(x, y));
+            this.scratch1 = scratch1;
+            this.scratch2 = scratch2;
             this.state = state;
         }
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            emitRem(crb, masm, opcode, result, x, y, scratch1, scratch2, state, getDelayedControlTransfer());
+            if (!isJavaConstant(x) && isJavaConstant(y)) {
+                assert isSimm13(crb.asIntConst(y));
+                assert !x.equals(scratch1);
+                assert !x.equals(scratch2);
+                assert !y.equals(scratch1);
+                switch (opcode) {
+                    case LUREM:
+                        crb.recordImplicitException(masm.position(), state);
+                        masm.udivx(asRegister(x, DWORD), crb.asIntConst(y), asRegister(scratch1, DWORD));
+                        masm.mulx(asRegister(scratch1, DWORD), crb.asIntConst(y), asRegister(scratch2, DWORD));
+                        getDelayedControlTransfer().emitControlTransfer(crb, masm);
+                        masm.sub(asRegister(x, DWORD), asRegister(scratch2, DWORD), asRegister(result, DWORD));
+                        break;
+                    case IUREM:
+                        JVMCIError.unimplemented();
+                        break;
+                    default:
+                        throw JVMCIError.shouldNotReachHere();
+                }
+            } else if (isRegister(x) && isRegister(y)) {
+                Value xLeft = x;
+                switch (opcode) {
+                    case LUREM:
+                        if (isJavaConstant(x)) {
+                            new Setx(crb.asLongConst(x), asRegister(scratch2, DWORD), false).emit(masm);
+                            xLeft = scratch2;
+                        }
+                        assert !asRegister(xLeft, DWORD).equals(asRegister(scratch1, DWORD));
+                        assert !asRegister(y, DWORD).equals(asRegister(scratch1, DWORD));
+                        crb.recordImplicitException(masm.position(), state);
+                        masm.udivx(asRegister(xLeft, DWORD), asRegister(y, DWORD), asRegister(scratch1, DWORD));
+                        masm.mulx(asRegister(scratch1, DWORD), asRegister(y, DWORD), asRegister(scratch1, DWORD));
+                        getDelayedControlTransfer().emitControlTransfer(crb, masm);
+                        masm.sub(asRegister(xLeft, DWORD), asRegister(scratch1, DWORD), asRegister(result, DWORD));
+                        break;
+                    case IUREM:
+                        assert !asRegister(result, WORD).equals(asRegister(scratch1, WORD));
+                        assert !asRegister(result, WORD).equals(asRegister(scratch2, WORD));
+                        masm.srl(asRegister(x, WORD), 0, asRegister(scratch1, WORD));
+                        masm.srl(asRegister(y, WORD), 0, asRegister(result, WORD));
+                        crb.recordImplicitException(masm.position(), state);
+                        masm.udivx(asRegister(scratch1, WORD), asRegister(result, WORD), asRegister(scratch2, WORD));
+                        masm.mulx(asRegister(scratch2, WORD), asRegister(result, WORD), asRegister(result, WORD));
+                        getDelayedControlTransfer().emitControlTransfer(crb, masm);
+                        masm.sub(asRegister(scratch1, WORD), asRegister(result, WORD), asRegister(result, WORD));
+                        break;
+                    default:
+                        throw JVMCIError.shouldNotReachHere();
+                }
+            } else {
+                throw JVMCIError.shouldNotReachHere();
+            }
+        }
+    }
+
+    public static final class SPARCIMulccOp extends SPARCLIRInstruction {
+        public static final LIRInstructionClass<SPARCIMulccOp> TYPE = LIRInstructionClass.create(SPARCIMulccOp.class);
+        public static final SizeEstimate SIZE = SizeEstimate.create(10);
+        @Def({REG}) protected Value result;
+        @Alive({REG}) protected Value x;
+        @Alive({REG}) protected Value y;
+
+        public SPARCIMulccOp(Value result, Value x, Value y) {
+            super(TYPE, SIZE);
+            this.result = result;
+            this.x = x;
+            this.y = y;
         }
 
         @Override
-        public void verify() {
-            super.verify();
-            verifyKind(opcode, result.getPlatformKind(), x.getPlatformKind(), y.getPlatformKind());
+        protected void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            try (ScratchRegister tmpScratch = masm.getScratchRegister()) {
+                Register tmp = tmpScratch.getRegister();
+                masm.mulx(asRegister(x, WORD), asRegister(y, WORD), asRegister(result, WORD));
+                Label noOverflow = new Label();
+                masm.sra(asRegister(result, WORD), 0, tmp);
+                masm.xorcc(SPARC.g0, SPARC.g0, SPARC.g0);
+                masm.compareBranch(tmp, asRegister(result), Equal, Xcc, noOverflow, PREDICT_TAKEN, null);
+                masm.wrccr(SPARC.g0, 1 << (SPARCAssembler.CCR_ICC_SHIFT + SPARCAssembler.CCR_V_SHIFT));
+                masm.bind(noOverflow);
+            }
         }
     }
 
@@ -270,21 +270,21 @@
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             Label noOverflow = new Label();
-            masm.mulx(asRegister(x, JavaKind.Long), asRegister(y, JavaKind.Long), asRegister(result, JavaKind.Long));
+            masm.mulx(asRegister(x, DWORD), asRegister(y, DWORD), asRegister(result, DWORD));
 
             // Calculate the upper 64 bit signed := (umulxhi product - (x{63}&y + y{63}&x))
-            masm.umulxhi(asRegister(x, JavaKind.Long), asRegister(y, JavaKind.Long), asRegister(scratch1, JavaKind.Long));
-            masm.srax(asRegister(x, JavaKind.Long), 63, asRegister(scratch2, JavaKind.Long));
-            masm.and(asRegister(scratch2, JavaKind.Long), asRegister(y, JavaKind.Long), asRegister(scratch2, JavaKind.Long));
-            masm.sub(asRegister(scratch1, JavaKind.Long), asRegister(scratch2, JavaKind.Long), asRegister(scratch1, JavaKind.Long));
+            masm.umulxhi(asRegister(x, DWORD), asRegister(y, DWORD), asRegister(scratch1, DWORD));
+            masm.srax(asRegister(x, DWORD), 63, asRegister(scratch2, DWORD));
+            masm.and(asRegister(scratch2, DWORD), asRegister(y, DWORD), asRegister(scratch2, DWORD));
+            masm.sub(asRegister(scratch1, DWORD), asRegister(scratch2, DWORD), asRegister(scratch1, DWORD));
 
-            masm.srax(asRegister(y, JavaKind.Long), 63, asRegister(scratch2, JavaKind.Long));
-            masm.and(asRegister(scratch2, JavaKind.Long), asRegister(x, JavaKind.Long), asRegister(scratch2, JavaKind.Long));
-            masm.sub(asRegister(scratch1, JavaKind.Long), asRegister(scratch2, JavaKind.Long), asRegister(scratch1, JavaKind.Long));
+            masm.srax(asRegister(y, DWORD), 63, asRegister(scratch2, DWORD));
+            masm.and(asRegister(scratch2, DWORD), asRegister(x, DWORD), asRegister(scratch2, DWORD));
+            masm.sub(asRegister(scratch1, DWORD), asRegister(scratch2, DWORD), asRegister(scratch1, DWORD));
 
             // Now construct the lower half and compare
-            masm.srax(asRegister(result, JavaKind.Long), 63, asRegister(scratch2, JavaKind.Long));
-            masm.cmp(asRegister(scratch1, JavaKind.Long), asRegister(scratch2, JavaKind.Long));
+            masm.srax(asRegister(result, DWORD), 63, asRegister(scratch2, DWORD));
+            masm.cmp(asRegister(scratch1, DWORD), asRegister(scratch2, DWORD));
             masm.bpcc(Equal, NOT_ANNUL, noOverflow, Xcc, PREDICT_TAKEN);
             masm.nop();
             masm.wrccr(g0, 1 << (CCR_XCC_SHIFT + CCR_V_SHIFT));
@@ -292,624 +292,22 @@
         }
     }
 
-    private static void emitRegConstant(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, JavaConstant src2, LIRFrameState info,
-                    SPARCDelayedControlTransfer delaySlotLir) {
-        assert isSimm13(src2.asLong()) : src2;
-        int constant = (int) src2.asLong();
-        int exceptionOffset = -1;
-        delaySlotLir.emitControlTransfer(crb, masm);
-        switch (opcode) {
-            case IADD:
-                masm.add(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int));
-                break;
-            case IADDCC:
-                masm.addcc(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int));
-                break;
-            case ISUB:
-                masm.sub(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int));
-                break;
-            case ISUBCC:
-                masm.subcc(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int));
-                break;
-            case IMUL:
-                masm.mulx(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int));
-                break;
-            case IMULCC:
-                throw JVMCIError.unimplemented();
-            case IDIV:
-                masm.sra(asRegister(src1), 0, asRegister(src1));
-                masm.sdivx(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int));
-                break;
-            case IUDIV:
-                masm.srl(asRegister(src1), 0, asRegister(src1));
-                masm.udivx(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int));
-                break;
-            case IAND:
-                masm.and(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int));
-                break;
-            case ISHL:
-                masm.sll(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int));
-                break;
-            case ISHR:
-                masm.sra(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int));
-                break;
-            case IUSHR:
-                masm.srl(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int));
-                break;
-            case IOR:
-                masm.or(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int));
-                break;
-            case IXOR:
-                masm.xor(asRegister(src1, JavaKind.Int), constant, asRegister(dst, JavaKind.Int));
-                break;
-            case LADD:
-                masm.add(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long));
-                break;
-            case LADDCC:
-                masm.addcc(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long));
-                break;
-            case LSUB:
-                masm.sub(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long));
-                break;
-            case LSUBCC:
-                masm.subcc(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long));
-                break;
-            case LMUL:
-                masm.mulx(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long));
-                break;
-            case LDIV:
-                exceptionOffset = masm.position();
-                masm.sdivx(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long));
-                break;
-            case LUDIV:
-                exceptionOffset = masm.position();
-                masm.udivx(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long));
-                break;
-            case LAND:
-                masm.and(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long));
-                break;
-            case LOR:
-                masm.or(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long));
-                break;
-            case LXOR:
-                masm.xor(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long));
-                break;
-            case LSHL:
-                masm.sllx(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long));
-                break;
-            case LSHR:
-                masm.srax(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long));
-                break;
-            case LUSHR:
-                masm.srlx(asRegister(src1, JavaKind.Long), constant, asRegister(dst, JavaKind.Long));
-                break;
-            case DAND: // Has no constant implementation in SPARC
-            case FADD:
-            case FMUL:
-            case FDIV:
-            case DADD:
-            case DMUL:
-            case DDIV:
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-        if (info != null) {
-            assert exceptionOffset != -1;
-            crb.recordImplicitException(exceptionOffset, info);
-        }
-    }
-
-    public static void emitRegReg(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info,
-                    SPARCDelayedControlTransfer delaySlotLir) {
-        int exceptionOffset = -1;
-        assert !isJavaConstant(src1) : src1;
-        assert !isJavaConstant(src2) : src2;
-        switch (opcode) {
-            case IADD:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.add(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                break;
-            case IADDCC:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.addcc(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                break;
-            case ISUB:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.sub(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                break;
-            case ISUBCC:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.subcc(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                break;
-            case IMUL:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.mulx(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                break;
-            case IMULCC:
-                try (ScratchRegister tmpScratch = masm.getScratchRegister()) {
-                    Register tmp = tmpScratch.getRegister();
-                    masm.mulx(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                    Label noOverflow = new Label();
-                    masm.sra(asRegister(dst, JavaKind.Int), 0, tmp);
-                    masm.xorcc(SPARC.g0, SPARC.g0, SPARC.g0);
-                    masm.compareBranch(tmp, asRegister(dst), Equal, Xcc, noOverflow, PREDICT_TAKEN, null);
-                    masm.wrccr(SPARC.g0, 1 << (SPARCAssembler.CCR_ICC_SHIFT + SPARCAssembler.CCR_V_SHIFT));
-                    masm.bind(noOverflow);
-                }
-                break;
-            case IDIV:
-                masm.signx(asRegister(src1, JavaKind.Int), asRegister(src1, JavaKind.Int));
-                masm.signx(asRegister(src2, JavaKind.Int), asRegister(src2, JavaKind.Int));
-                delaySlotLir.emitControlTransfer(crb, masm);
-                exceptionOffset = masm.position();
-                masm.sdivx(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                break;
-            case IUDIV:
-                masm.srl(asRegister(src1, JavaKind.Int), 0, asRegister(src1, JavaKind.Int));
-                masm.srl(asRegister(src2, JavaKind.Int), 0, asRegister(src2, JavaKind.Int));
-                delaySlotLir.emitControlTransfer(crb, masm);
-                exceptionOffset = masm.position();
-                masm.udivx(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                break;
-            case IAND:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.and(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                break;
-            case IOR:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.or(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                break;
-            case IXOR:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.xor(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                break;
-            case ISHL:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.sll(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                break;
-            case ISHR:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.sra(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                break;
-            case IUSHR:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.srl(asRegister(src1, JavaKind.Int), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                break;
-            case IREM:
-                throw JVMCIError.unimplemented();
-            case LADD:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.add(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(dst, JavaKind.Long));
-                break;
-            case LADDCC:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.addcc(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(dst, JavaKind.Long));
-                break;
-            case LSUB:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.sub(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(dst, JavaKind.Long));
-                break;
-            case LSUBCC:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.subcc(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(dst, JavaKind.Long));
-                break;
-            case LMUL:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.mulx(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(dst, JavaKind.Long));
-                break;
-            case LMULCC:
-                throw JVMCIError.unimplemented();
-            case LDIV:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                exceptionOffset = masm.position();
-                masm.sdivx(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(dst, JavaKind.Long));
-                break;
-            case LUDIV:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                exceptionOffset = masm.position();
-                masm.udivx(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(dst, JavaKind.Long));
-                break;
-            case LAND:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.and(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(dst, JavaKind.Long));
-                break;
-            case LOR:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.or(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(dst, JavaKind.Long));
-                break;
-            case LXOR:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.xor(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(dst, JavaKind.Long));
-                break;
-            case LSHL:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.sllx(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Long));
-                break;
-            case LSHR:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.srax(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Long));
-                break;
-            case LUSHR:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.srlx(asRegister(src1, JavaKind.Long), asRegister(src2, JavaKind.Int), asRegister(dst, JavaKind.Long));
-                break;
-            case FADD:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.fadds(asRegister(src1, JavaKind.Float), asRegister(src2, JavaKind.Float), asRegister(dst, JavaKind.Float));
-                break;
-            case FSUB:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.fsubs(asRegister(src1, JavaKind.Float), asRegister(src2, JavaKind.Float), asRegister(dst, JavaKind.Float));
-                break;
-            case FMUL:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                if (dst.getPlatformKind() == JavaKind.Double) {
-                    masm.fsmuld(asRegister(src1, JavaKind.Float), asRegister(src2, JavaKind.Float), asRegister(dst, JavaKind.Double));
-                } else if (dst.getPlatformKind() == JavaKind.Float) {
-                    masm.fmuls(asRegister(src1, JavaKind.Float), asRegister(src2, JavaKind.Float), asRegister(dst, JavaKind.Float));
-                }
-                break;
-            case FDIV:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                exceptionOffset = masm.position();
-                masm.fdivs(asRegister(src1, JavaKind.Float), asRegister(src2, JavaKind.Float), asRegister(dst, JavaKind.Float));
-                break;
-            case FREM:
-                throw JVMCIError.unimplemented();
-            case DADD:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.faddd(asRegister(src1, JavaKind.Double), asRegister(src2, JavaKind.Double), asRegister(dst, JavaKind.Double));
-                break;
-            case DSUB:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.fsubd(asRegister(src1, JavaKind.Double), asRegister(src2, JavaKind.Double), asRegister(dst, JavaKind.Double));
-                break;
-            case DMUL:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.fmuld(asRegister(src1, JavaKind.Double), asRegister(src2, JavaKind.Double), asRegister(dst, JavaKind.Double));
-                break;
-            case DDIV:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                exceptionOffset = masm.position();
-                masm.fdivd(asRegister(src1, JavaKind.Double), asRegister(src2, JavaKind.Double), asRegister(dst, JavaKind.Double));
-                break;
-            case DREM:
-                throw JVMCIError.unimplemented();
-            case DAND:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.fandd(asRegister(src1, JavaKind.Double), asRegister(src2, JavaKind.Double), asRegister(dst, JavaKind.Double));
-                break;
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-        if (info != null) {
-            assert exceptionOffset != -1;
-            crb.recordImplicitException(exceptionOffset, info);
-        }
-    }
-
-    public static void emitRem(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, Value scratch1, Value scratch2, LIRFrameState info,
-                    SPARCDelayedControlTransfer delaySlotLir) {
-        int exceptionOffset = -1;
-        if (!isJavaConstant(src1) && isJavaConstant(src2)) {
-            assert isSimm13(crb.asIntConst(src2));
-            assert !src1.equals(scratch1);
-            assert !src1.equals(scratch2);
-            assert !src2.equals(scratch1);
-            switch (opcode) {
-                case IREM:
-                    masm.sra(asRegister(src1, JavaKind.Int), 0, asRegister(dst, JavaKind.Int));
-                    exceptionOffset = masm.position();
-                    masm.sdivx(asRegister(dst, JavaKind.Int), crb.asIntConst(src2), asRegister(scratch1, JavaKind.Int));
-                    masm.mulx(asRegister(scratch1, JavaKind.Int), crb.asIntConst(src2), asRegister(scratch2, JavaKind.Int));
-                    delaySlotLir.emitControlTransfer(crb, masm);
-                    masm.sub(asRegister(dst, JavaKind.Int), asRegister(scratch2, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                    break;
-                case LREM:
-                    exceptionOffset = masm.position();
-                    masm.sdivx(asRegister(src1, JavaKind.Long), crb.asIntConst(src2), asRegister(scratch1, JavaKind.Long));
-                    masm.mulx(asRegister(scratch1, JavaKind.Long), crb.asIntConst(src2), asRegister(scratch2, JavaKind.Long));
-                    delaySlotLir.emitControlTransfer(crb, masm);
-                    masm.sub(asRegister(src1, JavaKind.Long), asRegister(scratch2, JavaKind.Long), asRegister(dst, JavaKind.Long));
-                    break;
-                case LUREM:
-                    exceptionOffset = masm.position();
-                    masm.udivx(asRegister(src1, JavaKind.Long), crb.asIntConst(src2), asRegister(scratch1, JavaKind.Long));
-                    masm.mulx(asRegister(scratch1, JavaKind.Long), crb.asIntConst(src2), asRegister(scratch2, JavaKind.Long));
-                    delaySlotLir.emitControlTransfer(crb, masm);
-                    masm.sub(asRegister(src1, JavaKind.Long), asRegister(scratch2, JavaKind.Long), asRegister(dst, JavaKind.Long));
-                    break;
-                case IUREM:
-                    JVMCIError.unimplemented();
-                    break;
-                default:
-                    throw JVMCIError.shouldNotReachHere();
-            }
-        } else if (isRegister(src1) && isRegister(src2)) {
-            Value srcLeft = src1;
-            switch (opcode) {
-                case LREM:
-                    if (isJavaConstant(src1)) {
-                        new Setx(crb.asLongConst(src1), asRegister(scratch2, JavaKind.Long), false).emit(masm);
-                        srcLeft = scratch2;
-                    }
-                    assert !asRegister(srcLeft, JavaKind.Long).equals(asRegister(scratch1, JavaKind.Long));
-                    assert !asRegister(src2, JavaKind.Long).equals(asRegister(scratch1, JavaKind.Long));
-                    // But src2 can be scratch2
-                    exceptionOffset = masm.position();
-                    masm.sdivx(asRegister(srcLeft, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(scratch1, JavaKind.Long));
-                    masm.mulx(asRegister(scratch1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(scratch1, JavaKind.Long));
-                    delaySlotLir.emitControlTransfer(crb, masm);
-                    masm.sub(asRegister(srcLeft, JavaKind.Long), asRegister(scratch1, JavaKind.Long), asRegister(dst, JavaKind.Long));
-                    break;
-                case LUREM:
-                    if (isJavaConstant(src1)) {
-                        new Setx(crb.asLongConst(src1), asRegister(scratch2, JavaKind.Long), false).emit(masm);
-                        srcLeft = scratch2;
-                    }
-                    assert !asRegister(srcLeft, JavaKind.Long).equals(asRegister(scratch1, JavaKind.Long));
-                    assert !asRegister(src2, JavaKind.Long).equals(asRegister(scratch1, JavaKind.Long));
-                    exceptionOffset = masm.position();
-                    masm.udivx(asRegister(srcLeft, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(scratch1, JavaKind.Long));
-                    masm.mulx(asRegister(scratch1, JavaKind.Long), asRegister(src2, JavaKind.Long), asRegister(scratch1, JavaKind.Long));
-                    delaySlotLir.emitControlTransfer(crb, masm);
-                    masm.sub(asRegister(srcLeft, JavaKind.Long), asRegister(scratch1, JavaKind.Long), asRegister(dst, JavaKind.Long));
-                    break;
-                case IREM:
-                    if (isJavaConstant(src1)) {
-                        new Setx(crb.asIntConst(src1), asRegister(scratch2, JavaKind.Int), false).emit(masm);
-                        srcLeft = scratch2;
-                    }
-                    assert !asRegister(srcLeft, JavaKind.Int).equals(asRegister(scratch1, JavaKind.Int));
-                    assert !asRegister(src2, JavaKind.Int).equals(asRegister(scratch1, JavaKind.Int));
-                    masm.sra(asRegister(src1, JavaKind.Int), 0, asRegister(scratch1, JavaKind.Int));
-                    masm.sra(asRegister(src2, JavaKind.Int), 0, asRegister(scratch2, JavaKind.Int));
-                    exceptionOffset = masm.position();
-                    masm.sdivx(asRegister(scratch1, JavaKind.Int), asRegister(scratch2, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                    masm.mulx(asRegister(dst, JavaKind.Int), asRegister(scratch2, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                    delaySlotLir.emitControlTransfer(crb, masm);
-                    masm.sub(asRegister(scratch1, JavaKind.Int), asRegister(dst, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                    break;
-                case IUREM:
-                    assert !asRegister(dst, JavaKind.Int).equals(asRegister(scratch1, JavaKind.Int));
-                    assert !asRegister(dst, JavaKind.Int).equals(asRegister(scratch2, JavaKind.Int));
-                    masm.srl(asRegister(src1, JavaKind.Int), 0, asRegister(scratch1, JavaKind.Int));
-                    masm.srl(asRegister(src2, JavaKind.Int), 0, asRegister(dst, JavaKind.Int));
-                    exceptionOffset = masm.position();
-                    masm.udivx(asRegister(scratch1, JavaKind.Int), asRegister(dst, JavaKind.Int), asRegister(scratch2, JavaKind.Int));
-                    masm.mulx(asRegister(scratch2, JavaKind.Int), asRegister(dst, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                    delaySlotLir.emitControlTransfer(crb, masm);
-                    masm.sub(asRegister(scratch1, JavaKind.Int), asRegister(dst, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                    break;
-                default:
-                    throw JVMCIError.shouldNotReachHere();
-            }
-        } else {
-            throw JVMCIError.shouldNotReachHere();
-        }
-        if (info != null) {
-            assert exceptionOffset != -1;
-            crb.recordImplicitException(exceptionOffset, info);
-        }
-    }
-
-    public static void emitUnary(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src, LIRFrameState info, SPARCDelayedControlTransfer delaySlotLir) {
-        int exceptionOffset = -1;
-        Label notOrdered = new Label();
-        switch (opcode) {
-            case INEG:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.neg(asRegister(src, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                break;
-            case LNEG:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.neg(asRegister(src, JavaKind.Long), asRegister(dst, JavaKind.Long));
-                break;
-            case INOT:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.not(asRegister(src, JavaKind.Int), asRegister(dst, JavaKind.Int));
-                break;
-            case LNOT:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.not(asRegister(src, JavaKind.Long), asRegister(dst, JavaKind.Long));
-                break;
-            case D2F:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.fdtos(asRegister(src, JavaKind.Double), asRegister(dst, JavaKind.Float));
-                break;
-            case L2D:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.fxtod(asRegister(src, JavaKind.Double), asRegister(dst, JavaKind.Double));
-                break;
-            case L2F:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.fxtos(asRegister(src, JavaKind.Double), asRegister(dst, JavaKind.Float));
-                break;
-            case I2D:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.fitod(asRegister(src, JavaKind.Float), asRegister(dst, JavaKind.Double));
-                break;
-            case I2L:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.signx(asRegister(src, JavaKind.Int), asRegister(dst, JavaKind.Long));
-                break;
-            case L2I:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.signx(asRegister(src, JavaKind.Long), asRegister(dst, JavaKind.Int));
-                break;
-            case B2L:
-                masm.sll(asRegister(src), 24, asRegister(dst, JavaKind.Long));
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.sra(asRegister(dst, JavaKind.Long), 24, asRegister(dst, JavaKind.Long));
-                break;
-            case B2I:
-                masm.sll(asRegister(src), 24, asRegister(dst, JavaKind.Int));
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.sra(asRegister(dst, JavaKind.Int), 24, asRegister(dst, JavaKind.Int));
-                break;
-            case S2L:
-                masm.sll(asRegister(src), 16, asRegister(dst, JavaKind.Long));
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.sra(asRegister(dst, JavaKind.Long), 16, asRegister(dst, JavaKind.Long));
-                break;
-            case S2I:
-                masm.sll(asRegister(src), 16, asRegister(dst, JavaKind.Int));
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.sra(asRegister(dst, JavaKind.Int), 16, asRegister(dst, JavaKind.Int));
-                break;
-            case I2F:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.fitos(asRegister(src, JavaKind.Float), asRegister(dst, JavaKind.Float));
-                break;
-            case F2D:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.fstod(asRegister(src, JavaKind.Float), asRegister(dst, JavaKind.Double));
-                break;
-            case F2L:
-                masm.fcmp(Fcc0, Fcmps, asRegister(src, JavaKind.Float), asRegister(src, JavaKind.Float));
-                masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN);
-                masm.fstox(asRegister(src, JavaKind.Float), asRegister(dst, JavaKind.Double));
-                masm.fxtod(asRegister(dst), asRegister(dst));
-                masm.fsubd(asRegister(dst, JavaKind.Double), asRegister(dst, JavaKind.Double), asRegister(dst, JavaKind.Double));
-                masm.bind(notOrdered);
-                break;
-            case F2I:
-                masm.fcmp(Fcc0, Fcmps, asRegister(src, JavaKind.Float), asRegister(src, JavaKind.Float));
-                masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN);
-                masm.fstoi(asRegister(src, JavaKind.Float), asRegister(dst, JavaKind.Float));
-                masm.fitos(asRegister(dst, JavaKind.Float), asRegister(dst, JavaKind.Float));
-                masm.fsubs(asRegister(dst, JavaKind.Float), asRegister(dst, JavaKind.Float), asRegister(dst, JavaKind.Float));
-                masm.bind(notOrdered);
-                break;
-            case D2L:
-                masm.fcmp(Fcc0, Fcmpd, asRegister(src, JavaKind.Double), asRegister(src, JavaKind.Double));
-                masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN);
-                masm.fdtox(asRegister(src, JavaKind.Double), asRegister(dst, JavaKind.Double));
-                masm.fxtod(asRegister(dst, JavaKind.Double), asRegister(dst, JavaKind.Double));
-                masm.fsubd(asRegister(dst, JavaKind.Double), asRegister(dst, JavaKind.Double), asRegister(dst, JavaKind.Double));
-                masm.bind(notOrdered);
-                break;
-            case D2I:
-                masm.fcmp(Fcc0, Fcmpd, asRegister(src, JavaKind.Double), asRegister(src, JavaKind.Double));
-                masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN);
-                masm.fdtoi(asRegister(src, JavaKind.Double), asRegister(dst, JavaKind.Float));
-                masm.fitos(asRegister(dst, JavaKind.Float), asRegister(dst, JavaKind.Float));
-                masm.fsubs(asRegister(dst, JavaKind.Float), asRegister(dst, JavaKind.Float), asRegister(dst, JavaKind.Float));
-                masm.bind(notOrdered);
-                break;
-            case FNEG:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.fnegs(asRegister(src, JavaKind.Float), asRegister(dst, JavaKind.Float));
-                break;
-            case DNEG:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.fnegd(asRegister(src, JavaKind.Double), asRegister(dst, JavaKind.Double));
-                break;
-            default:
-                throw JVMCIError.shouldNotReachHere("missing: " + opcode);
-        }
-        if (info != null) {
-            assert exceptionOffset != -1;
-            crb.recordImplicitException(exceptionOffset, info);
-        }
-    }
-
-    private static void verifyKind(SPARCArithmetic opcode, PlatformKind result, PlatformKind x, PlatformKind y) {
-        JavaKind rk;
-        JavaKind xk;
-        JavaKind yk;
-        JavaKind xsk;
-        JavaKind ysk;
-
-        switch (opcode) {
-            case IADD:
-            case IADDCC:
-            case ISUB:
-            case ISUBCC:
-            case IMUL:
-            case IMULCC:
-            case IDIV:
-            case IREM:
-            case IAND:
-            case IOR:
-            case IXOR:
-            case ISHL:
-            case ISHR:
-            case IUSHR:
-            case IUDIV:
-            case IUREM:
-                rk = ((JavaKind) result).getStackKind();
-                xsk = ((JavaKind) x).getStackKind();
-                ysk = ((JavaKind) y).getStackKind();
-                boolean valid = false;
-                for (JavaKind k : new JavaKind[]{JavaKind.Int, JavaKind.Short, JavaKind.Byte, JavaKind.Char}) {
-                    valid |= rk == k && xsk == k && ysk == k;
-                }
-                assert valid : "rk: " + rk + " xsk: " + xsk + " ysk: " + ysk;
-                break;
-            case LADD:
-            case LADDCC:
-            case LSUB:
-            case LSUBCC:
-            case LMUL:
-            case LMULCC:
-            case LDIV:
-            case LREM:
-            case LAND:
-            case LOR:
-            case LXOR:
-            case LUDIV:
-            case LUREM:
-                rk = (JavaKind) result;
-                xk = (JavaKind) x;
-                yk = (JavaKind) y;
-                assert rk == JavaKind.Long && xk == JavaKind.Long && yk == JavaKind.Long;
-                break;
-            case LSHL:
-            case LSHR:
-            case LUSHR:
-                rk = (JavaKind) result;
-                xk = (JavaKind) x;
-                yk = (JavaKind) y;
-                assert rk == JavaKind.Long && xk == JavaKind.Long && (yk == JavaKind.Int || yk == JavaKind.Long);
-                break;
-            case FADD:
-            case FSUB:
-            case FMUL:
-            case FDIV:
-            case FREM:
-                rk = (JavaKind) result;
-                xk = (JavaKind) x;
-                yk = (JavaKind) y;
-                assert (rk == JavaKind.Float || rk == JavaKind.Double) && xk == JavaKind.Float && yk == JavaKind.Float;
-                break;
-            case DAND:
-            case DADD:
-            case DSUB:
-            case DMUL:
-            case DDIV:
-            case DREM:
-                rk = (JavaKind) result;
-                xk = (JavaKind) x;
-                yk = (JavaKind) y;
-                assert rk == JavaKind.Double && xk == JavaKind.Double && yk == JavaKind.Double : "opcode=" + opcode + ", result kind=" + rk + ", x kind=" + xk + ", y kind=" + yk;
-                break;
-            default:
-                throw JVMCIError.shouldNotReachHere("missing: " + opcode);
-        }
-    }
-
     public static final class MulHighOp extends SPARCLIRInstruction {
         public static final LIRInstructionClass<MulHighOp> TYPE = LIRInstructionClass.create(MulHighOp.class);
         public static final SizeEstimate SIZE = SizeEstimate.create(4);
 
-        @Opcode private final SPARCArithmetic opcode;
+        @Opcode private final MulHigh opcode;
         @Def({REG}) public AllocatableValue result;
         @Alive({REG}) public AllocatableValue x;
         @Alive({REG}) public AllocatableValue y;
         @Temp({REG}) public AllocatableValue scratch;
 
-        public MulHighOp(SPARCArithmetic opcode, AllocatableValue x, AllocatableValue y, AllocatableValue result, AllocatableValue scratch) {
+        public enum MulHigh {
+            IMUL,
+            LMUL
+        }
+
+        public MulHighOp(MulHigh opcode, AllocatableValue x, AllocatableValue y, AllocatableValue result, AllocatableValue scratch) {
             super(TYPE, SIZE);
             this.opcode = opcode;
             this.x = x;
@@ -925,30 +323,20 @@
                 case IMUL:
                     masm.sra(asRegister(x), 0, asRegister(x));
                     masm.sra(asRegister(y), 0, asRegister(y));
-                    masm.mulx(asRegister(x, JavaKind.Int), asRegister(y, JavaKind.Int), asRegister(result, JavaKind.Int));
-                    masm.srax(asRegister(result, JavaKind.Int), 32, asRegister(result, JavaKind.Int));
-                    break;
-                case IUMUL:
-                    assert !asRegister(scratch, JavaKind.Int).equals(asRegister(result, JavaKind.Int));
-                    masm.srl(asRegister(x, JavaKind.Int), 0, asRegister(scratch, JavaKind.Int));
-                    masm.srl(asRegister(y, JavaKind.Int), 0, asRegister(result, JavaKind.Int));
-                    masm.mulx(asRegister(result, JavaKind.Int), asRegister(scratch, JavaKind.Int), asRegister(result, JavaKind.Int));
-                    masm.srlx(asRegister(result, JavaKind.Int), 32, asRegister(result, JavaKind.Int));
+                    masm.mulx(asRegister(x, WORD), asRegister(y, WORD), asRegister(result, WORD));
+                    masm.srax(asRegister(result, WORD), 32, asRegister(result, WORD));
                     break;
                 case LMUL:
-                    assert !asRegister(scratch, JavaKind.Long).equals(asRegister(result, JavaKind.Long));
-                    masm.umulxhi(asRegister(x, JavaKind.Long), asRegister(y, JavaKind.Long), asRegister(result, JavaKind.Long));
-
-                    masm.srlx(asRegister(x, JavaKind.Long), 63, asRegister(scratch, JavaKind.Long));
-                    masm.mulx(asRegister(scratch, JavaKind.Long), asRegister(y, JavaKind.Long), asRegister(scratch, JavaKind.Long));
-                    masm.sub(asRegister(result, JavaKind.Long), asRegister(scratch, JavaKind.Long), asRegister(result, JavaKind.Long));
+                    assert !asRegister(scratch, DWORD).equals(asRegister(result, DWORD));
+                    masm.umulxhi(asRegister(x, DWORD), asRegister(y, DWORD), asRegister(result, DWORD));
 
-                    masm.srlx(asRegister(y, JavaKind.Long), 63, asRegister(scratch, JavaKind.Long));
-                    masm.mulx(asRegister(scratch, JavaKind.Long), asRegister(x, JavaKind.Long), asRegister(scratch, JavaKind.Long));
-                    masm.sub(asRegister(result, JavaKind.Long), asRegister(scratch, JavaKind.Long), asRegister(result, JavaKind.Long));
-                    break;
-                case LUMUL:
-                    masm.umulxhi(asRegister(x, JavaKind.Long), asRegister(y, JavaKind.Long), asRegister(result, JavaKind.Long));
+                    masm.srlx(asRegister(x, DWORD), 63, asRegister(scratch, DWORD));
+                    masm.mulx(asRegister(scratch, DWORD), asRegister(y, DWORD), asRegister(scratch, DWORD));
+                    masm.sub(asRegister(result, DWORD), asRegister(scratch, DWORD), asRegister(result, DWORD));
+
+                    masm.srlx(asRegister(y, DWORD), 63, asRegister(scratch, DWORD));
+                    masm.mulx(asRegister(scratch, DWORD), asRegister(x, DWORD), asRegister(scratch, DWORD));
+                    masm.sub(asRegister(result, DWORD), asRegister(scratch, DWORD), asRegister(result, DWORD));
                     break;
                 default:
                     throw JVMCIError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java	Wed Sep 23 15:42:58 2015 +0200
@@ -34,6 +34,7 @@
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.REG;
 import static jdk.internal.jvmci.code.ValueUtil.asRegister;
 import static jdk.internal.jvmci.sparc.SPARC.g0;
+import static jdk.internal.jvmci.sparc.SPARCKind.WORD;
 
 import java.lang.reflect.Array;
 import java.lang.reflect.Field;
@@ -42,6 +43,7 @@
 import jdk.internal.jvmci.meta.JavaKind;
 import jdk.internal.jvmci.meta.LIRKind;
 import jdk.internal.jvmci.meta.Value;
+import jdk.internal.jvmci.sparc.SPARCKind;
 import sun.misc.Unsafe;
 
 import com.oracle.graal.asm.Label;
@@ -113,7 +115,7 @@
         masm.add(asRegister(array2Value), arrayBaseOffset, array2);
 
         // Get array length in bytes.
-        masm.mulx(asRegister(lengthValue, JavaKind.Int), arrayIndexScale, length);
+        masm.mulx(asRegister(lengthValue, WORD), arrayIndexScale, length);
         masm.mov(length, result); // copy
 
         emit8ByteCompare(masm, result, array1, array2, length, trueLabel, falseLabel);
@@ -142,7 +144,7 @@
      * Emits code that uses 8-byte vector compares.
      */
     private void emit8ByteCompare(SPARCMacroAssembler masm, Register result, Register array1, Register array2, Register length, Label trueLabel, Label falseLabel) {
-        assert lengthValue.getPlatformKind().equals(JavaKind.Int);
+        assert lengthValue.getPlatformKind().equals(SPARCKind.WORD);
         Label loop = new Label();
         Label compareTail = new Label();
         Label compareTailCorrectVectorEnd = new Label();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Wed Sep 23 15:42:58 2015 +0200
@@ -22,16 +22,15 @@
  */
 package com.oracle.graal.lir.sparc;
 
-import static com.oracle.graal.asm.sparc.SPARCAssembler.isSimm13;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.REG;
-import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant;
 import static jdk.internal.jvmci.code.ValueUtil.asRegister;
 import static jdk.internal.jvmci.code.ValueUtil.isRegister;
 import static jdk.internal.jvmci.sparc.SPARC.g0;
+import static jdk.internal.jvmci.sparc.SPARCKind.DWORD;
+import static jdk.internal.jvmci.sparc.SPARCKind.WORD;
 import jdk.internal.jvmci.code.Register;
 import jdk.internal.jvmci.common.JVMCIError;
 import jdk.internal.jvmci.meta.AllocatableValue;
-import jdk.internal.jvmci.meta.JavaKind;
 import jdk.internal.jvmci.meta.LIRKind;
 import jdk.internal.jvmci.meta.PlatformKind;
 import jdk.internal.jvmci.meta.Value;
@@ -46,8 +45,6 @@
     public static final LIRInstructionClass<SPARCBitManipulationOp> TYPE = LIRInstructionClass.create(SPARCBitManipulationOp.class);
 
     public enum IntrinsicOpcode {
-        IPOPCNT(SizeEstimate.create(2)),
-        LPOPCNT(SizeEstimate.create(1)),
         IBSR(SizeEstimate.create(13)),
         LBSR(SizeEstimate.create(14)),
         BSF(SizeEstimate.create(4));
@@ -74,26 +71,18 @@
 
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-        Register dst = asRegister(result, JavaKind.Int);
+        Register dst = asRegister(result, WORD);
         if (isRegister(input)) {
             Register src = asRegister(input);
             switch (opcode) {
-                case IPOPCNT:
-                    // clear upper word for 64 bit POPC
-                    masm.srl(src, g0, dst);
-                    masm.popc(dst, dst);
-                    break;
-                case LPOPCNT:
-                    masm.popc(src, dst);
-                    break;
                 case BSF:
                     PlatformKind tkind = input.getPlatformKind();
-                    if (tkind == JavaKind.Int) {
+                    if (tkind == WORD) {
                         masm.sub(src, 1, dst);
                         masm.andn(dst, src, dst);
                         masm.srl(dst, g0, dst);
                         masm.popc(dst, dst);
-                    } else if (tkind == JavaKind.Long) {
+                    } else if (tkind == DWORD) {
                         masm.sub(src, 1, dst);
                         masm.andn(dst, src, dst);
                         masm.popc(dst, dst);
@@ -103,7 +92,7 @@
                     break;
                 case IBSR: {
                     PlatformKind ikind = input.getPlatformKind();
-                    assert ikind == JavaKind.Int;
+                    assert ikind == WORD;
                     Register tmp = asRegister(scratch);
                     assert !tmp.equals(dst);
                     masm.srl(src, 1, tmp);
@@ -123,7 +112,7 @@
                 }
                 case LBSR: {
                     PlatformKind lkind = input.getPlatformKind();
-                    assert lkind == JavaKind.Long;
+                    assert lkind == DWORD;
                     Register tmp = asRegister(scratch);
                     assert !tmp.equals(dst);
                     masm.srlx(src, 1, tmp);
@@ -146,17 +135,6 @@
                     throw JVMCIError.shouldNotReachHere();
 
             }
-        } else if (isJavaConstant(input) && isSimm13(crb.asIntConst(input))) {
-            switch (opcode) {
-                case IPOPCNT:
-                    masm.popc(crb.asIntConst(input), dst);
-                    break;
-                case LPOPCNT:
-                    masm.popc(crb.asIntConst(input), dst);
-                    break;
-                default:
-                    throw JVMCIError.shouldNotReachHere();
-            }
         } else {
             throw JVMCIError.shouldNotReachHere();
         }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Wed Sep 23 15:42:58 2015 +0200
@@ -27,13 +27,15 @@
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.STACK;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.UNINITIALIZED;
 import static jdk.internal.jvmci.code.ValueUtil.asRegister;
+import static jdk.internal.jvmci.sparc.SPARCKind.DWORD;
+import static jdk.internal.jvmci.sparc.SPARCKind.WORD;
 import jdk.internal.jvmci.code.Register;
 import jdk.internal.jvmci.code.StackSlotValue;
 import jdk.internal.jvmci.code.ValueUtil;
 import jdk.internal.jvmci.common.JVMCIError;
-import jdk.internal.jvmci.meta.JavaKind;
 import jdk.internal.jvmci.meta.LIRKind;
 import jdk.internal.jvmci.meta.Value;
+import jdk.internal.jvmci.sparc.SPARCKind;
 
 import com.oracle.graal.asm.sparc.SPARCAddress;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Asi;
@@ -56,8 +58,8 @@
         super(TYPE, SIZE);
         this.result = result;
         this.input = input;
-        this.tmpSlot = tool.getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(JavaKind.Long));
-        this.tempIndex = tool.newVariable(LIRKind.value(JavaKind.Long));
+        this.tmpSlot = tool.getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(DWORD));
+        this.tempIndex = tool.newVariable(LIRKind.value(DWORD));
     }
 
     @Override
@@ -65,17 +67,17 @@
         SPARCAddress addr = (SPARCAddress) crb.asAddress(tmpSlot);
         SPARCMove.emitStore(input, addr, result.getPlatformKind(), SPARCDelayedControlTransfer.DUMMY, null, crb, masm);
         if (addr.getIndex().equals(Register.None)) {
-            Register tempReg = ValueUtil.asRegister(tempIndex, JavaKind.Long);
+            Register tempReg = ValueUtil.asRegister(tempIndex, DWORD);
             new SPARCMacroAssembler.Setx(addr.getDisplacement(), tempReg, false).emit(masm);
             addr = new SPARCAddress(addr.getBase(), tempReg);
         }
         getDelayedControlTransfer().emitControlTransfer(crb, masm);
-        switch ((JavaKind) input.getPlatformKind()) {
-            case Int:
-                masm.lduwa(addr.getBase(), addr.getIndex(), asRegister(result, JavaKind.Int), Asi.ASI_PRIMARY_LITTLE);
+        switch ((SPARCKind) input.getPlatformKind()) {
+            case WORD:
+                masm.lduwa(addr.getBase(), addr.getIndex(), asRegister(result, WORD), Asi.ASI_PRIMARY_LITTLE);
                 break;
-            case Long:
-                masm.ldxa(addr.getBase(), addr.getIndex(), asRegister(result, JavaKind.Long), Asi.ASI_PRIMARY_LITTLE);
+            case DWORD:
+                masm.ldxa(addr.getBase(), addr.getIndex(), asRegister(result, DWORD), Asi.ASI_PRIMARY_LITTLE);
                 break;
             default:
                 throw JVMCIError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Wed Sep 23 15:42:58 2015 +0200
@@ -65,7 +65,10 @@
 import static com.oracle.graal.lir.sparc.SPARCMove.const2reg;
 import static com.oracle.graal.lir.sparc.SPARCOP3Op.emitOp3;
 import static jdk.internal.jvmci.code.ValueUtil.asRegister;
+import static jdk.internal.jvmci.sparc.SPARC.CPU;
 import static jdk.internal.jvmci.sparc.SPARC.g0;
+import static jdk.internal.jvmci.sparc.SPARCKind.DWORD;
+import static jdk.internal.jvmci.sparc.SPARCKind.WORD;
 
 import java.util.ArrayList;
 import java.util.EnumSet;
@@ -78,10 +81,11 @@
 import jdk.internal.jvmci.meta.AllocatableValue;
 import jdk.internal.jvmci.meta.Constant;
 import jdk.internal.jvmci.meta.JavaConstant;
-import jdk.internal.jvmci.meta.JavaKind;
+import jdk.internal.jvmci.meta.PlatformKind;
 import jdk.internal.jvmci.meta.Value;
 import jdk.internal.jvmci.sparc.SPARC;
 import jdk.internal.jvmci.sparc.SPARC.CPUFeature;
+import jdk.internal.jvmci.sparc.SPARCKind;
 
 import com.oracle.graal.asm.Assembler;
 import com.oracle.graal.asm.Assembler.LabelHint;
@@ -90,6 +94,7 @@
 import com.oracle.graal.asm.sparc.SPARCAssembler;
 import com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict;
 import com.oracle.graal.asm.sparc.SPARCAssembler.CC;
+import com.oracle.graal.asm.sparc.SPARCAssembler.CMOV;
 import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.ScratchRegister;
@@ -135,7 +140,7 @@
     public static final class CompareBranchOp extends SPARCBlockEndOp implements SPARCDelayedControlTransfer {
         public static final LIRInstructionClass<CompareBranchOp> TYPE = LIRInstructionClass.create(CompareBranchOp.class);
         public static final SizeEstimate SIZE = SizeEstimate.create(3);
-        static final EnumSet<JavaKind> SUPPORTED_KINDS = EnumSet.of(JavaKind.Long, JavaKind.Int, JavaKind.Short, JavaKind.Char, JavaKind.Byte);
+        static final EnumSet<SPARCKind> SUPPORTED_KINDS = EnumSet.of(DWORD, WORD);
 
         @Use({REG}) protected Value x;
         @Use({REG, CONST}) protected Value y;
@@ -144,13 +149,13 @@
         protected LabelHint trueDestinationHint;
         protected final LabelRef falseDestination;
         protected LabelHint falseDestinationHint;
-        protected final JavaKind kind;
+        protected final SPARCKind kind;
         protected final boolean unorderedIsTrue;
         private boolean emitted = false;
         private int delaySlotPosition = -1;
         private double trueDestinationProbability;
 
-        public CompareBranchOp(Value x, Value y, Condition condition, LabelRef trueDestination, LabelRef falseDestination, JavaKind kind, boolean unorderedIsTrue, double trueDestinationProbability) {
+        public CompareBranchOp(Value x, Value y, Condition condition, LabelRef trueDestination, LabelRef falseDestination, SPARCKind kind, boolean unorderedIsTrue, double trueDestinationProbability) {
             super(TYPE, SIZE);
             this.x = x;
             this.y = y;
@@ -159,8 +164,7 @@
             this.kind = kind;
             this.unorderedIsTrue = unorderedIsTrue;
             this.trueDestinationProbability = trueDestinationProbability;
-            CC conditionCodeReg = CC.forKind(kind);
-            conditionFlag = fromCondition(conditionCodeReg, condition, unorderedIsTrue);
+            conditionFlag = fromCondition(kind.isInteger(), condition, unorderedIsTrue);
         }
 
         @Override
@@ -276,29 +280,16 @@
             return true;
         }
 
-        private static void emitCBCond(SPARCMacroAssembler masm, Value actualX, Value actualY, Label actualTrueTarget, ConditionFlag conditionFlag) {
-            switch ((JavaKind) actualX.getLIRKind().getPlatformKind()) {
-                case Int:
-                    if (isJavaConstant(actualY)) {
-                        JavaConstant c = asJavaConstant(actualY);
-                        int constantY = c.isNull() ? 0 : c.asInt();
-                        CBCOND.emit(masm, conditionFlag, false, asRegister(actualX, JavaKind.Int), constantY, actualTrueTarget);
-                    } else {
-                        CBCOND.emit(masm, conditionFlag, false, asRegister(actualX, JavaKind.Int), asRegister(actualY, JavaKind.Int), actualTrueTarget);
-                    }
-                    break;
-                case Long:
-                    if (isJavaConstant(actualY)) {
-                        JavaConstant c = asJavaConstant(actualY);
-                        assert c.isNull() || NumUtil.is32bit(c.asLong());
-                        int constantY = c.isNull() ? 0 : (int) c.asLong();
-                        CBCOND.emit(masm, conditionFlag, true, asRegister(actualX, JavaKind.Long), constantY, actualTrueTarget);
-                    } else {
-                        CBCOND.emit(masm, conditionFlag, true, asRegister(actualX, JavaKind.Long), asRegister(actualY, JavaKind.Long), actualTrueTarget);
-                    }
-                    break;
-                default:
-                    JVMCIError.shouldNotReachHere();
+        private void emitCBCond(SPARCMacroAssembler masm, Value actualX, Value actualY, Label actualTrueTarget, ConditionFlag cFlag) {
+            PlatformKind xKind = actualX.getPlatformKind();
+            boolean isLong = kind == SPARCKind.DWORD;
+            if (isJavaConstant(actualY)) {
+                JavaConstant c = asJavaConstant(actualY);
+                long constantY = c.isNull() ? 0 : c.asLong();
+                assert NumUtil.isInt(constantY);
+                CBCOND.emit(masm, cFlag, isLong, asRegister(actualX, xKind), (int) constantY, actualTrueTarget);
+            } else {
+                CBCOND.emit(masm, cFlag, isLong, asRegister(actualX, xKind), asRegister(actualY, xKind), actualTrueTarget);
             }
         }
 
@@ -306,13 +297,8 @@
             if (!asm.hasFeature(CPUFeature.CBCOND)) {
                 return false;
             }
-            switch ((JavaKind) x.getPlatformKind()) {
-                case Int:
-                case Long:
-                case Object:
-                    break;
-                default:
-                    return false;
+            if (!((SPARCKind) x.getPlatformKind()).isInteger()) {
+                return false;
             }
             // Do not use short branch, if the y value is a constant and does not fit into simm5 but
             // fits into simm13; this means the code with CBcond would be longer as the code without
@@ -373,10 +359,10 @@
         protected final ConditionFlag conditionFlag;
         protected final LabelRef trueDestination;
         protected final LabelRef falseDestination;
-        protected final JavaKind kind;
+        protected final SPARCKind kind;
         protected final double trueDestinationProbability;
 
-        public BranchOp(ConditionFlag conditionFlag, LabelRef trueDestination, LabelRef falseDestination, JavaKind kind, double trueDestinationProbability) {
+        public BranchOp(ConditionFlag conditionFlag, LabelRef trueDestination, LabelRef falseDestination, SPARCKind kind, double trueDestinationProbability) {
             super(TYPE, SIZE);
             this.trueDestination = trueDestination;
             this.falseDestination = falseDestination;
@@ -391,7 +377,7 @@
         }
     }
 
-    private static boolean emitBranch(CompilationResultBuilder crb, SPARCMacroAssembler masm, JavaKind kind, ConditionFlag conditionFlag, LabelRef trueDestination, LabelRef falseDestination,
+    private static boolean emitBranch(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCKind kind, ConditionFlag conditionFlag, LabelRef trueDestination, LabelRef falseDestination,
                     boolean withDelayedNop, double trueDestinationProbability) {
         Label actualTarget;
         ConditionFlag actualConditionFlag;
@@ -412,10 +398,11 @@
             // We cannot make use of the delay slot when we jump in true-case and false-case
             return false;
         }
-        if (kind == JavaKind.Double || kind == JavaKind.Float) {
+        if (kind.isFloat()) {
             masm.fbpcc(actualConditionFlag, NOT_ANNUL, actualTarget, CC.Fcc0, predictTaken);
         } else {
-            CC cc = kind == JavaKind.Int ? CC.Icc : CC.Xcc;
+            assert kind.isInteger();
+            CC cc = kind.equals(SPARCKind.WORD) ? CC.Icc : CC.Xcc;
             masm.bpcc(actualConditionFlag, NOT_ANNUL, actualTarget, cc, predictTaken);
         }
         if (withDelayedNop) {
@@ -506,29 +493,21 @@
             protected void conditionalJump(int index, Condition condition, Label target) {
                 JavaConstant constant = (JavaConstant) keyConstants[index];
                 CC conditionCode;
-                Long bits;
+                Long bits = constant.asLong();
                 switch (constant.getJavaKind()) {
                     case Char:
                     case Byte:
                     case Short:
                     case Int:
                         conditionCode = CC.Icc;
-                        bits = constant.asLong();
-                        break;
-                    case Long: {
-                        conditionCode = CC.Xcc;
-                        bits = constant.asLong();
                         break;
-                    }
-                    case Object: {
-                        conditionCode = crb.codeCache.getTarget().arch.getWordKind() == JavaKind.Long ? CC.Xcc : CC.Icc;
-                        bits = constant.isDefaultForKind() ? 0L : null;
+                    case Long:
+                        conditionCode = CC.Xcc;
                         break;
-                    }
                     default:
                         throw new JVMCIError("switch only supported for int, long and object");
                 }
-                ConditionFlag conditionFlag = fromCondition(conditionCode, condition, false);
+                ConditionFlag conditionFlag = fromCondition(keyRegister.getRegisterCategory().equals(CPU), condition, false);
                 LabelHint hint = requestHint(masm, target);
                 boolean isShortConstant = isSimm5(constant);
                 int cbCondPosition = masm.position();
@@ -606,8 +585,8 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            Register value = asRegister(index, JavaKind.Int);
-            Register scratchReg = asRegister(scratch, JavaKind.Long);
+            Register value = asRegister(index, SPARCKind.WORD);
+            Register scratchReg = asRegister(scratch, SPARCKind.DWORD);
 
             // Compare index against jump table bounds
             int highKey = lowKey + targets.length - 1;
@@ -673,22 +652,24 @@
 
         private final ConditionFlag condition;
         private final CC cc;
+        private final CMOV cmove;
 
-        public CondMoveOp(Variable result, CC cc, ConditionFlag condition, Value trueValue, Value falseValue) {
+        public CondMoveOp(CMOV cmove, CC cc, ConditionFlag condition, Value trueValue, Value falseValue, Value result) {
             super(TYPE);
             this.result = result;
             this.condition = condition;
             this.trueValue = trueValue;
             this.falseValue = falseValue;
             this.cc = cc;
+            this.cmove = cmove;
         }
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             if (result.equals(trueValue)) { // We have the true value in place, do he opposite
-                cmove(masm, cc, result, condition.negate(), falseValue);
+                cmove(masm, condition.negate(), falseValue);
             } else if (result.equals(falseValue)) {
-                cmove(masm, cc, result, condition, trueValue);
+                cmove(masm, condition, trueValue);
             } else { // We have to move one of the input values to the result
                 ConditionFlag actualCondition = condition;
                 Value actualTrueValue = trueValue;
@@ -699,7 +680,15 @@
                     actualFalseValue = trueValue;
                 }
                 SPARCMove.move(crb, masm, result, actualFalseValue, SPARCDelayedControlTransfer.DUMMY);
-                cmove(masm, cc, result, actualCondition, actualTrueValue);
+                cmove(masm, actualCondition, actualTrueValue);
+            }
+        }
+
+        private void cmove(SPARCMacroAssembler masm, ConditionFlag localCondition, Value value) {
+            if (isConstantValue(value)) {
+                cmove.emit(masm, localCondition, cc, asImmediate(asJavaConstant(value)), asRegister(result));
+            } else {
+                cmove.emit(masm, localCondition, cc, asRegister(value), asRegister(result));
             }
         }
 
@@ -716,97 +705,47 @@
         }
     }
 
-    private static void cmove(SPARCMacroAssembler masm, CC cc, Value result, ConditionFlag cond, Value other) {
-        switch ((JavaKind) other.getPlatformKind()) {
-            case Boolean:
-            case Byte:
-            case Short:
-            case Char:
-            case Int:
-                if (isJavaConstant(other)) {
-                    int constant;
-                    if (asJavaConstant(other).isNull()) {
-                        constant = 0;
-                    } else {
-                        constant = asJavaConstant(other).asInt();
-                    }
-                    masm.movcc(cond, cc, constant, asRegister(result));
-                } else {
-                    masm.movcc(cond, cc, asRegister(other), asRegister(result));
-                }
-                break;
-            case Long:
-            case Object:
-                if (isJavaConstant(other)) {
-                    long constant;
-                    if (asJavaConstant(other).isNull()) {
-                        constant = 0;
-                    } else {
-                        constant = asJavaConstant(other).asLong();
-                    }
-                    masm.movcc(cond, cc, (int) constant, asRegister(result));
-                } else {
-                    masm.movcc(cond, cc, asRegister(other), asRegister(result));
-                }
-                break;
-            case Float:
-                masm.fmovscc(cond, cc, asRegister(other, JavaKind.Float), asRegister(result, JavaKind.Float));
-                break;
-            case Double:
-                masm.fmovdcc(cond, cc, asRegister(other, JavaKind.Double), asRegister(result, JavaKind.Double));
-                break;
-            default:
-                throw JVMCIError.shouldNotReachHere();
+    public static ConditionFlag fromCondition(boolean integer, Condition cond, boolean unorderedIsTrue) {
+        if (integer) {
+            switch (cond) {
+                case EQ:
+                    return Equal;
+                case NE:
+                    return NotEqual;
+                case BT:
+                    return LessUnsigned;
+                case LT:
+                    return Less;
+                case BE:
+                    return LessEqualUnsigned;
+                case LE:
+                    return LessEqual;
+                case AE:
+                    return GreaterEqualUnsigned;
+                case GE:
+                    return GreaterEqual;
+                case AT:
+                    return GreaterUnsigned;
+                case GT:
+                    return Greater;
+            }
+            throw JVMCIError.shouldNotReachHere("Unimplemented for: " + cond);
+        } else {
+            switch (cond) {
+                case EQ:
+                    return unorderedIsTrue ? F_UnorderedOrEqual : F_Equal;
+                case NE:
+                    return ConditionFlag.F_NotEqual;
+                case LT:
+                    return unorderedIsTrue ? F_UnorderedOrLess : F_Less;
+                case LE:
+                    return unorderedIsTrue ? F_UnorderedOrLessOrEqual : F_LessOrEqual;
+                case GE:
+                    return unorderedIsTrue ? F_UnorderedGreaterOrEqual : F_GreaterOrEqual;
+                case GT:
+                    return unorderedIsTrue ? F_UnorderedOrGreater : F_Greater;
+            }
+            throw JVMCIError.shouldNotReachHere("Unkown condition: " + cond);
         }
     }
-
-    public static ConditionFlag fromCondition(CC conditionFlagsRegister, Condition cond, boolean unorderedIsTrue) {
-        switch (conditionFlagsRegister) {
-            case Xcc:
-            case Icc:
-                switch (cond) {
-                    case EQ:
-                        return Equal;
-                    case NE:
-                        return NotEqual;
-                    case BT:
-                        return LessUnsigned;
-                    case LT:
-                        return Less;
-                    case BE:
-                        return LessEqualUnsigned;
-                    case LE:
-                        return LessEqual;
-                    case AE:
-                        return GreaterEqualUnsigned;
-                    case GE:
-                        return GreaterEqual;
-                    case AT:
-                        return GreaterUnsigned;
-                    case GT:
-                        return Greater;
-                }
-                throw JVMCIError.shouldNotReachHere("Unimplemented for: " + cond);
-            case Fcc0:
-            case Fcc1:
-            case Fcc2:
-            case Fcc3:
-                switch (cond) {
-                    case EQ:
-                        return unorderedIsTrue ? F_UnorderedOrEqual : F_Equal;
-                    case NE:
-                        return ConditionFlag.F_NotEqual;
-                    case LT:
-                        return unorderedIsTrue ? F_UnorderedOrLess : F_Less;
-                    case LE:
-                        return unorderedIsTrue ? F_UnorderedOrLessOrEqual : F_LessOrEqual;
-                    case GE:
-                        return unorderedIsTrue ? F_UnorderedGreaterOrEqual : F_GreaterOrEqual;
-                    case GT:
-                        return unorderedIsTrue ? F_UnorderedOrGreater : F_Greater;
-                }
-                throw JVMCIError.shouldNotReachHere("Unkown condition: " + cond);
-        }
-        throw JVMCIError.shouldNotReachHere("Unknown condition flag register " + conditionFlagsRegister);
-    }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFloatCompareOp.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFloatCompareOp.java	Wed Sep 23 15:42:58 2015 +0200
@@ -53,7 +53,7 @@
 
     @Override
     protected void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-        SPARCAssembler.OPF.emitFcmp(masm, opf, cc, asRegister(a), asRegister(b));
+        SPARCAssembler.OpfOp.emitFcmp(masm, opf, cc, asRegister(a), asRegister(b));
     }
 
     @Override
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFrameMap.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFrameMap.java	Wed Sep 23 15:42:58 2015 +0200
@@ -25,9 +25,9 @@
 import jdk.internal.jvmci.code.CodeCacheProvider;
 import jdk.internal.jvmci.code.RegisterConfig;
 import jdk.internal.jvmci.code.StackSlot;
-import jdk.internal.jvmci.meta.JavaKind;
 import jdk.internal.jvmci.meta.LIRKind;
 import jdk.internal.jvmci.sparc.SPARC;
+import jdk.internal.jvmci.sparc.SPARCKind;
 
 import com.oracle.graal.asm.NumUtil;
 import com.oracle.graal.lir.framemap.FrameMap;
@@ -131,6 +131,6 @@
 
     public StackSlot allocateDeoptimizationRescueSlot() {
         assert spillSize == initialSpillSize : "Deoptimization rescue slot must be the first stack slot";
-        return allocateSpillSlot(LIRKind.value(JavaKind.Long));
+        return allocateSpillSlot(LIRKind.value(SPARCKind.DWORD));
     }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java	Wed Sep 23 15:42:58 2015 +0200
@@ -22,6 +22,9 @@
  */
 package com.oracle.graal.lir.sparc;
 
+import jdk.internal.jvmci.meta.JavaConstant;
+
+import com.oracle.graal.asm.NumUtil;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler;
 import com.oracle.graal.lir.LIRInstruction;
 import com.oracle.graal.lir.LIRInstructionClass;
@@ -53,4 +56,14 @@
     public SPARCLIRInstructionMixinStore getSPARCLIRInstructionStore() {
         return store;
     }
+
+    protected static int asImmediate(JavaConstant value) {
+        if (value.isNull()) {
+            return 0;
+        } else {
+            long val = value.asLong();
+            assert NumUtil.isInt(val);
+            return (int) val;
+        }
+    }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java	Mon Sep 21 14:35:30 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2011, 2015, 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.lir.sparc;
-
-import static jdk.internal.jvmci.code.ValueUtil.asRegister;
-import jdk.internal.jvmci.common.JVMCIError;
-import jdk.internal.jvmci.meta.JavaKind;
-import jdk.internal.jvmci.meta.Value;
-
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler;
-import com.oracle.graal.lir.LIRInstructionClass;
-import com.oracle.graal.lir.Opcode;
-import com.oracle.graal.lir.asm.CompilationResultBuilder;
-
-public final class SPARCMathIntrinsicOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
-    public static final LIRInstructionClass<SPARCMathIntrinsicOp> TYPE = LIRInstructionClass.create(SPARCMathIntrinsicOp.class);
-    public static final SizeEstimate SIZE = SizeEstimate.create(1);
-
-    public enum IntrinsicOpcode {
-        SQRT,
-        ABS
-    }
-
-    @Opcode private final IntrinsicOpcode opcode;
-    @Def protected Value result;
-    @Use protected Value input;
-
-    public SPARCMathIntrinsicOp(IntrinsicOpcode opcode, Value result, Value input) {
-        super(TYPE, SIZE);
-        this.opcode = opcode;
-        this.result = result;
-        this.input = input;
-    }
-
-    @Override
-    public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-        JavaKind inputKind = (JavaKind) input.getLIRKind().getPlatformKind();
-        getDelayedControlTransfer().emitControlTransfer(crb, masm);
-        switch (opcode) {
-            case SQRT:
-                switch (inputKind) {
-                    case Float:
-                        masm.fsqrts(asRegister(input, JavaKind.Float), asRegister(result, JavaKind.Float));
-                        break;
-                    case Double:
-                        masm.fsqrtd(asRegister(input, JavaKind.Double), asRegister(result, JavaKind.Double));
-                        break;
-                    default:
-                        JVMCIError.shouldNotReachHere();
-                }
-                break;
-            case ABS:
-                switch (inputKind) {
-                    case Float:
-                        masm.fabss(asRegister(input, JavaKind.Float), asRegister(result, JavaKind.Float));
-                        break;
-                    case Double:
-                        masm.fabsd(asRegister(input, JavaKind.Double), asRegister(result, JavaKind.Double));
-                        break;
-                    default:
-                        JVMCIError.shouldNotReachHere();
-                }
-                break;
-            default:
-                throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-}
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Wed Sep 23 15:42:58 2015 +0200
@@ -37,14 +37,11 @@
 import static jdk.internal.jvmci.code.ValueUtil.asStackSlot;
 import static jdk.internal.jvmci.code.ValueUtil.isRegister;
 import static jdk.internal.jvmci.code.ValueUtil.isStackSlot;
-import static jdk.internal.jvmci.meta.JavaKind.Byte;
-import static jdk.internal.jvmci.meta.JavaKind.Char;
-import static jdk.internal.jvmci.meta.JavaKind.Double;
-import static jdk.internal.jvmci.meta.JavaKind.Float;
-import static jdk.internal.jvmci.meta.JavaKind.Int;
-import static jdk.internal.jvmci.meta.JavaKind.Long;
-import static jdk.internal.jvmci.meta.JavaKind.Short;
 import static jdk.internal.jvmci.sparc.SPARC.g0;
+import static jdk.internal.jvmci.sparc.SPARCKind.DOUBLE;
+import static jdk.internal.jvmci.sparc.SPARCKind.DWORD;
+import static jdk.internal.jvmci.sparc.SPARCKind.SINGLE;
+import static jdk.internal.jvmci.sparc.SPARCKind.WORD;
 
 import java.util.Set;
 
@@ -55,12 +52,12 @@
 import jdk.internal.jvmci.meta.AllocatableValue;
 import jdk.internal.jvmci.meta.Constant;
 import jdk.internal.jvmci.meta.JavaConstant;
-import jdk.internal.jvmci.meta.JavaKind;
 import jdk.internal.jvmci.meta.LIRKind;
 import jdk.internal.jvmci.meta.PlatformKind;
 import jdk.internal.jvmci.meta.Value;
 import jdk.internal.jvmci.sparc.SPARC;
 import jdk.internal.jvmci.sparc.SPARC.CPUFeature;
+import jdk.internal.jvmci.sparc.SPARCKind;
 
 import com.oracle.graal.asm.sparc.SPARCAddress;
 import com.oracle.graal.asm.sparc.SPARCAssembler;
@@ -204,8 +201,8 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            JavaKind inputKind = (JavaKind) input.getPlatformKind();
-            JavaKind resultKind = (JavaKind) result.getPlatformKind();
+            SPARCKind inputKind = (SPARCKind) input.getPlatformKind();
+            SPARCKind resultKind = (SPARCKind) result.getPlatformKind();
             if (AllocatableValue.ILLEGAL.equals(temp)) {
                 moveDirect(crb, masm, inputKind, resultKind);
             } else {
@@ -213,36 +210,36 @@
             }
         }
 
-        private void moveDirect(CompilationResultBuilder crb, SPARCMacroAssembler masm, JavaKind inputKind, JavaKind resultKind) {
+        private void moveDirect(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCKind inputKind, SPARCKind resultKind) {
             getDelayedControlTransfer().emitControlTransfer(crb, masm);
-            if (resultKind == Float) {
-                if (inputKind == Int || inputKind == Short || inputKind == Char || inputKind == Byte) {
-                    masm.movwtos(asRegister(input, JavaKind.Int), asRegister(result, JavaKind.Float));
+            if (resultKind == SINGLE) {
+                if (inputKind == WORD) {
+                    masm.movwtos(asRegister(input, WORD), asRegister(result, SINGLE));
                 } else {
-                    throw JVMCIError.shouldNotReachHere();
+                    throw JVMCIError.shouldNotReachHere("inputKind: " + inputKind);
                 }
-            } else if (resultKind == Double) {
-                if (inputKind == Int || inputKind == Short || inputKind == Char || inputKind == Byte) {
-                    masm.movxtod(asRegister(input, JavaKind.Int), asRegister(result, JavaKind.Double));
+            } else if (resultKind == DOUBLE) {
+                if (inputKind == WORD) {
+                    masm.movxtod(asRegister(input, WORD), asRegister(result, DOUBLE));
                 } else {
-                    masm.movxtod(asRegister(input, JavaKind.Long), asRegister(result, JavaKind.Double));
+                    masm.movxtod(asRegister(input, DWORD), asRegister(result, DOUBLE));
                 }
-            } else if (inputKind == Float) {
-                if (resultKind == Int || resultKind == Short || resultKind == Byte) {
-                    masm.movstosw(asRegister(input, JavaKind.Float), asRegister(result, JavaKind.Int));
+            } else if (inputKind == SINGLE) {
+                if (resultKind == WORD) {
+                    masm.movstosw(asRegister(input, SINGLE), asRegister(result, WORD));
                 } else {
-                    masm.movstouw(asRegister(input, JavaKind.Float), asRegister(result, JavaKind.Int));
+                    masm.movstouw(asRegister(input, SINGLE), asRegister(result, WORD));
                 }
-            } else if (inputKind == Double) {
-                if (resultKind == Long) {
-                    masm.movdtox(asRegister(input, JavaKind.Double), asRegister(result, JavaKind.Long));
+            } else if (inputKind == DOUBLE) {
+                if (resultKind == DWORD) {
+                    masm.movdtox(asRegister(input, DOUBLE), asRegister(result, DWORD));
                 } else {
                     throw JVMCIError.shouldNotReachHere();
                 }
             }
         }
 
-        private void moveViaStack(CompilationResultBuilder crb, SPARCMacroAssembler masm, JavaKind inputKind, JavaKind resultKind) {
+        private void moveViaStack(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCKind inputKind, SPARCKind resultKind) {
             int resultKindSize = resultKind.getSizeInBytes();
             assert inputKind.getSizeInBytes() == resultKindSize;
             try (ScratchRegister sc = masm.getScratchRegister()) {
@@ -324,7 +321,7 @@
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             SPARCAddress address = addressValue.toAddress();
-            loadEffectiveAddress(crb, masm, address, asRegister(result, JavaKind.Long), getDelayedControlTransfer());
+            loadEffectiveAddress(crb, masm, address, asRegister(result, DWORD), getDelayedControlTransfer());
         }
     }
 
@@ -451,7 +448,7 @@
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             SPARCAddress address = (SPARCAddress) crb.asAddress(slot);
-            loadEffectiveAddress(crb, masm, address, asRegister(result, JavaKind.Long), getDelayedControlTransfer());
+            loadEffectiveAddress(crb, masm, address, asRegister(result, DWORD), getDelayedControlTransfer());
         }
     }
 
@@ -715,12 +712,11 @@
     protected static void compareAndSwap(CompilationResultBuilder crb, SPARCMacroAssembler masm, AllocatableValue address, AllocatableValue cmpValue, AllocatableValue newValue,
                     SPARCDelayedControlTransfer delay) {
         delay.emitControlTransfer(crb, masm);
-        switch ((JavaKind) cmpValue.getPlatformKind()) {
-            case Int:
+        switch ((SPARCKind) cmpValue.getPlatformKind()) {
+            case WORD:
                 masm.cas(asRegister(address), asRegister(cmpValue), asRegister(newValue));
                 break;
-            case Long:
-            case Object:
+            case DWORD:
                 masm.casx(asRegister(address), asRegister(cmpValue), asRegister(newValue));
                 break;
             default:
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCOP3Op.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCOP3Op.java	Wed Sep 23 15:42:58 2015 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.lir.sparc;
 
-import static com.oracle.graal.asm.sparc.SPARCAssembler.OP3;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.isSimm13;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.CONST;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.REG;
@@ -33,60 +32,85 @@
 import static jdk.internal.jvmci.common.JVMCIError.shouldNotReachHere;
 import static jdk.internal.jvmci.sparc.SPARC.g0;
 import jdk.internal.jvmci.meta.JavaConstant;
+import jdk.internal.jvmci.meta.LIRKind;
 import jdk.internal.jvmci.meta.Value;
 
+import com.oracle.graal.asm.sparc.SPARCAssembler;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Op3s;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler;
+import com.oracle.graal.lir.LIRFrameState;
 import com.oracle.graal.lir.LIRInstructionClass;
 import com.oracle.graal.lir.Opcode;
 import com.oracle.graal.lir.asm.CompilationResultBuilder;
 
-public class SPARCOP3Op extends SPARCLIRInstruction {
+public final class SPARCOP3Op extends SPARCLIRInstruction {
     public static final LIRInstructionClass<SPARCOP3Op> TYPE = LIRInstructionClass.create(SPARCOP3Op.class);
     public static final SizeEstimate SIZE = SizeEstimate.create(1);
 
     @Opcode private final Op3s op3;
-    @Use({REG}) protected Value a;
-    @Use({REG, CONST}) protected Value b;
-    @Use({REG}) protected Value result;
+    @Use({REG}) protected Value rs1;
+    @Use({REG, CONST}) protected Value rs2;
+    @Def({REG}) protected Value rd;
+    @State protected LIRFrameState state;
 
-    public SPARCOP3Op(Op3s op3, Value a, Value b) {
-        this(op3, a, b, g0.asValue());
+    public static SPARCOP3Op newUnary(Op3s op3, Value rs2, Value rd) {
+        return newUnary(op3, rs2, rd, null);
+    }
+
+    public static SPARCOP3Op newUnary(Op3s op3, Value rs2, Value rd, LIRFrameState state) {
+        return new SPARCOP3Op(op3, g0.asValue(LIRKind.value(rs2.getPlatformKind())), rs2, rd, state);
     }
 
-    public SPARCOP3Op(Op3s op3, Value a, Value b, Value result) {
+    public static SPARCOP3Op newBinaryVoid(Op3s op3, Value rs1, Value rs2) {
+        return newBinaryVoid(op3, rs1, rs2, null);
+    }
+
+    public static SPARCOP3Op newBinaryVoid(Op3s op3, Value rs1, Value rs2, LIRFrameState state) {
+        return new SPARCOP3Op(op3, rs1, rs2, g0.asValue(LIRKind.value(rs2.getPlatformKind())), state);
+    }
+
+    public SPARCOP3Op(Op3s op3, Value rs1, Value rs2, Value rd) {
+        this(op3, rs1, rs2, rd, null);
+    }
+
+    public SPARCOP3Op(Op3s op3, Value rs1, Value rs2, Value rd, LIRFrameState state) {
         super(TYPE, SIZE);
         this.op3 = op3;
-        this.a = a;
-        this.b = b;
-        this.result = result;
+        this.rs1 = rs1;
+        this.rs2 = rs2;
+        this.rd = rd;
+        this.state = state;
     }
 
     @Override
     protected void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-        emitOp3(masm, op3, a, b, result);
+        if (state != null) {
+            crb.recordImplicitException(masm.position(), state);
+        }
+        emitOp3(masm, op3, rs1, rs2, rd);
     }
 
-    public static void emitOp3(SPARCMacroAssembler masm, Op3s op3, Value a, Value b) {
-        emitOp3(masm, op3, a, b, g0.asValue());
+    public static void emitOp3(SPARCMacroAssembler masm, Op3s op3, Value rs1, Value rs2) {
+        emitOp3(masm, op3, rs1, rs2, g0.asValue(LIRKind.value(rs2.getPlatformKind())));
     }
 
-    public static void emitOp3(SPARCMacroAssembler masm, Op3s op3, Value a, Value b, Value result) {
-        assert isRegister(a);
-        if (isJavaConstant(b)) {
-            JavaConstant constant = asJavaConstant(b);
+    public static void emitOp3(SPARCMacroAssembler masm, Op3s op3, Value rs1, Value rs2, Value rd) {
+        assert isRegister(rs1) : rs1;
+        if (isJavaConstant(rs2)) {
+            JavaConstant constant = asJavaConstant(rs2);
             long simm13;
             if (constant.isNull()) {
                 simm13 = 0;
             } else {
-                simm13 = constant.asLong(); // Cast is safe, as isSimm13 assertion is done
+                // Cast is safe, as isSimm13 assertion is done
+                simm13 = constant.asLong();
             }
             assert isSimm13(constant);
-            OP3.emit(masm, op3, asRegister(a), (int) simm13, asRegister(result));
-        } else if (isRegister(b)) {
-            OP3.emit(masm, op3, asRegister(a), asRegister(b), asRegister(result));
+            SPARCAssembler.Op3Op.emit(masm, op3, asRegister(rs1), (int) simm13, asRegister(rd));
+        } else if (isRegister(rs2)) {
+            SPARCAssembler.Op3Op.emit(masm, op3, asRegister(rs1), asRegister(rs2), asRegister(rd));
         } else {
-            throw shouldNotReachHere(String.format("Got values a: %s b: %s", a, b));
+            throw shouldNotReachHere(String.format("Got values a: %s b: %s", rs1, rs2));
         }
     }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCOPFOp.java	Mon Sep 21 14:35:30 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCOPFOp.java	Wed Sep 23 15:42:58 2015 +0200
@@ -24,34 +24,51 @@
 
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.REG;
 import static jdk.internal.jvmci.code.ValueUtil.asRegister;
+import jdk.internal.jvmci.meta.LIRKind;
 import jdk.internal.jvmci.meta.Value;
+import jdk.internal.jvmci.sparc.SPARC;
+import jdk.internal.jvmci.sparc.SPARCKind;
 
 import com.oracle.graal.asm.sparc.SPARCAssembler;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Opfs;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler;
+import com.oracle.graal.lir.LIRFrameState;
 import com.oracle.graal.lir.LIRInstructionClass;
 import com.oracle.graal.lir.Opcode;
 import com.oracle.graal.lir.asm.CompilationResultBuilder;
 
-public class SPARCOPFOp extends SPARCLIRInstruction {
+public final class SPARCOPFOp extends SPARCLIRInstruction {
     public static final LIRInstructionClass<SPARCOPFOp> TYPE = LIRInstructionClass.create(SPARCOPFOp.class);
     public static final SizeEstimate SIZE = SizeEstimate.create(1);
 
     @Opcode protected final Opfs opf;
-    @Use({REG}) protected Value a;
-    @Use({REG}) protected Value b;
-    @Use({REG}) protected Value result;
+    @Use({REG}) protected Value rs1;
+    @Use({REG}) protected Value rs2;
+    @Def({REG}) protected Value rd;
+    @State protected LIRFrameState state;
 
-    public SPARCOPFOp(Opfs opf, Value a, Value b, Value result) {
+    public SPARCOPFOp(Opfs opf, Value rs2, Value rd) {
+        this(opf, SPARC.g0.asValue(LIRKind.value(SPARCKind.SINGLE)), rs2, rd);
+    }
+
+    public SPARCOPFOp(Opfs opf, Value rs1, Value rs2, Value rd) {
+        this(opf, rs1, rs2, rd, null);
+    }
+
+    public SPARCOPFOp(Opfs opf, Value rs1, Value rs2, Value rd, LIRFrameState state) {
         super(TYPE, SIZE);
         this.opf = opf;
-        this.a = a;
-        this.b = b;
-        this.result = result;
+        this.rs1 = rs1;
+        this.rs2 = rs2;
+        this.rd = rd;
+        this.state = state;
     }
 
     @Override
     protected void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-        SPARCAssembler.OPF.emit(masm, opf, asRegister(a), asRegister(b), asRegister(result));
+        if (state != null) {
+            crb.recordImplicitException(masm.position(), state);
+        }
+        SPARCAssembler.OpfOp.emit(masm, opf, asRegister(rs1), asRegister(rs2), asRegister(rd));
     }
 }