changeset 9831:705aca4ebf2f

SPARC array, load / store and compare operations
author Morris Meyer <morris.meyer@oracle.com>
date Tue, 28 May 2013 09:04:22 -0400
parents 98918f518640
children 1c4bef4568a8
files graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/ArraySPARCTest.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.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/SPARCCompare.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/SPARCMove.java make/build-graal.xml mx/projects
diffstat 12 files changed, 844 insertions(+), 217 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java	Tue May 28 10:59:01 2013 +0200
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java	Tue May 28 09:04:22 2013 -0400
@@ -28,8 +28,7 @@
 public class SPARCAddress extends AbstractAddress {
 
     private final Register base;
-    private final Register index;
-    private final int displacement;
+    private final int displacement; // need Register offset / displacement CompositeValue?
 
     /**
      * Creates an {@link SPARCAddress} with given base register, no scaling and a given
@@ -41,35 +40,16 @@
     public SPARCAddress(Register base, int displacement) {
         this.base = base;
         this.displacement = displacement;
-        this.index = null;
-    }
-
-    /**
-     * Creates an {@link SPARCAddress} with given base and index registers, scaling and
-     * displacement. This is the most general constructor.
-     * 
-     * @param base the base register
-     * @param index the index register
-     */
-    public SPARCAddress(Register base, Register index, int disp) {
-        this.base = base;
-        this.index = index;
-        this.displacement = disp;
     }
 
     @Override
     public String toString() {
         StringBuilder s = new StringBuilder();
         s.append("[");
-        String sep = "";
         if (!getBase().equals(Register.None)) {
             s.append(getBase());
-            sep = " + ";
         }
-        if (!getIndex().equals(Register.None)) {
-            s.append(sep).append(getIndex()).append(" * ");
-            sep = " + ";
-        }
+        // later: displacement CompositeValue?
         s.append("]");
         return s.toString();
     }
@@ -83,14 +63,6 @@
     }
 
     /**
-     * @return Index register, the value of which is added to {@link #getBase}. If not present, is
-     *         denoted by {@link Register#None}.
-     */
-    public Register getIndex() {
-        return index;
-    }
-
-    /**
      * @return Optional additive displacement.
      */
     public int getDisplacement() {
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Tue May 28 10:59:01 2013 +0200
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Tue May 28 09:04:22 2013 -0400
@@ -28,6 +28,7 @@
 import com.oracle.graal.api.meta.Kind;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.hotspot.HotSpotGraalRuntime;
+import com.oracle.graal.sparc.SPARC;
 
 /**
  * This class implements an assembler that can encode most SPARC instructions.
@@ -328,6 +329,20 @@
         Done(0x3e, "done"),
         Retry(0x3e, "retry"),
 
+        Lduw(0x00, "lduw"),
+        Ldub(0x01, "ldub"),
+        Lduh(0x02, "lduh"),
+        Ldd(0x03, "ldd"),
+        Stw(0x04, "stw"),
+        Stb(0x05, "stb"),
+        Sth(0x06, "sth"),
+        Std(0x07, "std"),
+        Ldsw(0x08, "ldsw"),
+        Ldsb(0x09, "ldsb"),
+        Ldsh(0x0A, "ldsh"),
+        Ldx(0x0b, "ldx"),
+        Stx(0x0e, "stx"),
+
         Ldf(0x20, "ldf"),
         Ldfsr(0x21, "ldfsr"),
         Ldaf(0x22, "ldaf"),
@@ -567,6 +582,21 @@
         return x & ((1 << nbits) - 1);
     }
 
+    private static final int max13 = ((1 << 12) - 1);
+    private static final int min13 = -(1 << 12);
+
+    public static boolean isSimm13(int src) {
+        return min13 <= src && src <= max13;
+    }
+
+    public static final int hi22(int x) {
+        return x >> 10;
+    }
+
+    public static final int lo10(int x) {
+        return x & ((1 << 10) - 1);
+    }
+
     private static int fcn(int val) {
         assert val < 0x20;
         return (val << 25);
@@ -805,14 +835,55 @@
         new Bpa(this, l);
     }
 
+    public static class Lddf extends Fmt3b {
+        public Lddf(SPARCAssembler masm, SPARCAddress src, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Lddf.getValue(),
+                  src.getBase().encoding(), src.getDisplacement(), dst.encoding());
+        }
+    }
 
-    public static class Ld extends Fmt3b {
-        public Ld(SPARCAssembler masm, SPARCAddress src, Register dst) {
+    public static class Ldf extends Fmt3b {
+        public Ldf(SPARCAssembler masm, SPARCAddress src, Register dst) {
             super(masm, Ops.ArithOp.getValue(), Op3s.Ldf.getValue(),
                   src.getBase().encoding(), src.getDisplacement(), dst.encoding());
         }
     }
 
+    public static class Ldsb extends Fmt3b {
+        public Ldsb(SPARCAssembler masm, SPARCAddress src, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Ldsb.getValue(),
+                  src.getBase().encoding(), src.getDisplacement(), dst.encoding());
+        }
+    }
+
+    public static class Ldsh extends Fmt3b {
+        public Ldsh(SPARCAssembler masm, SPARCAddress src, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Ldsh.getValue(),
+                  src.getBase().encoding(), src.getDisplacement(), dst.encoding());
+        }
+    }
+
+    public static class Ldsw extends Fmt3b {
+        public Ldsw(SPARCAssembler masm, SPARCAddress src, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Ldsw.getValue(),
+                  src.getBase().encoding(), src.getDisplacement(), dst.encoding());
+        }
+    }
+
+    public static class Lduw extends Fmt3b {
+        public Lduw(SPARCAssembler masm, SPARCAddress src, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Lduw.getValue(),
+                  src.getBase().encoding(), src.getDisplacement(), dst.encoding());
+        }
+    }
+
+    public static class Ldx extends Fmt3b {
+        public Ldx(SPARCAssembler masm, SPARCAddress src, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Ldx.getValue(),
+                  src.getBase().encoding(), src.getDisplacement(), dst.encoding());
+        }
+    }
+
     public static class Membar extends Fmt3b {
         public Membar(SPARCAssembler masm, MembarMask mask) {
             super(masm, Ops.ArithOp.getValue(), 0, Op3s.Membar.getValue(), 0xf, mask.getValue());
@@ -862,6 +933,13 @@
         }
     }
 
+    public static class NullCheck extends Fmt3b {
+        public NullCheck(SPARCAssembler masm, SPARCAddress src) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Ldx.getValue(),
+                            src.getBase().encoding(), src.getDisplacement(), SPARC.r0.encoding());
+        }
+    }
+
     public static class Or extends Fmt3b {
         public Or(SPARCAssembler masm, Register src1, int simm13, Register dst) {
             super(masm, Ops.ArithOp.getValue(), Op3s.Or.getValue(), src1.encoding(), simm13, dst.encoding());
@@ -996,6 +1074,68 @@
         }
     }
 
+    public static class Sethi extends Fmt2a {
+        public Sethi(SPARCAssembler masm, int simm22, Register dst) {
+            super(masm, Ops.BranchOp.getValue(), Op2s.Sethi.getValue(), simm22, dst.encoding());
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Setuw {
+        public Setuw(SPARCAssembler masm, int value, Register dst) {
+            if (value >= 0 && ((value & 0x3FFF) == 0)) {
+                new Sethi(masm, hi22(value), dst);
+            } else if (-4095 <= value && value <= 4096) {
+                // or   g0, value, dst
+                new Or(masm, SPARC.r0, value, dst);
+            } else {
+                new Sethi(masm, hi22(value), dst);
+                new Or(masm, dst, lo10(value), dst);
+            }
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Setx {
+        public Setx(SPARCAssembler masm, long value, Register tmp, Register dst) {
+            int hi = (int) (value >> 32);
+            int lo = (int) (value & ~0);
+
+            if (isSimm13(lo) && value == lo) {
+                new Or(masm, SPARC.r0, lo, dst);
+            } else if (hi == 0) {
+                new Sethi(masm, lo, dst);   // hardware version zero-extends to upper 32
+                if (lo10(lo) != 0) {
+                    new Or(masm, dst, lo10(lo), dst);
+                }
+            } else if (hi == -1) {
+                new Sethi(masm, ~lo, dst);  // hardware version zero-extends to upper 32
+                new Xor(masm, dst, lo10(lo) ^ ~lo10(~0), dst);
+            } else if (lo == 0) {
+                if (isSimm13(hi)) {
+                    new Or(masm, SPARC.r0, hi, dst);
+                } else {
+                    new Sethi(masm, hi, dst);   // hardware version zero-extends to upper 32
+                    if (lo10(hi) != 0) {
+                        new Or(masm, dst, lo10(hi), dst);
+                    }
+                }
+                new Sllx(masm, dst, 32, dst);
+            }  else {
+                new Sethi(masm, hi, tmp);
+                new Sethi(masm, lo, dst); // macro assembler version sign-extends
+                if (lo10(hi) != 0) {
+                    new Or(masm, tmp, lo10(hi), tmp);
+                }
+                if (lo10(lo) != 0) {
+                    new Or(masm, dst, lo10(lo), dst);
+                }
+                new Sllx(masm, tmp, 32, tmp);
+                new Or(masm, dst, tmp, dst);
+              }
+        }
+    }
+
     public final void sir(int simm13a) {
         emitInt(Ops.ArithOp.getValue() | Op3s.Sir.getValue() | ImmedTrue | simm(simm13a, 13));
     }
@@ -1078,6 +1218,34 @@
         emitInt(Ops.ArithOp.getValue() | Op3s.Membar.getValue() | 0x0003C000);
     }
 
+    public static class Stb extends Fmt3b {
+        public Stb(SPARCAssembler masm, SPARCAddress src, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Stb.getValue(),
+                  src.getBase().encoding(), src.getDisplacement(), dst.encoding());
+        }
+    }
+
+    public static class Sth extends Fmt3b {
+        public Sth(SPARCAssembler masm, SPARCAddress src, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Sth.getValue(),
+                  src.getBase().encoding(), src.getDisplacement(), dst.encoding());
+        }
+    }
+
+    public static class Stw extends Fmt3b {
+        public Stw(SPARCAssembler masm, SPARCAddress src, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Stw.getValue(),
+                  src.getBase().encoding(), src.getDisplacement(), dst.encoding());
+        }
+    }
+
+    public static class Stx extends Fmt3b {
+        public Stx(SPARCAssembler masm, SPARCAddress src, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Stx.getValue(),
+                  src.getBase().encoding(), src.getDisplacement(), dst.encoding());
+        }
+    }
+
     public static class Sub extends Fmt3b {
         public Sub(SPARCAssembler masm, Register src1, int simm13, Register dst) {
             super(masm, Ops.ArithOp.getValue(), Op3s.Sub.getValue(), src1.encoding(), simm13, dst.encoding());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/ArraySPARCTest.java	Tue May 28 09:04:22 2013 -0400
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.compiler.sparc.test;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+public class ArraySPARCTest extends SPARCTestBase {
+
+    @Test
+    public void testArray() {
+        compile("testArray1I");
+        compile("testArray1J");
+        compile("testArray1B");
+        compile("testArray1S");
+        compile("testArray1C");
+        compile("testArray1F");
+        compile("testArray1D");
+        compile("testArray1L");
+        compile("testStoreArray1I");
+        compile("testStoreArray1J");
+        compile("testStoreArray1B");
+        compile("testStoreArray1S");
+        compile("testStoreArray1F");
+        compile("testStoreArray1D");
+    }
+
+    public static int testArray1I(int[] array, int i) {
+        return array[i];
+    }
+
+    public static long testArray1J(long[] array, int i) {
+        return array[i];
+    }
+
+    public static byte testArray1B(byte[] array, int i) {
+        return array[i];
+    }
+
+    public static short testArray1S(short[] array, int i) {
+        return array[i];
+    }
+
+    public static char testArray1C(char[] array, int i) {
+        return array[i];
+    }
+
+    public static float testArray1F(float[] array, int i) {
+        return array[i];
+    }
+
+    public static double testArray1D(double[] array, int i) {
+        return array[i];
+    }
+
+    public static Object testArray1L(Object[] array, int i) {
+        return array[i];
+    }
+
+    public static void testStoreArray1I(int[] array, int i, int val) {
+        array[i] = val;
+    }
+
+    public static void testStoreArray1B(byte[] array, int i, byte val) {
+        array[i] = val;
+    }
+
+    public static void testStoreArray1S(short[] array, int i, short val) {
+        array[i] = val;
+    }
+
+    public static void testStoreArray1J(long[] array, int i, long val) {
+        array[i] = val;
+    }
+
+    public static void testStoreArray1F(float[] array, int i, float val) {
+        array[i] = val;
+    }
+
+    public static void testStoreArray1D(double[] array, int i, double val) {
+        array[i] = val;
+    }
+
+    public static void main(String[] args) {
+        ArraySPARCTest test = new ArraySPARCTest();
+        for (Method m : ArraySPARCTest.class.getMethods()) {
+            String name = m.getName();
+            if (m.getAnnotation(Test.class) == null && name.startsWith("test")) {
+                // CheckStyle: stop system..print check
+                System.out.println(name + ": \n" + new String(test.compile(name).getTargetCode()));
+                // CheckStyle: resume system..print check
+            }
+        }
+    }
+}
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue May 28 10:59:01 2013 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue May 28 09:04:22 2013 -0400
@@ -25,6 +25,7 @@
 
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.sparc.SPARCArithmetic.*;
+import static com.oracle.graal.lir.sparc.SPARCCompare.*;
 
 import com.oracle.graal.api.code.CallingConvention;
 import com.oracle.graal.api.code.CodeCacheProvider;
@@ -54,6 +55,8 @@
 import com.oracle.graal.lir.sparc.SPARCArithmetic.ShiftOp;
 import com.oracle.graal.lir.sparc.SPARCArithmetic.Unary1Op;
 import com.oracle.graal.lir.sparc.SPARCArithmetic.Unary2Op;
+import com.oracle.graal.lir.sparc.SPARCCompare.CompareOp;
+import com.oracle.graal.lir.sparc.SPARCControlFlow.BranchOp;
 import com.oracle.graal.lir.sparc.SPARCControlFlow.ReturnOp;
 import com.oracle.graal.lir.sparc.SPARCControlFlow.SequentialSwitchOp;
 import com.oracle.graal.lir.sparc.SPARCControlFlow.TableSwitchOp;
@@ -135,6 +138,26 @@
     @Override
     public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label) {
         switch (left.getKind().getStackKind()) {
+            case Int:
+                append(new CompareOp(ICMP, cond, left, right));
+                append(new BranchOp(cond, label));
+                break;
+            case Long:
+                append(new CompareOp(LCMP, cond, left, right));
+                append(new BranchOp(cond, label));
+                break;
+            case Float:
+                append(new CompareOp(FCMP, cond, left, right));
+                append(new BranchOp(cond, label));
+                break;
+            case Double:
+                append(new CompareOp(DCMP, cond, left, right));
+                append(new BranchOp(cond, label));
+                break;
+            case Object:
+                append(new CompareOp(ACMP, cond, left, right));
+                append(new BranchOp(cond, label));
+                break;
             default:
                 throw GraalInternalError.shouldNotReachHere("" + left.getKind());
         }
@@ -648,7 +671,7 @@
 
     @Override
     public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) {
-        throw new InternalError("NYI");
+        append(new ReturnOp(Value.ILLEGAL));
     }
 
     @Override
@@ -673,7 +696,8 @@
 
     @Override
     public void emitNullCheck(ValueNode v, DeoptimizingNode deopting) {
-        throw new InternalError("NYI");
+        assert v.kind() == Kind.Object;
+        append(new SPARCMove.NullCheckOp(load(operand(v)), state(deopting)));
     }
 
     @Override
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Tue May 28 10:59:01 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Tue May 28 09:04:22 2013 -0400
@@ -259,7 +259,6 @@
     }
 
     public void append(LIRInstruction op) {
-        assert LIRVerifier.verify(op);
         if (GraalOptions.PrintIRWithLIR && !TTY.isSuppressed()) {
             if (currentInstruction != null && lastInstructionPrinted != currentInstruction) {
                 lastInstructionPrinted = currentInstruction;
@@ -269,6 +268,7 @@
             TTY.println(op.toStringWithIdPrefix());
             TTY.println();
         }
+        assert LIRVerifier.verify(op);
         lir.lir(currentBlock).add(op);
     }
 
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java	Tue May 28 10:59:01 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java	Tue May 28 09:04:22 2013 -0400
@@ -36,8 +36,6 @@
 
     @Component({ REG, OperandFlag.ILLEGAL })
     protected AllocatableValue base;
-    @Component({ REG, OperandFlag.ILLEGAL })
-    protected AllocatableValue index;
     protected final int displacement;
 
     public SPARCAddressValue(PlatformKind kind, AllocatableValue baseRegister,
@@ -57,8 +55,7 @@
     }
 
     public SPARCAddress toAddress() {
-        return new SPARCAddress(toRegister(base), toRegister(index),
-                displacement);
+        return new SPARCAddress(toRegister(base), displacement);
     }
 
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Tue May 28 10:59:01 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Tue May 28 09:04:22 2013 -0400
@@ -47,6 +47,7 @@
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Sra;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Sub;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Xor;
+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.HINT;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.REG;
@@ -60,7 +61,7 @@
 
 //@formatter:off
 public enum SPARCArithmetic {
-    //@formatter:off
+    // @formatter:off
     IADD, ISUB, IMUL, IDIV, IDIVREM, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR,
     LADD, LSUB, LMUL, LDIV, LDIVREM, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR,
     FADD, FSUB, FMUL, FDIV, FREM, FAND, FOR, FXOR,
@@ -255,14 +256,13 @@
         if (isConstant(src1)) {
             switch (opcode) {
             case ISUB:
-                assert is_simm13(tasm.asIntConst(src1));
-                new Add(masm, asIntReg(src2), -(tasm.asIntConst(src1)),
-                        asIntReg(dst));
+                assert isSimm13(tasm.asIntConst(src1));
+                new Add(masm, asIntReg(src2), -(tasm.asIntConst(src1)), asIntReg(dst));
                 break;
             case IAND:
                 throw new InternalError("NYI");
             case IDIV:
-                assert is_simm13(tasm.asIntConst(src1));
+                assert isSimm13(tasm.asIntConst(src1));
                 throw new InternalError("NYI");
                 // new Sdivx(masm, asIntReg(src1), asIntReg(src2),
                 // asIntReg(dst));
@@ -280,49 +280,40 @@
         } else if (isConstant(src2)) {
             switch (opcode) {
             case IADD:
-                assert is_simm13(tasm.asIntConst(src2));
-                new Add(masm, asIntReg(src1), tasm.asIntConst(src2),
-                        asIntReg(dst));
+                assert isSimm13(tasm.asIntConst(src2));
+                new Add(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
                 break;
             case ISUB:
-                assert is_simm13(tasm.asIntConst(src2));
-                new Sub(masm, asIntReg(src1), tasm.asIntConst(src2),
-                        asIntReg(dst));
+                assert isSimm13(tasm.asIntConst(src2));
+                new Sub(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
                 break;
             case IMUL:
-                assert is_simm13(tasm.asIntConst(src2));
-                new Mulx(masm, asIntReg(src1), tasm.asIntConst(src2),
-                        asIntReg(dst));
+                assert isSimm13(tasm.asIntConst(src2));
+                new Mulx(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
                 break;
             case IAND:
-                assert is_simm13(tasm.asIntConst(src2));
-                new And(masm, asIntReg(src1), tasm.asIntConst(src2),
-                        asIntReg(dst));
+                assert isSimm13(tasm.asIntConst(src2));
+                new And(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
                 break;
             case ISHL:
-                assert is_simm13(tasm.asIntConst(src2));
-                new Sll(masm, asIntReg(src1), tasm.asIntConst(src2),
-                        asIntReg(dst));
+                assert isSimm13(tasm.asIntConst(src2));
+                new Sll(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
                 break;
             case ISHR:
-                assert is_simm13(tasm.asIntConst(src2));
-                new Srl(masm, asIntReg(src1), tasm.asIntConst(src2),
-                        asIntReg(dst));
+                assert isSimm13(tasm.asIntConst(src2));
+                new Srl(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
                 break;
             case IUSHR:
-                assert is_simm13(tasm.asIntConst(src2));
-                new Sra(masm, asIntReg(src1), tasm.asIntConst(src2),
-                        asIntReg(dst));
+                assert isSimm13(tasm.asIntConst(src2));
+                new Sra(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
                 break;
             case IXOR:
-                assert is_simm13(tasm.asIntConst(src2));
-                new Xor(masm, asIntReg(src1), tasm.asIntConst(src2),
-                        asIntReg(dst));
+                assert isSimm13(tasm.asIntConst(src2));
+                new Xor(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
                 break;
             case LXOR:
-                assert is_simm13(tasm.asIntConst(src2));
-                new Add(masm, asLongReg(src1), tasm.asIntConst(src2),
-                        asLongReg(dst));
+                assert isSimm13(tasm.asIntConst(src2));
+                new Add(masm, asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst));
                 break;
             case LUSHR:
                 throw new InternalError("NYI");
@@ -511,13 +502,6 @@
         }
     }
 
-    private static final int max13 = ((1 << 12) - 1);
-    private static final int min13 = -(1 << 12);
-
-    private static boolean is_simm13(int src) {
-        return min13 <= src && src <= max13;
-    }
-
     private static void verifyKind(SPARCArithmetic opcode, Value result, Value x, Value y) {
         Kind rk;
         Kind xk;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java	Tue May 28 09:04:22 2013 -0400
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.lir.sparc;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.sparc.SPARCAssembler;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.nodes.calc.*;
+
+public enum SPARCCompare {
+    ICMP, LCMP, ACMP, FCMP, DCMP;
+
+    public static class CompareOp extends SPARCLIRInstruction {
+
+        @Opcode private final SPARCCompare opcode;
+        @Use({REG, STACK, CONST}) protected Value x;
+        @Use({REG, STACK, CONST}) protected Value y;
+        private final Condition condition;
+
+        public CompareOp(SPARCCompare opcode, Condition condition, Value x, Value y) {
+            this.opcode = opcode;
+            this.condition = condition;
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+            emit(tasm, masm, opcode, condition, x, y);
+        }
+
+        @Override
+        protected void verify() {
+            super.verify();
+            assert (name().startsWith("I") && x.getKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) || (name().startsWith("L") && x.getKind() == Kind.Long && y.getKind() == Kind.Long) ||
+                            (name().startsWith("A") && x.getKind() == Kind.Object && y.getKind() == Kind.Object) ||
+                            (name().startsWith("F") && x.getKind() == Kind.Float && y.getKind() == Kind.Float) || (name().startsWith("D") && x.getKind() == Kind.Double && y.getKind() == Kind.Double);
+        }
+    }
+
+    public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm, SPARCCompare opcode, Condition condition, Value x, Value y) {
+        if (isConstant(x)) {
+            switch (opcode) {
+                case ICMP:
+                    emitCompareConstReg(masm, condition, tasm.asIntConst(x), asIntReg(y));
+                    break;
+                case FCMP:
+                    emitCompareConstReg(masm, condition, tasm.asFloatConst(x), asFloatReg(y));
+                    break;
+                case DCMP:
+                    emitCompareConstReg(masm, condition, tasm.asDoubleConst(x), asDoubleReg(y));
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        } else if (isConstant(y)) {
+            Register a = asIntReg(x);
+            int b = tasm.asIntConst(y);
+            switch (opcode) {
+                case ICMP:
+                    emitCompareRegConst(masm, condition, a, b);
+                    break;
+                case ACMP:
+                    if (((Constant) y).isNull()) {
+                        switch (condition) {
+                            case EQ:
+                                // masm.setp_eq_s32(a, b);
+                                break;
+                            case NE:
+                                // masm.setp_ne_s32(a, b);
+                                break;
+                            default:
+                                throw GraalInternalError.shouldNotReachHere();
+                        }
+                    } else {
+                        String msg = "Only null object constants allowed";
+                        throw GraalInternalError.shouldNotReachHere(msg);
+                    }
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        } else {
+            switch (opcode) {
+                case ICMP:
+                    emitCompareRegReg(masm, condition, asIntReg(x), asIntReg(y));
+                    break;
+                case LCMP:
+                    emitCompareRegReg(masm, condition, asLongReg(x), asLongReg(y));
+                    break;
+                case FCMP:
+                    emitCompareRegReg(masm, condition, asFloatReg(x), asFloatReg(y));
+                    break;
+                case DCMP:
+                    emitCompareRegReg(masm, condition, asDoubleReg(x), asDoubleReg(y));
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere("missing: " + opcode);
+            }
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private static void emitCompareConstReg(SPARCAssembler masm, Condition condition, float a, Register b) {
+        switch (condition) {
+            case EQ:
+                // masm.setp_eq_f32(a, b);
+                break;
+            case NE:
+                // masm.setp_ne_f32(a, b);
+                break;
+            case LT:
+                // masm.setp_lt_f32(a, b);
+                break;
+            case LE:
+                // masm.setp_le_f32(a, b);
+                break;
+            case GT:
+                // masm.setp_gt_f32(a, b);
+                break;
+            case GE:
+                // masm.setp_ge_f32(a, b);
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private static void emitCompareConstReg(SPARCAssembler masm, Condition condition, double a, Register b) {
+        switch (condition) {
+            case EQ:
+                // masm.setp_eq_f64(a, b);
+                break;
+            case NE:
+                // masm.setp_ne_f64(a, b);
+                break;
+            case LT:
+                // masm.setp_lt_f64(a, b);
+                break;
+            case LE:
+                // masm.setp_le_f64(a, b);
+                break;
+            case GT:
+                // masm.setp_gt_f64(a, b);
+                break;
+            case GE:
+                // masm.setp_ge_f64(a, b);
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private static void emitCompareConstReg(SPARCAssembler masm, Condition condition, int a, Register b) {
+        switch (condition) {
+            case EQ:
+                // masm.setp_eq_s32(a, b);
+                break;
+            case NE:
+                // masm.setp_ne_s32(a, b);
+                break;
+            case LT:
+                // masm.setp_lt_s32(a, b);
+                break;
+            case LE:
+                // masm.setp_le_s32(a, b);
+                break;
+            case GT:
+                // masm.setp_gt_s32(a, b);
+                break;
+            case GE:
+                // masm.setp_ge_s32(a, b);
+                break;
+            case AT:
+                // masm.setp_gt_u32(a, b);
+                break;
+            case AE:
+                // masm.setp_ge_u32(a, b);
+                break;
+            case BT:
+                // masm.setp_lt_u32(a, b);
+                break;
+            case BE:
+                // masm.setp_le_u32(a, b);
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private static void emitCompareRegConst(SPARCAssembler masm, Condition condition, Register a, int b) {
+        switch (condition) {
+            case EQ:
+                // masm.setp_eq_s32(a, b);
+                break;
+            case NE:
+                // masm.setp_ne_s32(a, b);
+                break;
+            case LT:
+                // masm.setp_lt_s32(a, b);
+                break;
+            case LE:
+                // masm.setp_le_s32(a, b);
+                break;
+            case GT:
+                // masm.setp_gt_s32(a, b);
+                break;
+            case GE:
+                // masm.setp_ge_s32(a, b);
+                break;
+            case AT:
+                // masm.setp_gt_u32(a, b);
+                break;
+            case AE:
+                // masm.setp_ge_u32(a, b);
+                break;
+            case BT:
+                // masm.setp_lt_u32(a, b);
+                break;
+            case BE:
+                // masm.setp_le_u32(a, b);
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private static void emitCompareRegReg(SPARCAssembler masm, Condition condition, Register a, Register b) {
+        switch (condition) {
+            case EQ:
+                // masm.setp_eq_s32(a, b);
+                break;
+            case NE:
+                // masm.setp_ne_s32(a, b);
+                break;
+            case LT:
+                // masm.setp_lt_s32(a, b);
+                break;
+            case LE:
+                // masm.setp_le_s32(a, b);
+                break;
+            case GT:
+                // masm.setp_gt_s32(a, b);
+                break;
+            case GE:
+                // masm.setp_ge_s32(a, b);
+                break;
+            case AT:
+                // masm.setp_gt_u32(a, b);
+                break;
+            case AE:
+                // masm.setp_ge_u32(a, b);
+                break;
+            case BT:
+                // masm.setp_lt_u32(a, b);
+                break;
+            case BE:
+                // masm.setp_le_u32(a, b);
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+}
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Tue May 28 10:59:01 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Tue May 28 09:04:22 2013 -0400
@@ -37,14 +37,46 @@
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.*;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.sparc.SPARC;
 
 public class SPARCControlFlow {
 
+    public static class BranchOp extends SPARCLIRInstruction implements StandardOp.BranchOp {
+
+        protected Condition condition;
+        protected LabelRef destination;
+
+        public BranchOp(Condition condition, LabelRef destination) {
+            this.condition = condition;
+            this.destination = destination;
+        }
+
+        @Override
+        @SuppressWarnings("unused")
+        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+            // masm.at();
+            Label l = destination.label();
+            // l.addPatchAt(tasm.asm.codeBuffer.position());
+            String target = l.isBound() ? "L" + l.toString() : AbstractSPARCAssembler.UNBOUND_TARGET;
+            // masm.bra(target);
+        }
+
+        @Override
+        public LabelRef destination() {
+            return destination;
+        }
+
+        @Override
+        public void negate(LabelRef newDestination) {
+            destination = newDestination;
+            condition = condition.negate();
+        }
+    }
+
     public static class ReturnOp extends SPARCLIRInstruction {
 
-        @Use({ REG, ILLEGAL })
-        protected Value x;
+        @Use({REG, ILLEGAL}) protected Value x;
 
         public ReturnOp(Value x) {
             this.x = x;
@@ -59,21 +91,15 @@
         }
     }
 
-    public static class SequentialSwitchOp extends SPARCLIRInstruction
-            implements FallThroughOp {
+    public static class SequentialSwitchOp extends SPARCLIRInstruction implements FallThroughOp {
 
-        @Use({ CONST })
-        protected Constant[] keyConstants;
+        @Use({CONST}) protected Constant[] keyConstants;
         private final LabelRef[] keyTargets;
         private LabelRef defaultTarget;
-        @Alive({ REG })
-        protected Value key;
-        @Temp({ REG, ILLEGAL })
-        protected Value scratch;
+        @Alive({REG}) protected Value key;
+        @Temp({REG, ILLEGAL}) protected Value scratch;
 
-        public SequentialSwitchOp(Constant[] keyConstants,
-                LabelRef[] keyTargets, LabelRef defaultTarget, Value key,
-                Value scratch) {
+        public SequentialSwitchOp(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key, Value scratch) {
             assert keyConstants.length == keyTargets.length;
             this.keyConstants = keyConstants;
             this.keyTargets = keyTargets;
@@ -112,14 +138,12 @@
                 Register intKey = asObjectReg(key);
                 Register temp = asObjectReg(scratch);
                 for (int i = 0; i < keyConstants.length; i++) {
-                    SPARCMove.move(tasm, masm, temp.asValue(Kind.Object),
-                            keyConstants[i]);
+                    SPARCMove.move(tasm, masm, temp.asValue(Kind.Object), keyConstants[i]);
                     new Subcc(masm, intKey, temp, SPARC.r0); // CMP
                     new Bpe(masm, CC.Icc, keyTargets[i].label());
                 }
             } else {
-                throw new GraalInternalError(
-                        "sequential switch only supported for int, long and object");
+                throw new GraalInternalError("sequential switch only supported for int, long and object");
             }
             if (defaultTarget != null) {
                 masm.jmp(defaultTarget.label());
@@ -144,13 +168,10 @@
         private final int lowKey;
         private final LabelRef defaultTarget;
         private final LabelRef[] targets;
-        @Alive
-        protected Value index;
-        @Temp
-        protected Value scratch;
+        @Alive protected Value index;
+        @Temp protected Value scratch;
 
-        public TableSwitchOp(final int lowKey, final LabelRef defaultTarget,
-                final LabelRef[] targets, Variable index, Variable scratch) {
+        public TableSwitchOp(final int lowKey, final LabelRef defaultTarget, final LabelRef[] targets, Variable index, Variable scratch) {
             this.lowKey = lowKey;
             this.defaultTarget = defaultTarget;
             this.targets = targets;
@@ -160,15 +181,12 @@
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
-            tableswitch(tasm, masm, lowKey, defaultTarget, targets,
-                    asIntReg(index), asLongReg(scratch));
+            tableswitch(tasm, masm, lowKey, defaultTarget, targets, asIntReg(index), asLongReg(scratch));
         }
     }
 
     @SuppressWarnings("unused")
-    private static void tableswitch(TargetMethodAssembler tasm,
-            SPARCAssembler masm, int lowKey, LabelRef defaultTarget,
-            LabelRef[] targets, Register value, Register scratch) {
+    private static void tableswitch(TargetMethodAssembler tasm, SPARCAssembler masm, int lowKey, LabelRef defaultTarget, LabelRef[] targets, Register value, Register scratch) {
         Buffer buf = masm.codeBuffer;
         // Compare index against jump table bounds
         int highKey = lowKey + targets.length - 1;
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Tue May 28 10:59:01 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Tue May 28 09:04:22 2013 -0400
@@ -28,23 +28,64 @@
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.asm.sparc.SPARCAddress;
+import com.oracle.graal.asm.sparc.SPARCAssembler;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Lddf;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldf;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsb;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsh;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsw;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Lduw;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Or;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Setuw;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Setx;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Stb;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Sth;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Stw;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Stx;
+import com.oracle.graal.asm.sparc.SPARCAssembler.NullCheck;
 import com.oracle.graal.graph.GraalInternalError;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.LIRInstruction.*;
 import com.oracle.graal.lir.StandardOp.MoveOp;
 import com.oracle.graal.lir.asm.TargetMethodAssembler;
+import com.oracle.graal.sparc.SPARC;
 
 public class SPARCMove {
 
+    public static class NullCheckOp extends SPARCLIRInstruction {
+
+        @Use({ REG })
+        protected AllocatableValue input;
+        @State
+        protected LIRFrameState state;
+
+        public NullCheckOp(Variable input, LIRFrameState state) {
+            this.input = input;
+            this.state = state;
+        }
+
+        @Override
+        @SuppressWarnings("unused")
+        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+            tasm.recordImplicitException(masm.codeBuffer.position(), state);
+            new NullCheck(masm, new SPARCAddress(asRegister(input), 0));
+        }
+    }
+
     public static class LoadOp extends SPARCLIRInstruction {
 
         private final Kind kind;
-        @Def({REG}) protected AllocatableValue result;
-        @Use({COMPOSITE}) protected SPARCAddressValue address;
-        @State protected LIRFrameState state;
+        @Def({ REG })
+        protected AllocatableValue result;
+        @Use({ COMPOSITE })
+        protected SPARCAddressValue address;
+        @State
+        protected LIRFrameState state;
 
-        public LoadOp(Kind kind, AllocatableValue result, SPARCAddressValue address, LIRFrameState state) {
+        public LoadOp(Kind kind, AllocatableValue result, SPARCAddressValue address,
+                LIRFrameState state) {
             this.kind = kind;
             this.result = result;
             this.address = address;
@@ -52,35 +93,36 @@
         }
 
         @Override
+        @SuppressWarnings("unused")
         public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
-            @SuppressWarnings("unused") SPARCAddress addr = address.toAddress();
+            SPARCAddress addr = address.toAddress();
             switch (kind) {
-                case Byte:
-                    // masm.ld_global_s8(asRegister(result), addr.getBase(), addr.getDisplacement());
-                    break;
-                case Short:
-                    // masm.ld_global_s16(asRegister(result), addr.getBase(), addr.getDisplacement());
-                    break;
-                case Char:
-                    // masm.ld_global_u16(asRegister(result), addr.getBase(), addr.getDisplacement());
-                    break;
-                case Int:
-                    // masm.ld_global_s32(asRegister(result), addr.getBase(), addr.getDisplacement());
-                    break;
-                case Long:
-                    // masm.ld_global_s64(asRegister(result), addr.getBase(), addr.getDisplacement());
-                    break;
-                case Float:
-                    // masm.ld_global_f32(asRegister(result), addr.getBase(), addr.getDisplacement());
-                    break;
-                case Double:
-                    // masm.ld_global_f64(asRegister(result), addr.getBase(), addr.getDisplacement());
-                    break;
-                case Object:
-                    // masm.ld_global_u32(asRegister(result), addr.getBase(), addr.getDisplacement());
-                    break;
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
+            case Byte:
+                new Ldsb(masm, addr, asRegister(result));
+                break;
+            case Short:
+                new Ldsh(masm, addr, asRegister(result));
+                break;
+            case Char:
+                new Lduw(masm, addr, asRegister(result));
+                break;
+            case Int:
+                new Ldsw(masm, addr, asRegister(result));
+                break;
+            case Long:
+                new Ldx(masm, addr, asRegister(result));
+                break;
+            case Float:
+                new Ldf(masm, addr, asRegister(result));
+                break;
+            case Double:
+                new Lddf(masm, addr, asRegister(result));
+                break;
+            case Object:
+                new Ldx(masm, addr, asRegister(result));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
             }
         }
     }
@@ -88,11 +130,15 @@
     public static class StoreOp extends SPARCLIRInstruction {
 
         private final Kind kind;
-        @Use({COMPOSITE}) protected SPARCAddressValue address;
-        @Use({REG}) protected AllocatableValue input;
-        @State protected LIRFrameState state;
+        @Use({ COMPOSITE })
+        protected SPARCAddressValue address;
+        @Use({ REG })
+        protected AllocatableValue input;
+        @State
+        protected LIRFrameState state;
 
-        public StoreOp(Kind kind, SPARCAddressValue address, AllocatableValue input, LIRFrameState state) {
+        public StoreOp(Kind kind, SPARCAddressValue address, AllocatableValue input,
+                LIRFrameState state) {
             this.kind = kind;
             this.address = address;
             this.input = input;
@@ -100,33 +146,34 @@
         }
 
         @Override
+        @SuppressWarnings("unused")
         public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
             assert isRegister(input);
-            @SuppressWarnings("unused") SPARCAddress addr = address.toAddress();
+            SPARCAddress addr = address.toAddress();
             switch (kind) {
-                case Byte:
-                    // masm.st_global_s8(addr.getBase(), addr.getDisplacement(), asRegister(input));
-                    break;
-                case Short:
-                    // masm.st_global_s8(addr.getBase(), addr.getDisplacement(), asRegister(input));
-                    break;
-                case Int:
-                    // masm.st_global_s32(addr.getBase(), addr.getDisplacement(), asRegister(input));
-                    break;
-                case Long:
-                    // masm.st_global_s64(addr.getBase(), addr.getDisplacement(), asRegister(input));
-                    break;
-                case Float:
-                    // masm.st_global_f32(addr.getBase(), addr.getDisplacement(), asRegister(input));
-                    break;
-                case Double:
-                    // masm.st_global_f64(addr.getBase(), addr.getDisplacement(), asRegister(input));
-                    break;
-                case Object:
-                    // masm.st_global_s32(addr.getBase(), addr.getDisplacement(), asRegister(input));
-                    break;
-                default:
-                    throw GraalInternalError.shouldNotReachHere("missing: " + address.getKind());
+            case Byte:
+                new Stb(masm, addr, asRegister(input));
+                break;
+            case Short:
+                new Sth(masm, addr, asRegister(input));
+                break;
+            case Int:
+                new Stw(masm, addr, asRegister(input));
+                break;
+            case Long:
+                new Stx(masm, addr, asRegister(input));
+                break;
+            case Float:
+                new Stx(masm, addr, asRegister(input));
+                break;
+            case Double:
+                new Stx(masm, addr, asRegister(input));
+                break;
+            case Object:
+                new Stx(masm, addr, asRegister(input));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere("missing: " + address.getKind());
             }
         }
     }
@@ -134,8 +181,10 @@
     @Opcode("MOVE")
     public static class MoveToRegOp extends SPARCLIRInstruction implements MoveOp {
 
-        @Def({REG, HINT}) protected AllocatableValue result;
-        @Use({REG, STACK, CONST}) protected Value input;
+        @Def({ REG, HINT })
+        protected AllocatableValue result;
+        @Use({ REG, STACK, CONST })
+        protected Value input;
 
         public MoveToRegOp(AllocatableValue result, Value input) {
             this.result = result;
@@ -161,8 +210,10 @@
     @Opcode("MOVE")
     public static class MoveFromRegOp extends SPARCLIRInstruction implements MoveOp {
 
-        @Def({REG, STACK}) protected AllocatableValue result;
-        @Use({REG, CONST, HINT}) protected Value input;
+        @Def({ REG, STACK })
+        protected AllocatableValue result;
+        @Use({ REG, CONST, HINT })
+        protected Value input;
 
         public MoveFromRegOp(AllocatableValue result, Value input) {
             this.result = result;
@@ -185,7 +236,8 @@
         }
     }
 
-    public static void move(TargetMethodAssembler tasm, SPARCAssembler masm, Value result, Value input) {
+    public static void move(TargetMethodAssembler tasm, SPARCAssembler masm, Value result,
+            Value input) {
         if (isRegister(input)) {
             if (isRegister(result)) {
                 reg2reg(masm, result, input);
@@ -203,58 +255,61 @@
         }
     }
 
-    private static void reg2reg(@SuppressWarnings("unused") SPARCAssembler masm, Value result, Value input) {
+    @SuppressWarnings("unused")
+    private static void reg2reg(SPARCAssembler masm, Value result,
+            Value input) {
         if (asRegister(input).equals(asRegister(result))) {
             return;
         }
         switch (input.getKind()) {
-            case Int:
-                // masm.mov_s32(asRegister(result), asRegister(input));
-                break;
-            case Long:
-             // masm.mov_s64(asRegister(result), asRegister(input));
-                break;
-            case Float:
-             // masm.mov_f32(asRegister(result), asRegister(input));
-                break;
-            case Double:
-             // masm.mov_f64(asRegister(result), asRegister(input));
-                break;
-            case Object:
-             // masm.mov_u64(asRegister(result), asRegister(input));
-                break;
-            default:
-                throw GraalInternalError.shouldNotReachHere("missing: " + input.getKind());
+        case Int:
+            new Or(masm, SPARC.r0, asRegister(input), asRegister(result));
+            break;
+        case Long:
+            new Or(masm, SPARC.r0, asRegister(input), asRegister(result));
+            break;
+        case Float:
+            new Or(masm, SPARC.r0, asRegister(input), asRegister(result));
+            break;
+        case Double:
+            new Or(masm, SPARC.r0, asRegister(input), asRegister(result));
+            break;
+        case Object:
+            new Or(masm, SPARC.r0, asRegister(input), asRegister(result));
+            break;
+        default:
+            throw GraalInternalError.shouldNotReachHere("missing: " + input.getKind());
         }
     }
 
     @SuppressWarnings("unused")
-    private static void const2reg(TargetMethodAssembler tasm, SPARCAssembler masm, Value result, Constant input) {
+    private static void const2reg(TargetMethodAssembler tasm, SPARCAssembler masm, Value result,
+            Constant input) {
         switch (input.getKind().getStackKind()) {
-            case Int:
-                if (tasm.runtime.needsDataPatch(input)) {
-                    tasm.recordDataReferenceInCode(input, 0, true);
-                }
-             // masm.mov_s32(asRegister(result), input.asInt());
-                break;
-            case Long:
-                if (tasm.runtime.needsDataPatch(input)) {
-                    tasm.recordDataReferenceInCode(input, 0, true);
-                }
-             // masm.mov_s64(asRegister(result), input.asLong());
-                break;
-            case Object:
-                if (input.isNull()) {
-                 // masm.mov_u64(asRegister(result), 0x0L);
-                } else if (tasm.target.inlineObjects) {
-                    tasm.recordDataReferenceInCode(input, 0, true);
-                 // masm.mov_u64(asRegister(result), 0xDEADDEADDEADDEADL);
-                } else {
-                 // masm.mov_u64(asRegister(result), tasm.recordDataReferenceInCode(input, 0, false));
-                }
-                break;
-            default:
-                throw GraalInternalError.shouldNotReachHere("missing: " + input.getKind());
+        case Int:
+            if (tasm.runtime.needsDataPatch(input)) {
+                tasm.recordDataReferenceInCode(input, 0, true);
+            }
+            new Setuw(masm, input.asInt(), asRegister(result));
+            break;
+        case Long:
+            if (tasm.runtime.needsDataPatch(input)) {
+                tasm.recordDataReferenceInCode(input, 0, true);
+            }
+            new Setx(masm, input.asInt(), null, asRegister(result));
+            break;
+        case Object:
+            if (input.isNull()) {
+                new Setx(masm, 0x0L, null, asRegister(result));
+            } else if (tasm.target.inlineObjects) {
+                tasm.recordDataReferenceInCode(input, 0, true);
+                new Setx(masm, 0xDEADDEADDEADDEADL, null, asRegister(result));
+            } else {
+                throw new InternalError("NYI");
+            }
+            break;
+        default:
+            throw GraalInternalError.shouldNotReachHere("missing: " + input.getKind());
         }
     }
 }
--- a/make/build-graal.xml	Tue May 28 10:59:01 2013 +0200
+++ b/make/build-graal.xml	Tue May 28 09:04:22 2013 -0400
@@ -59,8 +59,8 @@
       <src path="${src.dir}/com.oracle.graal.compiler.amd64"/>
       <src path="${src.dir}/com.oracle.graal.replacements.amd64"/>
       <src path="${src.dir}/com.oracle.graal.hotspot.amd64"/>
+      <src path="${src.dir}/com.oracle.graal.sparc"/>
       <src path="${src.dir}/com.oracle.graal.asm.sparc"/>
-      <src path="${src.dir}/com.oracle.graal.sparc"/>
       <src path="${src.dir}/com.oracle.graal.lir.sparc"/>
       <src path="${src.dir}/com.oracle.graal.compiler.sparc"/>
       <src path="${src.dir}/com.oracle.graal.hotspot.sparc"/>
--- a/mx/projects	Tue May 28 10:59:01 2013 +0200
+++ b/mx/projects	Tue May 28 09:04:22 2013 -0400
@@ -188,7 +188,7 @@
 # graal.lir.sparc
 project@com.oracle.graal.lir.sparc@subDir=graal
 project@com.oracle.graal.lir.sparc@sourceDirs=src
-project@com.oracle.graal.lir.sparc@dependencies=com.oracle.graal.asm.sparc,com.oracle.graal.sparc
+project@com.oracle.graal.lir.sparc@dependencies=com.oracle.graal.asm.sparc
 project@com.oracle.graal.lir.sparc@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.lir.sparc@javaCompliance=1.7
 
@@ -399,7 +399,7 @@
 # graal.asm.sparc
 project@com.oracle.graal.asm.sparc@subDir=graal
 project@com.oracle.graal.asm.sparc@sourceDirs=src
-project@com.oracle.graal.asm.sparc@dependencies=com.oracle.graal.hotspot
+project@com.oracle.graal.asm.sparc@dependencies=com.oracle.graal.hotspot,com.oracle.graal.sparc
 project@com.oracle.graal.asm.sparc@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.asm.sparc@javaCompliance=1.7