changeset 9851:4249a3510413

Merge
author Christos Kotselidis <christos.kotselidis@oracle.com>
date Tue, 04 Jun 2013 11:01:20 +0200
parents 6e0c6526334b (current diff) e876c2a6954f (diff)
children ed56953c514b
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java
diffstat 51 files changed, 3204 insertions(+), 600 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java	Tue Jun 04 11:01:20 2013 +0200
@@ -259,6 +259,7 @@
 
     public Assumptions(boolean useOptimisticAssumptions) {
         this.useOptimisticAssumptions = useOptimisticAssumptions;
+        list = new Assumption[4];
     }
 
     /**
@@ -362,6 +363,10 @@
         count++;
     }
 
+    public Assumption[] getAssumptions() {
+        return list;
+    }
+
     public void record(Assumptions assumptions) {
         for (int i = 0; i < assumptions.count; i++) {
             record(assumptions.list[i]);
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Tue Jun 04 11:01:20 2013 +0200
@@ -198,7 +198,8 @@
      * Resolves the method implementation for virtual dispatches on objects of this dynamic type.
      * 
      * @param method the method to select the implementation of
-     * @return the method implementation that would be selected at runtime
+     * @return the method implementation that would be selected at runtime, or {@code null} if the
+     *         runtime cannot resolve the method at this point in time.
      */
     ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method);
 
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java	Tue Jun 04 11:01:20 2013 +0200
@@ -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 Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Tue Jun 04 11:01:20 2013 +0200
@@ -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.
@@ -189,7 +190,27 @@
             assert rs1 >= 0 && rs1 < 0x20;
             assert  rd >= 0 &&  rd < 0x20;
 
-            masm.emitInt(op << 30 | rd << 25 | op3 << 19 |  rs1 << 14);
+            masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14);
+        }
+    }
+
+    public static class Fmt3r {
+        public Fmt3r(SPARCAssembler masm, int op, int fcn, int op3) {
+            assert  op == 23;
+            assert op3 >= 0 && op3 < 0x40;
+            assert fcn >= 0 && fcn < 0x40;
+
+            masm.emitInt(op << 30 | fcn << 25 | op3 << 19);
+        }
+    }
+
+    public static class Fmt4a {
+        public Fmt4a(SPARCAssembler masm, int op, int op3, int cc, int rs1, int regOrImmediate, int rd) {
+            assert  op == 2;
+            assert rs1 >= 0 && rs1 < 0x20;
+            assert  rd >= 0 &&  rd < 0x10;
+
+            masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | ((cc << 11) & 0x000001800) | regOrImmediate);
         }
     }
 
@@ -328,6 +349,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"),
@@ -376,6 +411,10 @@
         Fdivd(0x4D, "fdivd"),
         Fdivq(0x4E, "fdivq"),
 
+        Fsqrts(0x29, "fsqrts"),
+        Fsqrtd(0x2A, "fsqrtd"),
+        Fsqrtq(0x2B, "fsqrtq"),
+
         Fsmuld(0x69, "fsmuld"),
         Fmulq(0x6B, "fmulq"),
         Fdmuldq(0x6E, "fdmulq"),
@@ -452,7 +491,7 @@
         }
     }
 
-    public enum Condition {
+    public enum ConditionFlag {
         // for FBfcc & FBPfcc instruction
 
         F_Never(0, "f_never"),
@@ -499,7 +538,7 @@
         private final int value;
         private final String operator;
 
-        private Condition(int value, String op) {
+        private ConditionFlag(int value, String op) {
             this.value = value;
             this.operator = op;
         }
@@ -567,9 +606,25 @@
         return x & ((1 << nbits) - 1);
     }
 
-    private static int fcn(int val) {
-        assert val < 0x20;
-        return (val << 25);
+    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);
+    }
+
+    @Override
+    @SuppressWarnings("unused")
+    public void jmp(Label l) {
+         new Bpa(this, l);
     }
 
     public static class Add extends Fmt3b {
@@ -646,23 +701,119 @@
 
     public static class Bpa extends Fmt2c {
         public Bpa(SPARCAssembler masm, int simmm19) {
-            super(masm, Ops.BranchOp.getValue(), 0, Condition.Always.getValue(),
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Always.getValue(),
                             Op2s.Bp.getValue(), CC.Icc.getValue(), 1, simmm19);
         }
         public Bpa(SPARCAssembler masm, Label label) {
-            super(masm, Ops.BranchOp.getValue(), 0, Condition.Always.getValue(),
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Always.getValue(),
                             Op2s.Bp.getValue(), CC.Icc.getValue(), 1,
                             label.isBound() ? label.position() : patchUnbound(masm, label));
         }
     }
 
+    public static class Bpcc extends Fmt2c {
+        public Bpcc(SPARCAssembler masm, CC cc, int simmm19) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.CarryClear.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1, simmm19);
+        }
+        public Bpcc(SPARCAssembler masm, CC cc, Label label) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.CarryClear.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1,
+                            label.isBound() ? label.position() : patchUnbound(masm, label));
+        }
+    }
+
+    public static class Bpcs extends Fmt2c {
+        public Bpcs(SPARCAssembler masm, CC cc, int simmm19) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.CarrySet.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1, simmm19);
+        }
+        public Bpcs(SPARCAssembler masm, CC cc, Label label) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.CarrySet.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1,
+                            label.isBound() ? label.position() : patchUnbound(masm, label));
+        }
+    }
+
     public static class Bpe extends Fmt2c {
         public Bpe(SPARCAssembler masm, CC cc, int simmm19) {
-            super(masm, Ops.BranchOp.getValue(), 0, Condition.Equal.getValue(),
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Equal.getValue(),
                             Op2s.Bp.getValue(), cc.getValue(), 1, simmm19);
         }
         public Bpe(SPARCAssembler masm, CC cc, Label label) {
-            super(masm, Ops.BranchOp.getValue(), 0, Condition.Equal.getValue(),
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Equal.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1,
+                            label.isBound() ? label.position() : patchUnbound(masm, label));
+        }
+    }
+
+    public static class Bpg extends Fmt2c {
+        public Bpg(SPARCAssembler masm, CC cc, int simmm19) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Greater.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1, simmm19);
+        }
+        public Bpg(SPARCAssembler masm, CC cc, Label label) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Greater.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1,
+                            label.isBound() ? label.position() : patchUnbound(masm, label));
+        }
+    }
+
+    public static class Bpge extends Fmt2c {
+        public Bpge(SPARCAssembler masm, CC cc, int simmm19) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.GreaterEqual.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1, simmm19);
+        }
+        public Bpge(SPARCAssembler masm, CC cc, Label label) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.GreaterEqual.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1,
+                            label.isBound() ? label.position() : patchUnbound(masm, label));
+        }
+    }
+
+    public static class Bpgu extends Fmt2c {
+        public Bpgu(SPARCAssembler masm, CC cc, int simmm19) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.GreaterUnsigned.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1, simmm19);
+        }
+        public Bpgu(SPARCAssembler masm, CC cc, Label label) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.GreaterUnsigned.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1,
+                            label.isBound() ? label.position() : patchUnbound(masm, label));
+        }
+    }
+
+    public static class Bpl extends Fmt2c {
+        public Bpl(SPARCAssembler masm, CC cc, int simmm19) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Less.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1, simmm19);
+        }
+        public Bpl(SPARCAssembler masm, CC cc, Label label) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Less.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1,
+                            label.isBound() ? label.position() : patchUnbound(masm, label));
+        }
+    }
+
+    public static class Bple extends Fmt2c {
+        public Bple(SPARCAssembler masm, CC cc, int simmm19) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.LessEqual.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1, simmm19);
+        }
+        public Bple(SPARCAssembler masm, CC cc, Label label) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.LessEqual.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1,
+                            label.isBound() ? label.position() : patchUnbound(masm, label));
+        }
+    }
+
+    public static class Bpleu extends Fmt2c {
+        public Bpleu(SPARCAssembler masm, CC cc, int simmm19) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.LessEqualUnsigned.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1, simmm19);
+        }
+        public Bpleu(SPARCAssembler masm, CC cc, Label label) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.LessEqualUnsigned.getValue(),
                             Op2s.Bp.getValue(), cc.getValue(), 1,
                             label.isBound() ? label.position() : patchUnbound(masm, label));
         }
@@ -670,11 +821,11 @@
 
     public static class Bpn extends Fmt2c {
         public Bpn(SPARCAssembler masm, CC cc, int simmm19) {
-            super(masm, Ops.BranchOp.getValue(), 0, Condition.Never.getValue(),
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Never.getValue(),
                             Op2s.Bp.getValue(), cc.getValue(), 1, simmm19);
         }
         public Bpn(SPARCAssembler masm, CC cc, Label label) {
-            super(masm, Ops.BranchOp.getValue(), 0, Condition.Never.getValue(),
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Never.getValue(),
                             Op2s.Bp.getValue(), cc.getValue(), 1,
                             label.isBound() ? label.position() : patchUnbound(masm, label));
         }
@@ -682,11 +833,59 @@
 
     public static class Bpne extends Fmt2c {
         public Bpne(SPARCAssembler masm, CC cc, int simmm19) {
-            super(masm, Ops.BranchOp.getValue(), 0, Condition.NotZero.getValue(),
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.NotZero.getValue(),
                             Op2s.Bp.getValue(), cc.getValue(), 1, simmm19);
         }
         public Bpne(SPARCAssembler masm, CC cc, Label label) {
-            super(masm, Ops.BranchOp.getValue(), 0, Condition.NotZero.getValue(),
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.NotZero.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1,
+                            label.isBound() ? label.position() : patchUnbound(masm, label));
+        }
+    }
+
+    public static class Bpneg extends Fmt2c {
+        public Bpneg(SPARCAssembler masm, CC cc, int simmm19) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Negative.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1, simmm19);
+        }
+        public Bpneg(SPARCAssembler masm, CC cc, Label label) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Negative.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1,
+                            label.isBound() ? label.position() : patchUnbound(masm, label));
+        }
+    }
+
+    public static class Bppos extends Fmt2c {
+        public Bppos(SPARCAssembler masm, CC cc, int simmm19) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Positive.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1, simmm19);
+        }
+        public Bppos(SPARCAssembler masm, CC cc, Label label) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Positive.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1,
+                            label.isBound() ? label.position() : patchUnbound(masm, label));
+        }
+    }
+
+    public static class Bpvc extends Fmt2c {
+        public Bpvc(SPARCAssembler masm, CC cc, int simmm19) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.OverflowClear.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1, simmm19);
+        }
+        public Bpvc(SPARCAssembler masm, CC cc, Label label) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.OverflowClear.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1,
+                            label.isBound() ? label.position() : patchUnbound(masm, label));
+        }
+    }
+
+    public static class Bpvs extends Fmt2c {
+        public Bpvs(SPARCAssembler masm, CC cc, int simmm19) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.OverflowSet.getValue(),
+                            Op2s.Bp.getValue(), cc.getValue(), 1, simmm19);
+        }
+        public Bpvs(SPARCAssembler masm, CC cc, Label label) {
+            super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.OverflowSet.getValue(),
                             Op2s.Bp.getValue(), cc.getValue(), 1,
                             label.isBound() ? label.position() : patchUnbound(masm, label));
         }
@@ -774,10 +973,20 @@
         }
     }
 
-    public final void flushw() {
-        emitInt(Ops.ArithOp.getValue() | Op3s.Flushw.getValue());
+    public static class Flushw extends Fmt3r {
+        public Flushw(SPARCAssembler masm) {
+            super(masm, Ops.ArithOp.getValue(), 0, Op3s.Flushw.getValue());
+        }
     }
 
+    public static class Fsqrtd extends Fmt3p {
+        public Fsqrtd(SPARCAssembler masm, Register src2, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fsqrtd.getValue(),
+                  0, src2.encoding(), dst.encoding());
+        }
+    }
+
+
     public static class Fsubs extends Fmt3p {
         public Fsubs(SPARCAssembler masm, Register src1, Register src2, Register dst) {
             super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fsubs.getValue(),
@@ -799,32 +1008,75 @@
         }
     }
 
-    @Override
-    @SuppressWarnings("unused")
-    public void jmp(Label l) {
-        new Bpa(this, l);
+    public static class Jmpl extends Fmt3b {
+        public Jmpl(SPARCAssembler asm, SPARCAddress src, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Jmpl.getValue(),
+                  src.getBase().encoding(), src.getDisplacement(), dst.encoding());
+        }
     }
 
+    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());
+        public Membar(SPARCAssembler masm, int barriers) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Membar.getValue(),
+                  SPARC.r15.encoding(), ImmedTrue | barriers, SPARC.r0.encoding());
         }
     }
 
     public static class Movcc extends Fmt4c {
-        public Movcc(SPARCAssembler masm, Condition cond, CC cca, Register src2, Register dst) {
+        public Movcc(SPARCAssembler masm, ConditionFlag cond, CC cca, Register src2, Register dst) {
             super(masm, Ops.ArithOp.getValue(), Op3s.Movcc.getValue(), cond.getValue(), cca.getValue(),
                   src2.encoding(), dst.encoding());
         }
-        public Movcc(SPARCAssembler masm, Condition cond, CC cca, int simm11a, Register dst) {
+        public Movcc(SPARCAssembler masm, ConditionFlag cond, CC cca, int simm11a, Register dst) {
             super(masm, Ops.ArithOp.getValue(), Op3s.Movcc.getValue(), cond.getValue(), cca.getValue(),
                   simm11a, dst.encoding());
         }
@@ -862,6 +1114,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());
@@ -946,6 +1205,19 @@
         }
     }
 
+    public static class Restore extends Fmt3b {
+        public Restore(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Restore.getValue(),
+                  src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Restored extends Fmt3r {
+        public Restored(SPARCAssembler asm) {
+            super(asm, Ops.ArithOp.getValue(), 1, Op3s.Saved.getValue());
+        }
+    }
+
     public static class Return extends Fmt3d {
         public Return(SPARCAssembler masm, Register src1, int simm13) {
             super(masm, Ops.ArithOp.getValue(), Op3s.Rett.getValue(), src1.encoding(), simm13);
@@ -955,12 +1227,17 @@
         }
     }
 
-    public final void restored() {
-        emitInt(Ops.ArithOp.getValue() | Op3s.Saved.getValue() | fcn(1));
+    public static class Save extends Fmt3b {
+        public Save(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Save.getValue(),
+                  src1.encoding(), src2.encoding(), dst.encoding());
+        }
     }
 
-    public final void saved() {
-        emitInt(Ops.ArithOp.getValue() | Op3s.Saved.getValue() | fcn(0));
+    public static class Saved extends Fmt3r {
+        public Saved(SPARCAssembler asm) {
+            super(asm, Ops.ArithOp.getValue(), 0, Op3s.Saved.getValue());
+        }
     }
 
     @Deprecated
@@ -996,8 +1273,17 @@
         }
     }
 
-    public final void sir(int simm13a) {
-        emitInt(Ops.ArithOp.getValue() | Op3s.Sir.getValue() | ImmedTrue | simm(simm13a, 13));
+    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());
+        }
+    }
+
+    public static class Sir extends Fmt3b {
+        public Sir(SPARCAssembler asm, int simm13) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Sir.getValue(),
+                  SPARC.r0.encoding(), simm13, SPARC.r15.encoding());
+        }
     }
 
     public static class Sll extends Fmt3b {
@@ -1074,8 +1360,39 @@
     }
 
     @Deprecated
-    public final void stbar() {
-        emitInt(Ops.ArithOp.getValue() | Op3s.Membar.getValue() | 0x0003C000);
+    public static class Stbar extends Fmt3b {
+        public Stbar(SPARCAssembler masm) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Membar.getValue(),
+                  SPARC.r15.encoding(), 0, SPARC.r0.encoding());
+        }
+    }
+
+    public static class Stb extends Fmt3b {
+        public Stb(SPARCAssembler masm, Register dst, SPARCAddress addr) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Stb.getValue(),
+                            addr.getBase().encoding(), addr.getDisplacement(), dst.encoding());
+        }
+    }
+
+    public static class Sth extends Fmt3b {
+        public Sth(SPARCAssembler masm, Register dst, SPARCAddress addr) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Sth.getValue(),
+                            addr.getBase().encoding(), addr.getDisplacement(), dst.encoding());
+        }
+    }
+
+    public static class Stw extends Fmt3b {
+        public Stw(SPARCAssembler masm, Register dst, SPARCAddress addr) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Stw.getValue(),
+                            addr.getBase().encoding(), addr.getDisplacement(), dst.encoding());
+        }
+    }
+
+    public static class Stx extends Fmt3b {
+        public Stx(SPARCAssembler masm, Register dst, SPARCAddress addr) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Stx.getValue(),
+                            addr.getBase().encoding(), addr.getDisplacement(), dst.encoding());
+        }
     }
 
     public static class Sub extends Fmt3b {
@@ -1114,6 +1431,17 @@
         }
     }
 
+    public static class Ta extends Fmt4a {
+        public Ta(SPARCAssembler asm, CC cc, Register src1, int trap) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), trap, ConditionFlag.Always.getValue());
+        }
+        public Ta(SPARCAssembler asm, CC cc, Register src1, Register src2) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), src2.encoding(), ConditionFlag.Always.getValue());
+        }
+    }
+
     public static class Taddcc extends Fmt3b {
         public Taddcc(SPARCAssembler masm, Register src1, int simm13, Register dst) {
             super(masm, Ops.ArithOp.getValue(), Op3s.Taddcc.getValue(), src1.encoding(), simm13, dst.encoding());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Tue Jun 04 11:01:20 2013 +0200
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.asm.sparc;
+
+import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.sparc.*;
+
+public class SPARCMacroAssembler extends SPARCAssembler {
+
+    public SPARCMacroAssembler(TargetDescription target, RegisterConfig registerConfig) {
+        super(target, registerConfig);
+    }
+
+    @SuppressWarnings("unused")
+    public static class Bclr {
+
+        public Bclr(SPARCAssembler asm, Register src, Register dst) {
+            new Andn(asm, dst, src, dst);
+        }
+
+        public Bclr(SPARCAssembler asm, int simm13, Register dst) {
+            new Andn(asm, dst, simm13, dst);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Bset {
+
+        public Bset(SPARCAssembler asm, Register src, Register dst) {
+            new Or(asm, dst, src, dst);
+        }
+
+        public Bset(SPARCAssembler asm, int simm13, Register dst) {
+            new Or(asm, dst, simm13, dst);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Btog {
+
+        public Btog(SPARCAssembler asm, Register src, Register dst) {
+            new Xor(asm, dst, src, dst);
+        }
+
+        public Btog(SPARCAssembler asm, int simm13, Register dst) {
+            new Xor(asm, dst, simm13, dst);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Btst {
+
+        public Btst(SPARCAssembler asm, Register src1, Register src2) {
+            new Andcc(asm, src1, src2, SPARC.g0);
+        }
+
+        public Btst(SPARCAssembler asm, Register src1, int simm13) {
+            new Andcc(asm, src1, simm13, SPARC.g0);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Clr {
+
+        public Clr(SPARCAssembler asm, Register dst) {
+            new Or(asm, SPARC.g0, SPARC.g0, dst);
+        }
+
+        public Clr(SPARCAssembler asm, SPARCAddress addr) {
+            new Stw(asm, SPARC.g0, addr);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Clrb {
+
+        public Clrb(SPARCAssembler asm, SPARCAddress addr) {
+            new Stb(asm, SPARC.g0, addr);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Clrh {
+
+        public Clrh(SPARCAssembler asm, SPARCAddress addr) {
+            new Sth(asm, SPARC.g0, addr);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Clrx {
+
+        public Clrx(SPARCAssembler asm, SPARCAddress addr) {
+            new Stx(asm, SPARC.g0, addr);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Clruw {
+
+        public Clruw(SPARCAssembler asm, Register src1, Register dst) {
+            assert src1.encoding() != dst.encoding();
+            new Srl(asm, src1, SPARC.g0, dst);
+        }
+
+        public Clruw(SPARCAssembler asm, Register dst) {
+            new Srl(asm, dst, SPARC.g0, dst);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Cmp {
+
+        public Cmp(SPARCAssembler asm, Register a, Register b) {
+            new Subcc(asm, a, b, SPARC.g0);
+        }
+
+        public Cmp(SPARCAssembler asm, Register a, int simm13) {
+            new Subcc(asm, a, simm13, SPARC.g0);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Dec {
+
+        public Dec(SPARCAssembler asm, Register dst) {
+            new Sub(asm, dst, 1, dst);
+        }
+
+        public Dec(SPARCAssembler asm, int simm13, Register dst) {
+            new Sub(asm, dst, simm13, dst);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Deccc {
+
+        public Deccc(SPARCAssembler asm, Register dst) {
+            new Subcc(asm, dst, 1, dst);
+        }
+
+        public Deccc(SPARCAssembler asm, int simm13, Register dst) {
+            new Subcc(asm, dst, simm13, dst);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Inc {
+
+        public Inc(SPARCAssembler asm, Register dst) {
+            new Add(asm, dst, 1, dst);
+        }
+
+        public Inc(SPARCAssembler asm, int simm13, Register dst) {
+            new Add(asm, dst, simm13, dst);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Inccc {
+
+        public Inccc(SPARCAssembler asm, Register dst) {
+            new Addcc(asm, dst, 1, dst);
+        }
+
+        public Inccc(SPARCAssembler asm, int simm13, Register dst) {
+            new Addcc(asm, dst, simm13, dst);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Jmp {
+
+        public Jmp(SPARCAssembler asm, SPARCAddress address) {
+            new Jmpl(asm, address, SPARC.g0);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Neg {
+
+        public Neg(SPARCAssembler asm, Register src2, Register dst) {
+            assert src2.encoding() != dst.encoding();
+            new Sub(asm, SPARC.g0, src2, dst);
+        }
+
+        public Neg(SPARCAssembler asm, Register dst) {
+            new Sub(asm, SPARC.g0, dst, dst);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Not {
+
+        public Not(SPARCAssembler asm, Register src1, Register dst) {
+            assert src1.encoding() != dst.encoding();
+            new Xnor(asm, src1, SPARC.g0, dst);
+        }
+
+        public Not(SPARCAssembler asm, Register dst) {
+            new Xnor(asm, dst, SPARC.g0, dst);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class RestoreWindow {
+
+        public RestoreWindow(SPARCAssembler asm) {
+            new Restore(asm, SPARC.g0, SPARC.g0, SPARC.g0);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Ret {
+
+        public Ret(SPARCAssembler asm) {
+            new Jmpl(asm, new SPARCAddress(SPARC.i0, 8), SPARC.g0);
+
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class SaveWindow {
+
+        public SaveWindow(SPARCAssembler asm) {
+            new Save(asm, SPARC.g0, SPARC.g0, SPARC.g0);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Setuw {
+
+        public Setuw(SPARCAssembler asm, int value, Register dst) {
+            if (value >= 0 && ((value & 0x3FFF) == 0)) {
+                new Sethi(asm, hi22(value), dst);
+            } else if (-4095 <= value && value <= 4096) {
+                new Or(asm, SPARC.g0, value, dst);
+            } else {
+                new Sethi(asm, hi22(value), dst);
+                new Or(asm, dst, lo10(value), dst);
+            }
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Setx {
+
+        public Setx(SPARCAssembler asm, long value, Register tmp, Register dst) {
+            int hi = (int) (value >> 32);
+            int lo = (int) (value & ~0);
+
+            if (isSimm13(lo) && value == lo) {
+                new Or(asm, SPARC.g0, lo, dst);
+            } else if (hi == 0) {
+                new Sethi(asm, lo, dst);   // hardware version zero-extends to upper 32
+                if (lo10(lo) != 0) {
+                    new Or(asm, dst, lo10(lo), dst);
+                }
+            } else if (hi == -1) {
+                new Sethi(asm, ~lo, dst);  // hardware version zero-extends to upper 32
+                new Xor(asm, dst, lo10(lo) ^ ~lo10(~0), dst);
+            } else if (lo == 0) {
+                if (isSimm13(hi)) {
+                    new Or(asm, SPARC.g0, hi, dst);
+                } else {
+                    new Sethi(asm, hi, dst);   // hardware version zero-extends to upper 32
+                    if (lo10(hi) != 0) {
+                        new Or(asm, dst, lo10(hi), dst);
+                    }
+                }
+                new Sllx(asm, dst, 32, dst);
+            } else {
+                new Sethi(asm, hi, tmp);
+                new Sethi(asm, lo, dst); // macro assembler version sign-extends
+                if (lo10(hi) != 0) {
+                    new Or(asm, tmp, lo10(hi), tmp);
+                }
+                if (lo10(lo) != 0) {
+                    new Or(asm, dst, lo10(lo), dst);
+                }
+                new Sllx(asm, tmp, 32, tmp);
+                new Or(asm, dst, tmp, dst);
+            }
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Signx {
+
+        public Signx(SPARCAssembler asm, Register src1, Register dst) {
+            assert src1.encoding() != dst.encoding();
+            new Sra(asm, src1, SPARC.g0, dst);
+        }
+
+        public Signx(SPARCAssembler asm, Register dst) {
+            new Sra(asm, dst, SPARC.g0, dst);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class Trap {
+
+        public Trap(SPARCAssembler asm, int trap) {
+            assert trap >= 0 && trap <= 0x7f;
+            new Ta(asm, Icc, SPARC.g0, trap);
+        }
+    }
+}
--- /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 Jun 04 11:01:20 2013 +0200
@@ -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
+            }
+        }
+    }
+}
--- /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/LogicSPARCTest.java	Tue Jun 04 11:01:20 2013 +0200
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.compiler.sparc.test;
+
+import java.lang.reflect.Method;
+
+import org.junit.Test;
+
+public class LogicSPARCTest extends SPARCTestBase {
+
+    @Test
+    public void testAnd() {
+        compile("testAnd2I");
+        compile("testAnd2L");
+    }
+
+    public static int testAnd2I(int a, int b) {
+        return a & b;
+    }
+
+    public static long testAnd2L(long a, long b) {
+        return a & b;
+    }
+
+    @Test
+    public void testOr() {
+        compile("testOr2I");
+        compile("testOr2L");
+    }
+
+    public static int testOr2I(int a, int b) {
+        return a | b;
+    }
+
+    public static long testOr2L(long a, long b) {
+        return a | b;
+    }
+
+    @Test
+    public void testXor() {
+        compile("testXor2I");
+        compile("testXor2L");
+    }
+
+    public static int testXor2I(int a, int b) {
+        return a ^ b;
+    }
+
+    public static long testXor2L(long a, long b) {
+        return a ^ b;
+    }
+
+    @Test
+    public void testNot() {
+        compile("testNot1I");
+        compile("testNot1L");
+    }
+
+    public static int testNot1I(int a) {
+        return ~a;
+    }
+
+    public static long testNot1L(long a) {
+        return ~a;
+    }
+
+    @Test
+    public void testShiftLeft() {
+        compile("testShiftLeft2I");
+        compile("testShiftLeft2L");
+    }
+
+    public static int testShiftLeft2I(int a, int b) {
+        return a << b;
+    }
+
+    public static long testShiftLeft2L(long a, int b) {
+        return a << b;
+    }
+
+    @Test
+    public void testShiftRight() {
+        compile("testShiftRight2I");
+        compile("testShiftRight2L");
+        compile("testUnsignedShiftRight2I");
+        compile("testUnsignedShiftRight2L");
+    }
+
+    public static int testShiftRight2I(int a, int b) {
+        return a >> b;
+    }
+
+    public static long testShiftRight2L(long a, int b) {
+        return a >> b;
+    }
+
+    public static int testUnsignedShiftRight2I(int a, int b) {
+        return a >>> b;
+    }
+
+    public static long testUnsignedShiftRight2L(long a, long b) {
+        return a >>> b;
+    }
+
+    public static void main(String[] args) {
+        LogicSPARCTest test = new LogicSPARCTest();
+        for (Method m : LogicSPARCTest.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 Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue Jun 04 11:01:20 2013 +0200
@@ -24,7 +24,11 @@
 package com.oracle.graal.compiler.sparc;
 
 import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.lir.LIRValueUtil.*;
+import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.*;
+import static com.oracle.graal.lir.sparc.SPARCMathIntrinsicOp.IntrinsicOpcode.*;
 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;
@@ -32,33 +36,41 @@
 import com.oracle.graal.api.code.ForeignCallLinkage;
 import com.oracle.graal.api.code.StackSlot;
 import com.oracle.graal.api.code.TargetDescription;
-import com.oracle.graal.api.meta.AllocatableValue;
-import com.oracle.graal.api.meta.Constant;
-import com.oracle.graal.api.meta.Kind;
-import com.oracle.graal.api.meta.Value;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.NumUtil;
 import com.oracle.graal.compiler.gen.LIRGenerator;
 import com.oracle.graal.compiler.target.LIRGenLowerable;
 import com.oracle.graal.graph.GraalInternalError;
-import com.oracle.graal.lir.FrameMap;
-import com.oracle.graal.lir.LIR;
-import com.oracle.graal.lir.LIRFrameState;
-import com.oracle.graal.lir.LIRInstruction;
-import com.oracle.graal.lir.LabelRef;
-import com.oracle.graal.lir.Variable;
+import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.*;
-import com.oracle.graal.lir.sparc.*;
+import com.oracle.graal.lir.sparc.SPARCAddressValue;
+import com.oracle.graal.lir.sparc.SPARCArithmetic.BinaryRegConst;
+import com.oracle.graal.lir.sparc.SPARCArithmetic.Op1Stack;
+import com.oracle.graal.lir.sparc.SPARCArithmetic.Op2Stack;
+import com.oracle.graal.lir.sparc.SPARCArithmetic.Op2Reg;
+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.SPARCBitManipulationOp;
+import com.oracle.graal.lir.sparc.SPARCBreakpointOp;
+import com.oracle.graal.lir.sparc.SPARCByteSwapOp;
+import com.oracle.graal.lir.sparc.SPARCCompare.CompareOp;
+import com.oracle.graal.lir.sparc.SPARCControlFlow.BranchOp;
+import com.oracle.graal.lir.sparc.SPARCControlFlow.CondMoveOp;
+import com.oracle.graal.lir.sparc.SPARCControlFlow.FloatCondMoveOp;
 import com.oracle.graal.lir.sparc.SPARCControlFlow.ReturnOp;
 import com.oracle.graal.lir.sparc.SPARCControlFlow.SequentialSwitchOp;
+import com.oracle.graal.lir.sparc.SPARCControlFlow.SwitchRangesOp;
 import com.oracle.graal.lir.sparc.SPARCControlFlow.TableSwitchOp;
+import com.oracle.graal.lir.sparc.SPARCMathIntrinsicOp;
 import com.oracle.graal.lir.sparc.SPARCMove.LoadOp;
+import com.oracle.graal.lir.sparc.SPARCMove.MembarOp;
 import com.oracle.graal.lir.sparc.SPARCMove.MoveFromRegOp;
 import com.oracle.graal.lir.sparc.SPARCMove.MoveToRegOp;
+import com.oracle.graal.lir.sparc.SPARCMove.NullCheckOp;
+import com.oracle.graal.lir.sparc.SPARCMove.StackLoadAddressOp;
 import com.oracle.graal.lir.sparc.SPARCMove.StoreOp;
-import com.oracle.graal.lir.sparc.SPARCArithmetic.Op1Stack;
-import com.oracle.graal.lir.sparc.SPARCArithmetic.Op2Stack;
-import com.oracle.graal.lir.sparc.SPARCArithmetic.Unary1Op;
-import com.oracle.graal.lir.sparc.SPARCArithmetic.Unary2Op;
+import com.oracle.graal.lir.sparc.SPARCTestOp;
 import com.oracle.graal.nodes.BreakpointNode;
 import com.oracle.graal.nodes.DeoptimizingNode;
 import com.oracle.graal.nodes.DirectCallTargetNode;
@@ -67,7 +79,7 @@
 import com.oracle.graal.nodes.SafepointNode;
 import com.oracle.graal.nodes.StructuredGraph;
 import com.oracle.graal.nodes.ValueNode;
-import com.oracle.graal.nodes.calc.Condition;
+import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.calc.ConvertNode.Op;
 import com.oracle.graal.nodes.java.CompareAndSwapNode;
 
@@ -133,6 +145,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, left, right));
+                append(new BranchOp(cond, label));
+                break;
+            case Long:
+                append(new CompareOp(LCMP, left, right));
+                append(new BranchOp(cond, label));
+                break;
+            case Float:
+                append(new CompareOp(FCMP, left, right));
+                append(new BranchOp(cond, label));
+                break;
+            case Double:
+                append(new CompareOp(DCMP, left, right));
+                append(new BranchOp(cond, label));
+                break;
+            case Object:
+                append(new CompareOp(ACMP, left, right));
+                append(new BranchOp(cond, label));
+                break;
             default:
                 throw GraalInternalError.shouldNotReachHere("" + left.getKind());
         }
@@ -140,22 +172,112 @@
 
     @Override
     public void emitOverflowCheckBranch(LabelRef label, boolean negated) {
-        throw new InternalError("NYI");
+        // append(new BranchOp(negated ? ConditionFlag.NoOverflow : ConditionFlag.Overflow, label));
+        throw GraalInternalError.shouldNotReachHere("emitOverflowCheckBranch: unimp");
     }
 
     @Override
     public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label) {
-        throw new InternalError("NYI");
+        emitIntegerTest(left, right);
+        append(new BranchOp(negated ? Condition.NE : Condition.EQ, label));
+    }
+
+    private void emitIntegerTest(Value a, Value b) {
+        assert a.getKind().getStackKind() == Kind.Int || a.getKind() == Kind.Long;
+        if (LIRValueUtil.isVariable(b)) {
+            append(new SPARCTestOp(load(b), loadNonConst(a)));
+        } else {
+            append(new SPARCTestOp(load(a), loadNonConst(b)));
+        }
+    }
+
+    @Override
+    public Variable load(Value value) {
+        if (!isVariable(value)) {
+            return emitMove(value);
+        }
+        return (Variable) value;
+    }
+
+    @Override
+    public Value loadNonConst(Value value) {
+        if (isConstant(value) && !canInlineConstant((Constant) value)) {
+            return emitMove(value);
+        }
+        return value;
     }
 
     @Override
-    public Variable emitConditionalMove(Value leftVal, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
-        throw new InternalError("NYI");
+    public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
+        boolean mirrored = emitCompare(left, right);
+        Condition finalCondition = mirrored ? cond.mirror() : cond;
+
+        Variable result = newVariable(trueValue.getKind());
+        switch (left.getKind().getStackKind()) {
+            case Int:
+            case Long:
+            case Object:
+                append(new CondMoveOp(result, finalCondition, load(trueValue), loadNonConst(falseValue)));
+                break;
+            case Float:
+            case Double:
+                append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue)));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere("" + left.getKind());
+        }
+        return result;
+    }
+
+    /**
+     * This method emits the compare instruction, and may reorder the operands. It returns true if
+     * it did so.
+     * 
+     * @param a the left operand of the comparison
+     * @param b the right operand of the comparison
+     * @return true if the left and right operands were switched, false otherwise
+     */
+    private boolean emitCompare(Value a, Value b) {
+        Variable left;
+        Value right;
+        boolean mirrored;
+        if (LIRValueUtil.isVariable(b)) {
+            left = load(b);
+            right = loadNonConst(a);
+            mirrored = true;
+        } else {
+            left = load(a);
+            right = loadNonConst(b);
+            mirrored = false;
+        }
+        switch (left.getKind().getStackKind()) {
+            case Int:
+                append(new CompareOp(ICMP, left, right));
+                break;
+            case Long:
+                append(new CompareOp(LCMP, left, right));
+                break;
+            case Object:
+                append(new CompareOp(ACMP, left, right));
+                break;
+            case Float:
+                append(new CompareOp(FCMP, left, right));
+                break;
+            case Double:
+                append(new CompareOp(DCMP, left, right));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+        return mirrored;
     }
 
     @Override
-    public Variable emitIntegerTestMove(Value leftVal, Value right, Value trueValue, Value falseValue) {
-        throw new InternalError("NYI");
+    public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) {
+        emitIntegerTest(left, right);
+        Variable result = newVariable(trueValue.getKind());
+        append(new CondMoveOp(result, Condition.EQ, load(trueValue), loadNonConst(falseValue)));
+        return result;
     }
 
     @Override
@@ -187,7 +309,7 @@
 
     @Override
     protected void emitSwitchRanges(int[] lowKeys, int[] highKeys, LabelRef[] targets, LabelRef defaultTarget, Value key) {
-        throw new InternalError("NYI");
+        append(new SwitchRangesOp(lowKeys, highKeys, targets, defaultTarget, key));
     }
 
     @Override
@@ -200,52 +322,60 @@
 
     @Override
     public void emitBitCount(Variable result, Value operand) {
-        throw new InternalError("NYI");
+        if (operand.getKind().getStackKind() == Kind.Int) {
+            append(new SPARCBitManipulationOp(IPOPCNT, result, asAllocatable(operand)));
+        } else {
+            append(new SPARCBitManipulationOp(LPOPCNT, result, asAllocatable(operand)));
+        }
     }
 
     @Override
     public void emitBitScanForward(Variable result, Value operand) {
-        throw new InternalError("NYI");
+        append(new SPARCBitManipulationOp(BSF, result, asAllocatable(operand)));
     }
 
     @Override
     public void emitBitScanReverse(Variable result, Value operand) {
-        throw new InternalError("NYI");
+        if (operand.getKind().getStackKind() == Kind.Int) {
+            append(new SPARCBitManipulationOp(IBSR, result, asAllocatable(operand)));
+        } else {
+            append(new SPARCBitManipulationOp(LBSR, result, asAllocatable(operand)));
+        }
     }
 
     @Override
     public void emitMathAbs(Variable result, Variable input) {
-        throw new InternalError("NYI");
+        append(new BinaryRegConst(DAND, result, input, Constant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL))));
     }
 
     @Override
     public void emitMathSqrt(Variable result, Variable input) {
-        throw new InternalError("NYI");
+        append(new SPARCMathIntrinsicOp(SQRT, result, input));
     }
 
     @Override
     public void emitMathLog(Variable result, Variable input, boolean base10) {
-        throw new InternalError("NYI");
+        append(new SPARCMathIntrinsicOp(LOG, result, input));
     }
 
     @Override
     public void emitMathCos(Variable result, Variable input) {
-        throw new InternalError("NYI");
+        append(new SPARCMathIntrinsicOp(COS, result, input));
     }
 
     @Override
     public void emitMathSin(Variable result, Variable input) {
-        throw new InternalError("NYI");
+        append(new SPARCMathIntrinsicOp(SIN, result, input));
     }
 
     @Override
     public void emitMathTan(Variable result, Variable input) {
-        throw new InternalError("NYI");
+        append(new SPARCMathIntrinsicOp(TAN, result, input));
     }
 
     @Override
-    public void emitByteSwap(Variable result, Value operand) {
-        throw new InternalError("NYI");
+    public void emitByteSwap(Variable result, Value input) {
+        append(new SPARCByteSwapOp(result, input));
     }
 
     @Override
@@ -332,7 +462,9 @@
 
     @Override
     public Value emitAddress(StackSlot address) {
-        throw new InternalError("NYI");
+        Variable result = newVariable(target().wordKind);
+        append(new StackLoadAddressOp(result, address));
+        return result;
     }
 
     @Override
@@ -460,27 +592,83 @@
 
     @Override
     public Value emitUDiv(Value a, Value b, DeoptimizingNode deopting) {
-        throw new InternalError("NYI");
+        @SuppressWarnings("unused")
+        LIRFrameState state = state(deopting);
+        switch (a.getKind()) {
+            case Int:
+                // emitDivRem(IUDIV, a, b, state);
+                // return emitMove(RAX_I);
+            case Long:
+                // emitDivRem(LUDIV, a, b, state);
+                // return emitMove(RAX_L);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
     }
 
     @Override
     public Value emitURem(Value a, Value b, DeoptimizingNode deopting) {
-        throw new InternalError("NYI");
+        @SuppressWarnings("unused")
+        LIRFrameState state = state(deopting);
+        switch (a.getKind()) {
+            case Int:
+                // emitDivRem(IUREM, a, b, state);
+                // return emitMove(RDX_I);
+            case Long:
+                // emitDivRem(LUREM, a, b, state);
+                // return emitMove(RDX_L);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
     }
 
     @Override
     public Value emitAnd(Value a, Value b) {
-        throw new InternalError("NYI");
+        Variable result = newVariable(a.getKind());
+        switch (a.getKind()) {
+            case Int:
+                append(new Op2Stack(IAND, result, a, loadNonConst(b)));
+                break;
+            case Long:
+                append(new Op2Stack(LAND, result, a, loadNonConst(b)));
+                break;
+
+            default:
+                throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind());
+        }
+        return result;
     }
 
     @Override
     public Value emitOr(Value a, Value b) {
-        throw new InternalError("NYI");
+        Variable result = newVariable(a.getKind());
+        switch (a.getKind()) {
+            case Int:
+                append(new Op2Stack(IOR, result, a, loadNonConst(b)));
+                break;
+            case Long:
+                append(new Op2Stack(LOR, result, a, loadNonConst(b)));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind());
+        }
+        return result;
     }
 
     @Override
     public Value emitXor(Value a, Value b) {
-        throw new InternalError("NYI");
+        Variable result = newVariable(a.getKind());
+        switch (a.getKind()) {
+            case Int:
+                append(new Op2Stack(IXOR, result, a, loadNonConst(b)));
+                break;
+            case Long:
+                append(new Op2Stack(LXOR, result, a, loadNonConst(b)));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+        return result;
     }
 
     @Override
@@ -607,12 +795,15 @@
 
     @Override
     public void emitMembar(int barriers) {
-        throw new InternalError("NYI");
+        int necessaryBarriers = target.arch.requiredBarriers(barriers);
+        if (target.isMP && necessaryBarriers != 0) {
+            append(new MembarOp(necessaryBarriers));
+        }
     }
 
     @Override
     public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) {
-        throw new InternalError("NYI");
+        append(new ReturnOp(Value.ILLEGAL));
     }
 
     @Override
@@ -626,8 +817,14 @@
     }
 
     @Override
-    public void visitBreakpointNode(BreakpointNode i) {
-        throw new InternalError("NYI");
+    public void visitBreakpointNode(BreakpointNode node) {
+        JavaType[] sig = new JavaType[node.arguments().size()];
+        for (int i = 0; i < sig.length; i++) {
+            sig[i] = node.arguments().get(i).stamp().javaType(runtime);
+        }
+
+        Value[] parameters = visitInvokeArguments(frameMap.registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, null, sig, target(), false), node.arguments());
+        append(new SPARCBreakpointOp(parameters));
     }
 
     @Override
@@ -637,7 +834,8 @@
 
     @Override
     public void emitNullCheck(ValueNode v, DeoptimizingNode deopting) {
-        throw new InternalError("NYI");
+        assert v.kind() == Kind.Object;
+        append(new NullCheckOp(load(operand(v)), state(deopting)));
     }
 
     @Override
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java	Tue Jun 04 11:01:20 2013 +0200
@@ -27,11 +27,11 @@
 
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.internal.*;
-import com.oracle.graal.phases.*;
 
 /**
- * Implements the filter specified by the {@link GraalOptions#Dump}, {@link GraalOptions#Log},
- * {@link GraalOptions#Meter} and {@link GraalOptions#Time} options.
+ * Implements the filter specified by the {@link GraalDebugConfig#Dump},
+ * {@link GraalDebugConfig#Log}, {@link GraalDebugConfig#Meter} and {@link GraalDebugConfig#Time}
+ * options.
  * <p>
  * These options enable the associated debug facility if their filter matches the
  * {@linkplain DebugScope#getQualifiedName() name} of the {@linkplain Debug#currentScope() current
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Tue Jun 04 11:01:20 2013 +0200
@@ -38,6 +38,7 @@
 import com.oracle.graal.nodes.cfg.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.util.*;
+import com.oracle.graal.options.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.phases.common.*;
@@ -52,6 +53,11 @@
  */
 public class GraalCompiler {
 
+    // @formatter:off
+    @Option(help = "")
+    public static final OptionValue<Boolean> VerifyUsageWithEquals = new OptionValue<>(true);
+    // @formatter:on
+
     /**
      * Requests compilation of a given graph.
      * 
@@ -125,8 +131,10 @@
         } else {
             Debug.dump(graph, "initial state");
         }
-        new VerifyUsageWithEquals(runtime, Value.class).apply(graph);
-        new VerifyUsageWithEquals(runtime, Register.class).apply(graph);
+        if (VerifyUsageWithEquals.getValue()) {
+            new VerifyUsageWithEquals(runtime, Value.class).apply(graph);
+            new VerifyUsageWithEquals(runtime, Register.class).apply(graph);
+        }
 
         if (GraalOptions.OptCanonicalizer) {
             new CanonicalizerPhase.Instance(runtime, assumptions).apply(graph);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java	Tue Jun 04 11:01:20 2013 +0200
@@ -31,10 +31,33 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.util.*;
-import com.oracle.graal.phases.*;
+import com.oracle.graal.options.*;
 
 public class GraalDebugConfig implements DebugConfig {
 
+    // @formatter:off
+    @Option(help = "Enable scope-based debugging", name = "Debug")
+    public static final OptionValue<Boolean> DebugEnabled = new OptionValue<>(true);
+    @Option(help = "Scopes to be dumped")
+    public static final OptionValue<String> Dump = new OptionValue<>(null);
+    @Option(help = "Scopes to be metered")
+    public static final OptionValue<String> Meter = new OptionValue<>(null);
+    @Option(help = "Scopes to be timed")
+    public static final OptionValue<String> Time = new OptionValue<>(null);
+    @Option(help = "Scopes to be logged")
+    public static final OptionValue<String> Log = new OptionValue<>(null);
+    @Option(help = "Filters debug scope output by method name/pattern")
+    public static final OptionValue<String> MethodFilter = new OptionValue<>(null);
+    @Option(help = "")
+    public static final OptionValue<Boolean> PerThreadDebugValues = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Boolean> SummarizeDebugValues = new OptionValue<>(false);
+    @Option(help = "")
+    public static final OptionValue<Boolean> SummarizePerPhase = new OptionValue<>(false);
+    @Option(help = "Send Graal IR to dump handlers on error")
+    public static final OptionValue<Boolean> DumpOnError = new OptionValue<>(false);
+    // @formatter:on
+
     private final DebugFilter logFilter;
     private final DebugFilter meterFilter;
     private final DebugFilter timerFilter;
@@ -170,7 +193,7 @@
         for (Object o : Debug.context()) {
             if (o instanceof Graph) {
                 Debug.log("Context obj %s", o);
-                if (GraalOptions.DumpOnError) {
+                if (DumpOnError.getValue()) {
                     Debug.dump(o, "Exception graph");
                 } else {
                     Debug.log("Use -G:+DumpOnError to enable dumping of graphs on this error");
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Tue Jun 04 11:01:20 2013 +0200
@@ -203,7 +203,7 @@
         return value;
     }
 
-    protected LabelRef getLIRBlock(FixedNode b) {
+    public LabelRef getLIRBlock(FixedNode b) {
         Block result = lir.cfg.blockFor(b);
         int suxIndex = currentBlock.getSuccessors().indexOf(result);
         assert suxIndex != -1 : "Block not in successor list of current block";
@@ -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.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Tue Jun 04 11:01:20 2013 +0200
@@ -37,11 +37,17 @@
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.options.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 
 public final class CompilationTask implements Runnable, Comparable<CompilationTask> {
 
+    //@formatter:off
+    @Option(help = "")
+    public static final OptionValue<Integer> SlowQueueCutoff = new OptionValue<>(100000);
+    //@formatter:on
+
     public static final ThreadLocal<Boolean> withinEnqueue = new ThreadLocal<Boolean>() {
 
         @Override
@@ -109,7 +115,7 @@
             }
             inProgress = true;
             if (GraalOptions.DynamicCompilePriority) {
-                int threadPriority = priority < GraalOptions.SlowQueueCutoff ? Thread.NORM_PRIORITY : Thread.MIN_PRIORITY;
+                int threadPriority = priority < SlowQueueCutoff.getValue() ? Thread.NORM_PRIORITY : Thread.MIN_PRIORITY;
                 if (Thread.currentThread().getPriority() != threadPriority) {
                     Thread.currentThread().setPriority(threadPriority);
                 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java	Tue Jun 04 11:01:20 2013 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.hotspot;
 
+import static com.oracle.graal.compiler.GraalDebugConfig.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
 import java.io.*;
@@ -29,7 +30,6 @@
 
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.debug.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.printer.*;
 
 public final class CompilerThread extends Thread {
@@ -60,7 +60,7 @@
     @Override
     public void run() {
         GraalDebugConfig hotspotDebugConfig = null;
-        if (GraalOptions.Debug) {
+        if (DebugEnabled.getValue()) {
             PrintStream log = graalRuntime().getVMToCompiler().log();
             DebugEnvironment.initialize(log);
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java	Tue Jun 04 11:01:20 2013 +0200
@@ -27,10 +27,21 @@
 import java.util.*;
 
 import com.oracle.graal.hotspot.logging.*;
+import com.oracle.graal.options.*;
 import com.oracle.graal.phases.*;
 
 public class HotSpotOptions {
 
+    private static final Map<String, OptionProvider> options = new HashMap<>();
+
+    static {
+        ServiceLoader<OptionProvider> sl = ServiceLoader.loadInstalled(OptionProvider.class);
+        for (OptionProvider provider : sl) {
+            String name = provider.getName();
+            options.put(name, provider);
+        }
+    }
+
     // Called from VM code
     public static boolean setOption(String option) {
         if (option.length() == 0) {
@@ -61,6 +72,53 @@
             }
         }
 
+        OptionProvider optionProvider = options.get(fieldName);
+        if (optionProvider == null) {
+            return setOptionLegacy(option, fieldName, value, valueString);
+        }
+
+        Class<?> optionType = optionProvider.getType();
+
+        if (value == null) {
+            if (optionType == Boolean.TYPE || optionType == Boolean.class) {
+                Logger.info("Value for boolean option '" + fieldName + "' must use '-G:+" + fieldName + "' or '-G:-" + fieldName + "' format");
+                return false;
+            }
+
+            if (valueString == null) {
+                Logger.info("Value for option '" + fieldName + "' must use '-G:" + fieldName + "=<value>' format");
+                return false;
+            }
+
+            if (optionType == Float.class) {
+                value = Float.parseFloat(valueString);
+            } else if (optionType == Double.class) {
+                value = Double.parseDouble(valueString);
+            } else if (optionType == Integer.class) {
+                value = Integer.parseInt(valueString);
+            } else if (optionType == String.class) {
+                value = valueString;
+            }
+        } else {
+            if (optionType != Boolean.class) {
+                Logger.info("Value for option '" + fieldName + "' must use '-G:" + fieldName + "=<value>' format");
+                return false;
+            }
+        }
+
+        if (value != null) {
+            optionProvider.getOptionValue().setValue(value);
+            // Logger.info("Set option " + fieldName + " to " + value);
+        } else {
+            Logger.info("Wrong value \"" + valueString + "\" for option " + fieldName);
+            return false;
+        }
+
+        return true;
+    }
+
+    private static boolean setOptionLegacy(String option, String fieldName, Object v, String valueString) {
+        Object value = v;
         Field f;
         try {
             f = GraalOptions.class.getDeclaredField(fieldName);
@@ -116,10 +174,25 @@
         }
 
         return true;
+
     }
 
     private static void printFlags() {
         Logger.info("[Graal flags]");
+        SortedMap<String, OptionProvider> sortedOptions = new TreeMap<>(options);
+        for (Map.Entry<String, OptionProvider> e : sortedOptions.entrySet()) {
+            e.getKey();
+            OptionProvider opt = e.getValue();
+            Object value = opt.getOptionValue().getValue();
+            Logger.info(String.format("%9s %-40s = %-14s %s", opt.getType().getSimpleName(), e.getKey(), value, opt.getHelp()));
+        }
+
+        printFlagsLegacy();
+
+        System.exit(0);
+    }
+
+    protected static void printFlagsLegacy() {
         Field[] flags = GraalOptions.class.getDeclaredFields();
         Arrays.sort(flags, new Comparator<Field>() {
 
@@ -137,6 +210,5 @@
                 }
             }
         }
-        System.exit(0);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Tue Jun 04 11:01:20 2013 +0200
@@ -23,6 +23,7 @@
 
 package com.oracle.graal.hotspot.bridge;
 
+import static com.oracle.graal.compiler.GraalDebugConfig.*;
 import static com.oracle.graal.graph.UnsafeAccess.*;
 import static com.oracle.graal.hotspot.CompilationTask.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
@@ -46,10 +47,10 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.debug.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.options.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.phases.common.*;
-import com.oracle.graal.printer.*;
 import com.oracle.graal.replacements.*;
 
 /**
@@ -57,6 +58,38 @@
  */
 public class VMToCompilerImpl implements VMToCompiler {
 
+    //@formatter:off
+    @Option(help = "File to which compiler logging is sent")
+    private static final OptionValue<String> LogFile = new OptionValue<>(null);
+
+    @Option(help = "Use low priority compilation threads")
+    private static final OptionValue<Boolean> SlowCompileThreads = new OptionValue<>(false);
+
+    @Option(help = "Use priority-based compilation queue")
+    private static final OptionValue<Boolean> PriorityCompileQueue = new OptionValue<>(true);
+
+    @Option(help = "Print compilation queue activity periodically")
+    private static final OptionValue<Boolean> PrintQueue = new OptionValue<>(false);
+
+    @Option(help = "Time limit in milliseconds for bootstrap (-1 for no limit)")
+    private static final OptionValue<Integer> TimedBootstrap = new OptionValue<>(-1);
+
+    @Option(help = "Number of compilation threads to use")
+    private static final OptionValue<Integer> Threads = new OptionValue<Integer>(1) {
+
+        @Override
+        public Integer initialValue() {
+            return Runtime.getRuntime().availableProcessors();
+        }
+    };
+
+    @Option(help = "")
+    private static final OptionValue<Boolean> GenericDynamicCounters = new OptionValue<>(false);
+
+    @Option(help = "")
+    private static final OptionValue<String> BenchmarkDynamicCounters = new OptionValue<>(null);
+    //@formatter:on
+
     private final HotSpotGraalRuntime graalRuntime;
 
     public final HotSpotResolvedPrimitiveType typeBoolean;
@@ -117,35 +150,32 @@
         initMirror(typeLong, offset);
         initMirror(typeVoid, offset);
 
-        if (GraalOptions.LogFile != null) {
+        if (LogFile.getValue() != null) {
             try {
                 final boolean enableAutoflush = true;
-                log = new PrintStream(new FileOutputStream(GraalOptions.LogFile), enableAutoflush);
+                log = new PrintStream(new FileOutputStream(LogFile.getValue()), enableAutoflush);
             } catch (FileNotFoundException e) {
-                throw new RuntimeException("couldn't open log file: " + GraalOptions.LogFile, e);
+                throw new RuntimeException("couldn't open log file: " + LogFile.getValue(), e);
             }
         }
 
         TTY.initialize(log);
 
-        if (GraalOptions.Log == null && GraalOptions.Meter == null && GraalOptions.Time == null && GraalOptions.Dump == null) {
-            if (GraalOptions.MethodFilter != null) {
+        if (Log.getValue() == null && Meter.getValue() == null && Time.getValue() == null && Dump.getValue() == null) {
+            if (MethodFilter.getValue() != null) {
                 TTY.println("WARNING: Ignoring MethodFilter option since Log, Meter, Time and Dump options are all null");
             }
         }
 
         if (config.ciTime) {
-            quietMeterAndTime = (GraalOptions.Meter == null && GraalOptions.Time == null);
-            GraalOptions.Debug = true;
-            GraalOptions.Meter = "";
-            GraalOptions.Time = "";
+            quietMeterAndTime = (Meter.getValue() == null && Time.getValue() == null);
+            DebugEnabled.setValue(true);
+            Meter.setValue("");
+            Time.setValue("");
         }
 
-        if (GraalOptions.Debug) {
+        if (DebugEnabled.getValue()) {
             Debug.enable();
-            if (GraalOptions.DebugReplacements) {
-                DebugEnvironment.initialize(log);
-            }
         }
 
         // Install intrinsics.
@@ -173,21 +203,17 @@
 
         }
 
-        if (GraalOptions.DebugReplacements) {
-            phaseTransition("replacements");
-        }
+        // Create compilation queue.
+        BlockingQueue<Runnable> queue = PriorityCompileQueue.getValue() ? new PriorityBlockingQueue<Runnable>() : new LinkedBlockingQueue<Runnable>();
+        compileQueue = new ThreadPoolExecutor(Threads.getValue(), Threads.getValue(), 0L, TimeUnit.MILLISECONDS, queue, CompilerThread.FACTORY);
 
-        // Create compilation queue.
-        BlockingQueue<Runnable> queue = GraalOptions.PriorityCompileQueue ? new PriorityBlockingQueue<Runnable>() : new LinkedBlockingQueue<Runnable>();
-        compileQueue = new ThreadPoolExecutor(GraalOptions.Threads, GraalOptions.Threads, 0L, TimeUnit.MILLISECONDS, queue, CompilerThread.FACTORY);
-
-        if (GraalOptions.SlowCompileThreads) {
-            BlockingQueue<Runnable> slowQueue = GraalOptions.PriorityCompileQueue ? new PriorityBlockingQueue<Runnable>() : new LinkedBlockingQueue<Runnable>();
-            slowCompileQueue = new ThreadPoolExecutor(GraalOptions.Threads, GraalOptions.Threads, 0L, TimeUnit.MILLISECONDS, slowQueue, CompilerThread.LOW_PRIORITY_FACTORY);
+        if (SlowCompileThreads.getValue()) {
+            BlockingQueue<Runnable> slowQueue = PriorityCompileQueue.getValue() ? new PriorityBlockingQueue<Runnable>() : new LinkedBlockingQueue<Runnable>();
+            slowCompileQueue = new ThreadPoolExecutor(Threads.getValue(), Threads.getValue(), 0L, TimeUnit.MILLISECONDS, slowQueue, CompilerThread.LOW_PRIORITY_FACTORY);
         }
 
         // Create queue status printing thread.
-        if (GraalOptions.PrintQueue) {
+        if (PrintQueue.getValue()) {
             Thread t = new Thread() {
 
                 @Override
@@ -209,8 +235,8 @@
             t.start();
         }
 
-        if (GraalOptions.BenchmarkDynamicCounters != null) {
-            String[] arguments = GraalOptions.BenchmarkDynamicCounters.split(",");
+        if (BenchmarkDynamicCounters.getValue() != null) {
+            String[] arguments = BenchmarkDynamicCounters.getValue().split(",");
             if (arguments.length == 0 || (arguments.length % 3) != 0) {
                 throw new GraalInternalError("invalid arguments to BenchmarkDynamicCounters: (err|out),start,end,(err|out),start,end,... (~ matches multiple digits)");
             }
@@ -228,7 +254,7 @@
             DynamicCounterNode.excludedClassPrefix = "Lcom/oracle/graal/";
             DynamicCounterNode.enabled = true;
         }
-        if (GraalOptions.GenericDynamicCounters) {
+        if (GenericDynamicCounters.getValue()) {
             DynamicCounterNode.enabled = true;
         }
         compilerStartTime = System.nanoTime();
@@ -382,7 +408,7 @@
                     TTY.flush();
                 }
             }
-        } while ((System.currentTimeMillis() - startTime) <= GraalOptions.TimedBootstrap);
+        } while ((System.currentTimeMillis() - startTime) <= TimedBootstrap.getValue());
 
         phaseTransition("bootstrap");
 
@@ -413,7 +439,7 @@
     private static void shutdownCompileQueue(ThreadPoolExecutor queue) throws InterruptedException {
         if (queue != null) {
             queue.shutdown();
-            if (Debug.isEnabled() && GraalOptions.Dump != null) {
+            if (Debug.isEnabled() && Dump.getValue() != null) {
                 // Wait 2 seconds to flush out all graph dumps that may be of interest
                 queue.awaitTermination(2, TimeUnit.SECONDS);
             }
@@ -437,9 +463,9 @@
                 ArrayList<DebugValue> sortedValues = new ArrayList<>(debugValues);
                 Collections.sort(sortedValues);
 
-                if (GraalOptions.SummarizeDebugValues) {
+                if (SummarizeDebugValues.getValue()) {
                     printSummary(topLevelMaps, sortedValues);
-                } else if (GraalOptions.PerThreadDebugValues) {
+                } else if (PerThreadDebugValues.getValue()) {
                     for (DebugValueMap map : topLevelMaps) {
                         TTY.println("Showing the results for thread: " + map.getName());
                         map.group();
@@ -449,13 +475,13 @@
                 } else {
                     DebugValueMap globalMap = new DebugValueMap("Global");
                     for (DebugValueMap map : topLevelMaps) {
-                        if (GraalOptions.SummarizePerPhase) {
+                        if (SummarizePerPhase.getValue()) {
                             flattenChildren(map, globalMap);
                         } else {
                             globalMap.addChild(map);
                         }
                     }
-                    if (!GraalOptions.SummarizePerPhase) {
+                    if (!SummarizePerPhase.getValue()) {
                         globalMap.group();
                     }
                     globalMap.normalize();
@@ -471,7 +497,7 @@
         }
 
         SnippetCounter.printGroups(TTY.out().out());
-        if (GraalOptions.GenericDynamicCounters) {
+        if (GenericDynamicCounters.getValue()) {
             DynamicCounterNode.dump(System.out, (System.nanoTime() - compilerStartTime) / 1000000000d);
         }
     }
@@ -581,7 +607,7 @@
                         return true;
                     }
                 } else {
-                    if (GraalOptions.PriorityCompileQueue) {
+                    if (PriorityCompileQueue.getValue()) {
                         // normally compilation tasks will only be re-queued when they get a
                         // priority boost, so cancel the old task and add a new one
                         current.cancel();
@@ -604,7 +630,7 @@
             } else {
                 try {
                     method.setCurrentTask(task);
-                    if (GraalOptions.SlowCompileThreads && priority > GraalOptions.SlowQueueCutoff) {
+                    if (SlowCompileThreads.getValue() && priority > SlowQueueCutoff.getValue()) {
                         slowCompileQueue.execute(task);
                     } else {
                         compileQueue.execute(task);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Tue Jun 04 11:01:20 2013 +0200
@@ -313,6 +313,7 @@
 
     @Override
     public boolean isAssignableFrom(ResolvedJavaType other) {
+        assert other != null;
         if (other instanceof HotSpotResolvedObjectType) {
             HotSpotResolvedObjectType otherType = (HotSpotResolvedObjectType) other;
             return javaMirror.isAssignableFrom(otherType.javaMirror);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java	Tue Jun 04 11:01:20 2013 +0200
@@ -129,6 +129,7 @@
 
     @Override
     public boolean isAssignableFrom(ResolvedJavaType other) {
+        assert other != null;
         return other == this;
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java	Tue Jun 04 11:01:20 2013 +0200
@@ -77,7 +77,7 @@
     }
 
     private static boolean isCloneableType(ResolvedJavaType type, MetaAccessProvider metaAccess) {
-        return metaAccess.lookupJavaType(Cloneable.class).isAssignableFrom(type);
+        return type != null && metaAccess.lookupJavaType(Cloneable.class).isAssignableFrom(type);
     }
 
     private static ResolvedJavaType getConcreteType(ObjectStamp stamp, Assumptions assumptions) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Tue Jun 04 11:01:20 2013 +0200
@@ -260,7 +260,7 @@
             if (kind == Kind.Object) {
                 stamp = StampFactory.declared(type);
             } else {
-                stamp = StampFactory.forKind(kind);
+                stamp = StampFactory.forKind(type.getKind());
             }
             LocalNode local = builder.add(new LocalNode(i, stamp));
             locals[i] = local;
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java	Tue Jun 04 11:01:20 2013 +0200
@@ -82,7 +82,7 @@
             if (kind == Kind.Object && type instanceof ResolvedJavaType) {
                 stamp = StampFactory.declared((ResolvedJavaType) type);
             } else {
-                stamp = StampFactory.forKind(kind);
+                stamp = StampFactory.forKind(type.getKind());
             }
             LocalNode local = graph.unique(new LocalNode(index, stamp));
             storeLocal(javaIndex, local);
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Jun 04 11:01:20 2013 +0200
@@ -1107,8 +1107,11 @@
         }
         if (exact != null) {
             // either the holder class is exact, or the receiver object has an exact type
-            invokeDirect(exact.resolveMethod(target), args);
-            return;
+            ResolvedJavaMethod exactMethod = exact.resolveMethod(target);
+            if (exactMethod != null) {
+                invokeDirect(exactMethod, args);
+                return;
+            }
         }
         // devirtualization failed, produce an actual invokevirtual
         appendInvoke(invokeKind, target, args);
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java	Tue Jun 04 11:01:20 2013 +0200
@@ -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 Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Tue Jun 04 11:01:20 2013 +0200
@@ -41,10 +41,13 @@
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Or;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Sdivx;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Sll;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Sllx;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Srl;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Srlx;
 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;
@@ -56,83 +59,60 @@
 import com.oracle.graal.lir.LIRFrameState;
 import com.oracle.graal.lir.asm.TargetMethodAssembler;
 
+//@formatter:off
 public enum SPARCArithmetic {
-    IADD,
-    ISUB,
-    IMUL,
-    IDIV,
-    IDIVREM,
-    IREM,
-    IUDIV,
-    IUREM,
-    IAND,
-    IOR,
-    IXOR,
-    ISHL,
-    ISHR,
-    IUSHR,
-    LADD,
-    LSUB,
-    LMUL,
-    LDIV,
-    LDIVREM,
-    LREM,
-    LUDIV,
-    LUREM,
-    LAND,
-    LOR,
-    LXOR,
-    LSHL,
-    LSHR,
-    LUSHR,
-    FADD,
-    FSUB,
-    FMUL,
-    FDIV,
-    FREM,
-    FAND,
-    FOR,
-    FXOR,
-    DADD,
-    DSUB,
-    DMUL,
-    DDIV,
-    DREM,
-    DAND,
-    DOR,
-    DXOR,
-    INEG,
-    LNEG,
-    FNEG,
-    DNEG,
-    I2L,
-    L2I,
-    I2B,
-    I2C,
-    I2S,
-    F2D,
-    D2F,
-    I2F,
-    I2D,
-    F2I,
-    D2I,
-    L2F,
-    L2D,
-    F2L,
-    D2L,
-    MOV_I2F,
-    MOV_L2D,
-    MOV_F2I,
-    MOV_D2L;
+    // @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,
+    DADD, DSUB, DMUL, DDIV, DREM, DAND, DOR, DXOR,
+    INEG, LNEG, FNEG, DNEG,
+    I2L, L2I, I2B, I2C, I2S,
+    F2D, D2F,
+    I2F, I2D, F2I, D2I,
+    L2F, L2D, F2L, D2L,
+    MOV_I2F, MOV_L2D, MOV_F2I, MOV_D2L;
+
+    /**
+     * Binary operation with single source/destination operand and one constant.
+     */
+    public static class BinaryRegConst extends SPARCLIRInstruction {
+        @Opcode private final SPARCArithmetic opcode;
+        @Def({REG, HINT}) protected AllocatableValue result;
+        @Use({REG, STACK}) protected AllocatableValue x;
+        protected Constant y;
+
+        public BinaryRegConst(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x, Constant y) {
+            this.opcode = opcode;
+            this.result = result;
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+            SPARCMove.move(tasm, masm, result, x);
+            emit(tasm, masm, opcode, result, y, null);
+        }
+
+        @Override
+        public void verify() {
+            super.verify();
+            verifyKind(opcode, result, x, y);
+        }
+    }
 
     /**
      * Unary operation with separate source and destination operand.
      */
     public static class Unary2Op extends SPARCLIRInstruction {
 
-        @Opcode private final SPARCArithmetic opcode;
-        @Def({REG}) protected AllocatableValue result;
-        @Use({REG, STACK}) protected AllocatableValue x;
+        @Opcode
+        private final SPARCArithmetic opcode;
+        @Def({ REG })
+        protected AllocatableValue result;
+        @Use({ REG, STACK })
+        protected AllocatableValue x;
 
         public Unary2Op(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x) {
             this.opcode = opcode;
@@ -152,9 +132,12 @@
      */
     public static class Unary1Op extends SPARCLIRInstruction {
 
-        @Opcode private final SPARCArithmetic opcode;
-        @Def({REG, HINT}) protected AllocatableValue result;
-        @Use({REG, STACK}) protected AllocatableValue x;
+        @Opcode
+        private final SPARCArithmetic opcode;
+        @Def({ REG, HINT })
+        protected AllocatableValue result;
+        @Use({ REG, STACK })
+        protected AllocatableValue x;
 
         public Unary1Op(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x) {
             this.opcode = opcode;
@@ -170,9 +153,12 @@
 
     public static class Op1Stack extends SPARCLIRInstruction {
 
-        @Opcode private final SPARCArithmetic opcode;
-        @Def({REG, HINT}) protected Value result;
-        @Use({REG, STACK, CONST}) protected Value x;
+        @Opcode
+        private final SPARCArithmetic opcode;
+        @Def({ REG, HINT })
+        protected Value result;
+        @Use({ REG, STACK, CONST })
+        protected Value x;
 
         public Op1Stack(SPARCArithmetic opcode, Value result, Value x) {
             this.opcode = opcode;
@@ -188,10 +174,14 @@
 
     public static class Op2Stack extends SPARCLIRInstruction {
 
-        @Opcode private final SPARCArithmetic opcode;
-        @Def({REG, HINT}) protected Value result;
-        @Use({REG, STACK, CONST}) protected Value x;
-        @Alive({REG, STACK, CONST}) protected Value y;
+        @Opcode
+        private final SPARCArithmetic opcode;
+        @Def({ REG, HINT })
+        protected Value result;
+        @Use({ REG, STACK, CONST })
+        protected Value x;
+        @Alive({ REG, STACK, CONST })
+        protected Value y;
 
         public Op2Stack(SPARCArithmetic opcode, Value result, Value x, Value y) {
             this.opcode = opcode;
@@ -214,10 +204,14 @@
 
     public static class Op2Reg extends SPARCLIRInstruction {
 
-        @Opcode private final SPARCArithmetic opcode;
-        @Def({REG, HINT}) protected Value result;
-        @Use({REG, STACK, CONST}) protected Value x;
-        @Alive({REG, CONST}) protected Value y;
+        @Opcode
+        private final SPARCArithmetic opcode;
+        @Def({ REG, HINT })
+        protected Value result;
+        @Use({ REG, STACK, CONST })
+        protected Value x;
+        @Alive({ REG, CONST })
+        protected Value y;
 
         public Op2Reg(SPARCArithmetic opcode, Value result, Value x, Value y) {
             this.opcode = opcode;
@@ -240,10 +234,14 @@
 
     public static class ShiftOp extends SPARCLIRInstruction {
 
-        @Opcode private final SPARCArithmetic opcode;
-        @Def({REG, HINT}) protected Value result;
-        @Use({REG, STACK, CONST}) protected Value x;
-        @Alive({REG, CONST}) protected Value y;
+        @Opcode
+        private final SPARCArithmetic opcode;
+        @Def({ REG, HINT })
+        protected Value result;
+        @Use({ REG, STACK, CONST })
+        protected Value x;
+        @Alive({ REG, CONST })
+        protected Value y;
 
         public ShiftOp(SPARCArithmetic opcode, Value result, Value x, Value y) {
             this.opcode = opcode;
@@ -268,192 +266,210 @@
     @SuppressWarnings("unused")
     protected static void emit(SPARCAssembler masm, SPARCArithmetic opcode, Value result) {
         switch (opcode) {
-            case L2I:
-                new Sra(masm, asLongReg(result), 0, asIntReg(result));
-                break;
-            case I2C:
-                new Sll(masm, asIntReg(result), 16, asIntReg(result));
-                new Srl(masm, asIntReg(result), 16, asIntReg(result));
-                break;
-            default:
-                throw GraalInternalError.shouldNotReachHere("missing: " + opcode);
+        case L2I:
+            new And(masm, asIntReg(result), -1, asIntReg(result));
+            break;
+        case I2C:
+            new Sll(masm, asIntReg(result), 16, asIntReg(result));
+            new Srl(masm, asIntReg(result), 16, asIntReg(result));
+            break;
+        default:
+            throw GraalInternalError.shouldNotReachHere("missing: " + opcode);
         }
     }
 
     @SuppressWarnings("unused")
-    public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info) {
+    public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm,
+            SPARCArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info) {
         int exceptionOffset = -1;
         if (isConstant(src1)) {
             switch (opcode) {
-                case ISUB:
-                    assert is_simm13(tasm.asIntConst(src1));
-                    new Add(masm, asIntReg(src2), -(tasm.asIntConst(src1)), asIntReg(dst));
-                    break;
-                case IAND:
-                    throw new InternalError("NYI");
-                case IDIV:
-                    assert is_simm13(tasm.asIntConst(src1));
-                    throw new InternalError("NYI");
-                    // new Sdivx(masm, asIntReg(src1), asIntReg(src2),
-                    // asIntReg(dst));
-                case FSUB:
-                    throw new InternalError("NYI");
-                case FDIV:
-                    throw new InternalError("NYI");
-                case DSUB:
-                    throw new InternalError("NYI");
-                case DDIV:
-                    throw new InternalError("NYI");
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
+            case ISUB:
+                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 isSimm13(tasm.asIntConst(src1));
+                throw new InternalError("NYI");
+                // new Sdivx(masm, asIntReg(src1), asIntReg(src2),
+                // asIntReg(dst));
+            case FSUB:
+                throw new InternalError("NYI");
+            case FDIV:
+                throw new InternalError("NYI");
+            case DSUB:
+                throw new InternalError("NYI");
+            case DDIV:
+                throw new InternalError("NYI");
+            default:
+                throw GraalInternalError.shouldNotReachHere();
             }
         } else if (isConstant(src2)) {
             switch (opcode) {
-                case IADD:
-                    assert is_simm13(tasm.asIntConst(src2));
-                    new Add(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
-                    break;
-                case ISUB:
-                    assert is_simm13(tasm.asIntConst(src2));
-                    new Sub(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
-                    break;
-                case IMUL:
-                    assert is_simm13(tasm.asIntConst(src2));
-                    new Mulx(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
-                    break;
-                case IAND:
-                    assert is_simm13(tasm.asIntConst(src2));
-                    new And(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
-                    break;
-                case ISHL:
-                    assert is_simm13(tasm.asIntConst(src2));
-                    new Sll(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
-                    break;
-                case ISHR:
-                    assert is_simm13(tasm.asIntConst(src2));
-                    new Srl(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
-                    break;
-                case IUSHR:
-                    assert is_simm13(tasm.asIntConst(src2));
-                    new Sra(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
-                    break;
-                case IXOR:
-                    throw new InternalError("NYI");
-                case LXOR:
-                    throw new InternalError("NYI");
-                case LUSHR:
-                    throw new InternalError("NYI");
-                case FADD:
-                    throw new InternalError("NYI");
-                case FMUL:
-                    throw new InternalError("NYI");
-                case FDIV:
-                    throw new InternalError("NYI");
-                case DADD:
-                    throw new InternalError("NYI");
-                case DMUL:
-                    throw new InternalError("NYI");
-                case DDIV:
-                    throw new InternalError("NYI");
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
+            case IADD:
+                assert isSimm13(tasm.asIntConst(src2));
+                new Add(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
+                break;
+            case ISUB:
+                assert isSimm13(tasm.asIntConst(src2));
+                new Sub(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
+                break;
+            case IMUL:
+                assert isSimm13(tasm.asIntConst(src2));
+                new Mulx(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
+                break;
+            case IAND:
+                assert isSimm13(tasm.asIntConst(src2));
+                new And(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
+                break;
+            case ISHL:
+                assert isSimm13(tasm.asIntConst(src2));
+                new Sll(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
+                break;
+            case ISHR:
+                assert isSimm13(tasm.asIntConst(src2));
+                new Srl(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
+                break;
+            case IUSHR:
+                assert isSimm13(tasm.asIntConst(src2));
+                new Sra(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
+                break;
+            case IXOR:
+                assert isSimm13(tasm.asIntConst(src2));
+                new Xor(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst));
+                break;
+            case LXOR:
+                assert isSimm13(tasm.asIntConst(src2));
+                new Add(masm, asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst));
+                break;
+            case LUSHR:
+                throw new InternalError("NYI");
+            case FADD:
+                throw new InternalError("NYI");
+            case FMUL:
+                throw new InternalError("NYI");
+            case FDIV:
+                throw new InternalError("NYI");
+            case DADD:
+                throw new InternalError("NYI");
+            case DMUL:
+                throw new InternalError("NYI");
+            case DDIV:
+                throw new InternalError("NYI");
+            default:
+                throw GraalInternalError.shouldNotReachHere();
             }
         } else {
             switch (opcode) {
-                case IADD:
-                    new Add(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
-                    break;
-                case ISUB:
-                    new Sub(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
-                    break;
-                case IMUL:
-                    new Mulx(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
-                    break;
-                case IDIV:
-                    new Sdivx(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
-                    break;
-                case IAND:
-                    new And(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
-                    break;
-                case IOR:
-                    new Or(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
-                    break;
-                case IXOR:
-                    new Xor(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
-                    break;
-                case ISHL:
-                    new Sll(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
-                    break;
-                case ISHR:
-                    new Srl(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
-                    break;
-                case IUSHR:
-                    new Sra(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
-                    break;
-                case IREM:
-                    throw new InternalError("NYI");
-                case LADD:
-                    new Add(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
-                    break;
-                case LSUB:
-                    new Sub(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
-                    break;
-                case LMUL:
-                    new Mulx(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
-                    break;
-                case LDIV:
-                    new Sdivx(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
-                    break;
-                case LAND:
-                    new And(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
-                    break;
-                case LOR:
-                    new Or(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
-                    break;
-                case LXOR:
-                    new Xor(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
-                    break;
-                case LSHL:
-                    new Sll(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
-                    break;
-                case LSHR:
-                    new Srl(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
-                    break;
-                case LUSHR:
-                    new Sra(masm, asLongReg(src1), asLongReg(src2), asIntReg(dst));
-                    break;
-                case LREM:
-                    throw new InternalError("NYI");
-                case FADD:
-                    new Fadds(masm, asFloatReg(src1), asFloatReg(src2), asFloatReg(dst));
-                    break;
-                case FSUB:
-                    new Fsubs(masm, asFloatReg(src1), asFloatReg(src2), asFloatReg(dst));
-                    break;
-                case FMUL:
-                    new Fmuls(masm, asFloatReg(src1), asFloatReg(src2), asFloatReg(dst));
-                    break;
-                case FDIV:
-                    new Fdivs(masm, asFloatReg(src1), asFloatReg(src2), asFloatReg(dst));
-                    break;
-                case FREM:
-                    throw new InternalError("NYI");
-                case DADD:
-                    new Faddd(masm, asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst));
-                    break;
-                case DSUB:
-                    new Fsubd(masm, asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst));
-                    break;
-                case DMUL:
-                    new Fmuld(masm, asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst));
-                    break;
-                case DDIV:
-                    new Fdivd(masm, asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst));
-                    break;
-                case DREM:
-                    throw new InternalError("NYI");
-                default:
-                    throw GraalInternalError.shouldNotReachHere("missing: " + opcode);
+            case IADD:
+                new Add(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
+                break;
+            case ISUB:
+                new Sub(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
+                break;
+            case IMUL:
+                new Mulx(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
+                break;
+            case IDIV:
+                new Sdivx(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
+                break;
+            case IAND:
+                new And(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
+                break;
+            case IOR:
+                new Or(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
+                break;
+            case IXOR:
+                new Xor(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
+                break;
+            case ISHL:
+                new Sll(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
+                break;
+            case ISHR:
+                new Srl(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
+                break;
+            case IUSHR:
+                new Sra(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst));
+                break;
+            case IREM:
+                throw new InternalError("NYI");
+            case LADD:
+                new Add(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
+                break;
+            case LSUB:
+                new Sub(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
+                break;
+            case LMUL:
+                new Mulx(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
+                break;
+            case LDIV:
+                new Sdivx(masm, asLongReg(src1), asLongReg(src2),
+                        asLongReg(dst));
+                break;
+            case LAND:
+                new And(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
+                break;
+            case LOR:
+                new Or(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
+                break;
+            case LXOR:
+                new Xor(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
+                break;
+            case LSHL:
+                new Sll(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
+                break;
+            case LSHR:
+                new Srl(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst));
+                break;
+            case LUSHR:
+                new Sra(masm, asLongReg(src1), asIntReg(src2), asLongReg(dst));
+                break;
+            case LDIVREM:
+            case LUDIV:
+            case LUREM:
+            case LREM:
+                throw new InternalError("NYI");
+            case FADD:
+                new Fadds(masm, asFloatReg(src1), asFloatReg(src2),
+                        asFloatReg(dst));
+                break;
+            case FSUB:
+                new Fsubs(masm, asFloatReg(src1), asFloatReg(src2),
+                        asFloatReg(dst));
+                break;
+            case FMUL:
+                new Fmuls(masm, asFloatReg(src1), asFloatReg(src2),
+                        asFloatReg(dst));
+                break;
+            case FDIV:
+                new Fdivs(masm, asFloatReg(src1), asFloatReg(src2),
+                        asFloatReg(dst));
+                break;
+            case FREM:
+                throw new InternalError("NYI");
+            case DADD:
+                new Faddd(masm, asDoubleReg(src1), asDoubleReg(src2),
+                        asDoubleReg(dst));
+                break;
+            case DSUB:
+                new Fsubd(masm, asDoubleReg(src1), asDoubleReg(src2),
+                        asDoubleReg(dst));
+                break;
+            case DMUL:
+                new Fmuld(masm, asDoubleReg(src1), asDoubleReg(src2),
+                        asDoubleReg(dst));
+                break;
+            case DDIV:
+                new Fdivd(masm, asDoubleReg(src1), asDoubleReg(src2),
+                        asDoubleReg(dst));
+                break;
+            case DREM:
+                throw new InternalError("NYI");
+            default:
+                throw GraalInternalError.shouldNotReachHere("missing: "
+                        + opcode);
             }
         }
 
@@ -464,41 +480,51 @@
     }
 
     @SuppressWarnings("unused")
-    public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm, SPARCArithmetic opcode, Value dst, Value src, LIRFrameState info) {
+    public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm,
+            SPARCArithmetic opcode, Value dst, Value src, LIRFrameState info) {
         int exceptionOffset = -1;
         if (isRegister(src)) {
             switch (opcode) {
-                case I2L:
-                    new Sra(masm, asIntReg(src), 0, asLongReg(dst));
-                    break;
-                case I2B:
-                    new Sll(masm, asIntReg(src), 24, asIntReg(src));
-                    new Srl(masm, asIntReg(dst), 24, asIntReg(src));
-                    break;
-                case I2F:
-                    new Fstoi(masm, asIntReg(src), asFloatReg(dst));
-                    break;
-                case I2D:
-                    new Fdtoi(masm, asIntReg(src), asDoubleReg(dst));
-                    break;
-                case FNEG:
-                    new Fnegs(masm, asFloatReg(src), asFloatReg(dst));
-                    break;
-                case DNEG:
-                    new Fnegd(masm, asDoubleReg(src), asDoubleReg(dst));
-                    break;
-                default:
-                    throw GraalInternalError.shouldNotReachHere("missing: " + opcode);
+            case I2L:
+                new Sra(masm, asIntReg(src), 0, asLongReg(dst));
+                break;
+            case I2B:
+                new Sll(masm, asIntReg(src), 24, asIntReg(src));
+                new Srl(masm, asIntReg(dst), 24, asIntReg(src));
+                break;
+            case I2F:
+                new Fstoi(masm, asIntReg(src), asFloatReg(dst));
+                break;
+            case I2D:
+                new Fdtoi(masm, asIntReg(src), asDoubleReg(dst));
+                break;
+            case FNEG:
+                new Fnegs(masm, asFloatReg(src), asFloatReg(dst));
+                break;
+            case DNEG:
+                new Fnegd(masm, asDoubleReg(src), asDoubleReg(dst));
+                break;
+            case LSHL:
+                new Sllx(masm, asLongReg(dst), asIntReg(src), asLongReg(dst));
+                break;
+            case LSHR:
+                new Srlx(masm, asLongReg(dst), asIntReg(src), asLongReg(dst));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere("missing: "
+                        + opcode);
             }
         } else if (isConstant(src)) {
             switch (opcode) {
-                default:
-                    throw GraalInternalError.shouldNotReachHere("missing: " + opcode);
+            default:
+                throw GraalInternalError.shouldNotReachHere("missing: "
+                        + opcode);
             }
         } else {
             switch (opcode) {
-                default:
-                    throw GraalInternalError.shouldNotReachHere("missing: " + opcode);
+            default:
+                throw GraalInternalError.shouldNotReachHere("missing: "
+                        + opcode);
             }
         }
 
@@ -508,19 +534,72 @@
         }
     }
 
-    private static final int max13 = ((1 << 12) - 1);
-    private static final int min13 = -(1 << 12);
+    private static void verifyKind(SPARCArithmetic opcode, Value result, Value x, Value y) {
+        Kind rk;
+        Kind xk;
+        Kind yk;
+        Kind xsk;
+        Kind ysk;
 
-    private static boolean is_simm13(int src) {
-        return min13 <= src && src <= max13;
-    }
+        switch (opcode) {
+        case IADD:
+        case ISUB:
+        case IMUL:
+        case IDIV:
+        case IREM:
+        case IAND:
+        case IOR:
+        case IXOR:
+        case ISHL:
+        case ISHR:
+        case IUSHR:
+            rk = result.getKind();
+            xsk = x.getKind().getStackKind();
+            ysk = y.getKind().getStackKind();
 
-    private static void verifyKind(SPARCArithmetic opcode, Value result, Value x, Value y) {
-        if (((opcode.name().startsWith("I") && result.getKind() == Kind.Int && x.getKind().getStackKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) ||
-                        (opcode.name().startsWith("L") && result.getKind() == Kind.Long && x.getKind() == Kind.Long && y.getKind() == Kind.Long) ||
-                        (opcode.name().startsWith("F") && result.getKind() == Kind.Float && x.getKind() == Kind.Float && y.getKind() == Kind.Float) || (opcode.name().startsWith("D") &&
-                        result.getKind() == Kind.Double && x.getKind() == Kind.Double && y.getKind() == Kind.Double)) == false) {
-            throw GraalInternalError.shouldNotReachHere("opcode: " + opcode.name() + " x: " + x.getKind() + " y: " + y.getKind());
+            assert rk == Kind.Int && xsk == Kind.Int && ysk == Kind.Int;
+            break;
+        case LADD:
+        case LSUB:
+        case LMUL:
+        case LDIV:
+        case LREM:
+        case LAND:
+        case LOR:
+        case LXOR:
+        case LSHL:
+        case LSHR:
+        case LUSHR:
+            rk = result.getKind();
+            xk = x.getKind();
+            yk = y.getKind();
+
+            assert rk == Kind.Long && xk == Kind.Long && yk == Kind.Long;
+            break;
+        case FADD:
+        case FSUB:
+        case FMUL:
+        case FDIV:
+        case FREM:
+            rk = result.getKind();
+            xk = x.getKind();
+            yk = y.getKind();
+
+            assert rk == Kind.Float && xk == Kind.Float && yk == Kind.Float;
+            break;
+        case DADD:
+        case DSUB:
+        case DMUL:
+        case DDIV:
+        case DREM:
+            rk = result.getKind();
+            xk = x.getKind();
+            yk = y.getKind();
+
+            assert rk == Kind.Double && xk == Kind.Double && yk == Kind.Double;
+            break;
+        default:
+            throw new InternalError("NYI: " + opcode);
         }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Tue Jun 04 11:01:20 2013 +0200
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.lir.sparc;
+
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Popc;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Srl;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.isSimm13;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.sparc.SPARC;
+
+public class SPARCBitManipulationOp extends SPARCLIRInstruction {
+
+    public enum IntrinsicOpcode {
+        IPOPCNT, LPOPCNT, IBSR, LBSR, BSF;
+    }
+
+    @Opcode private final IntrinsicOpcode opcode;
+    @Def protected AllocatableValue result;
+    @Use({OperandFlag.REG, OperandFlag.STACK}) protected AllocatableValue input;
+
+    public SPARCBitManipulationOp(IntrinsicOpcode opcode, AllocatableValue result, AllocatableValue input) {
+        this.opcode = opcode;
+        this.result = result;
+        this.input = input;
+    }
+
+    @Override
+    @SuppressWarnings("unused")
+    public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        Register dst = ValueUtil.asIntReg(result);
+        if (ValueUtil.isRegister(input)) {
+            Register src = ValueUtil.asRegister(input);
+            switch (opcode) {
+                case IPOPCNT:
+                    // clear upper word for 64 bit POPC
+                    new Srl(masm, src, SPARC.g0, dst);
+                    new Popc(masm, src, dst);
+                    break;
+                case LPOPCNT:
+                    new Popc(masm, src, dst);
+                    break;
+                case BSF:  // masm.bsfq(dst, src);
+                case IBSR:  // masm.bsrl(dst, src);
+                case LBSR:  // masm.bsrq(dst, src);
+                default:
+                    throw GraalInternalError.shouldNotReachHere("missing: " + opcode);
+
+            }
+        } else if (ValueUtil.isConstant(input) && isSimm13(tasm.asIntConst(input))) {
+            switch (opcode) {
+                case IPOPCNT:
+                    new Popc(masm, tasm.asIntConst(input), dst);
+                    break;
+                case LPOPCNT:
+                    new Popc(masm, tasm.asIntConst(input), dst);
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere("missing: " + opcode);
+            }
+        } else {
+            SPARCAddress src = (SPARCAddress) tasm.asAddress(input);
+            switch (opcode) {
+                case IPOPCNT:
+                    // masm.popcntl(dst, src);
+                    break;
+                case LPOPCNT:
+                    // masm.popcntq(dst, src);
+                    break;
+                case BSF:
+                    // masm.bsfq(dst, src);
+                    break;
+                case IBSR:
+                    // masm.bsrl(dst, src);
+                    break;
+                case LBSR:
+                    // masm.bsrq(dst, src);
+                    break;
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java	Tue Jun 04 11:01:20 2013 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.lir.sparc;
+
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.sparc.SPARCAssembler;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Trap;
+import com.oracle.graal.lir.LIRInstruction.*;
+import com.oracle.graal.lir.asm.*;
+
+/**
+ * Emits a breakpoint.
+ */
+@Opcode("BREAKPOINT")
+public class SPARCBreakpointOp extends SPARCLIRInstruction {
+
+    // historical - from hotspot src/cpu/sparc/vm
+    // <sys/trap.h> promises that the system will not use traps 16-31
+    // We want to use ST_BREAKPOINT here, but the debugger is confused by it.
+    public static final int ST_RESERVED_FOR_USER_0 = 0x10;
+
+    /**
+     * A set of values loaded into the Java ABI parameter locations (for inspection by a debugger).
+     */
+    @Use({REG, STACK}) protected Value[] parameters;
+
+    public SPARCBreakpointOp(Value[] parameters) {
+        this.parameters = parameters;
+    }
+
+    @Override
+    @SuppressWarnings("unused")
+    public void emitCode(TargetMethodAssembler tasm, SPARCAssembler asm) {
+        new Trap(asm, ST_RESERVED_FOR_USER_0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Tue Jun 04 11:01:20 2013 +0200
@@ -0,0 +1,51 @@
+/*
+ * 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 com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.lir.LIRInstruction.Opcode;
+import com.oracle.graal.lir.asm.*;
+
+@Opcode("BSWAP")
+public class SPARCByteSwapOp extends SPARCLIRInstruction {
+
+    @Def({OperandFlag.REG, OperandFlag.HINT}) protected Value result;
+    @Use protected Value input;
+
+    public SPARCByteSwapOp(Value result, Value input) {
+        this.result = result;
+        this.input = input;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        SPARCMove.move(tasm, masm, result, input);
+        switch (input.getKind()) {
+        // case Int:
+        // masm.bswapl(ValueUtil.asIntReg(result));
+        // case Long:
+        // masm.bswapq(ValueUtil.asLongReg(result));
+        }
+    }
+}
--- /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 Jun 04 11:01:20 2013 +0200
@@ -0,0 +1,137 @@
+/*
+ * 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.asm.sparc.SPARCAssembler.isSimm13;
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.sparc.SPARCAssembler;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.asm.*;
+
+//@formatter:off
+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;
+
+        public CompareOp(SPARCCompare opcode, Value x, Value y) {
+            this.opcode = opcode;
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+            emit(tasm, masm, opcode, 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);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm, SPARCCompare opcode, Value x, Value y) {
+        if (isRegister(y)) {
+            switch (opcode) {
+                case ICMP:
+                    new Cmp(masm, asIntReg(x), asIntReg(y));
+                    break;
+                case LCMP:
+                    new Cmp(masm, asLongReg(x), asLongReg(y));
+                    break;
+                case ACMP:
+                    // masm.cmpptr(asObjectReg(x), asObjectReg(y));
+                    break;
+                case FCMP:
+                    // masm.ucomiss(asFloatReg(x), asFloatReg(y));
+                    break;
+                case DCMP:
+                    // masm.ucomisd(asDoubleReg(x), asDoubleReg(y));
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        } else if (isConstant(y)) {
+            switch (opcode) {
+                case ICMP:
+                    assert isSimm13(tasm.asIntConst(y));
+                    new Cmp(masm, asIntReg(x), tasm.asIntConst(y));
+                    break;
+                case LCMP:
+                    assert isSimm13(tasm.asIntConst(y));
+                    new Cmp(masm, asLongReg(x), tasm.asIntConst(y));
+                    break;
+                case ACMP:
+                    if (((Constant) y).isNull()) {
+                        // masm.cmpq(asObjectReg(x), 0);
+                        break;
+                    } else {
+                        throw GraalInternalError.shouldNotReachHere("Only null object constants are allowed in comparisons");
+                    }
+                case FCMP:
+                    // masm.ucomiss(asFloatReg(x), (AMD64Address) tasm.asFloatConstRef(y));
+                    break;
+                case DCMP:
+                    // masm.ucomisd(asDoubleReg(x), (AMD64Address) tasm.asDoubleConstRef(y));
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        } else {
+            switch (opcode) {
+                case ICMP:
+                    // masm.cmpl(asIntReg(x), (AMD64Address) tasm.asIntAddr(y)); 
+                    break;
+                case LCMP:
+                    // masm.cmpq(asLongReg(x), (AMD64Address) tasm.asLongAddr(y));
+                    break;
+                case ACMP:
+                    // masm.cmpptr(asObjectReg(x), (AMD64Address) tasm.asObjectAddr(y));
+                    break;
+                case FCMP:
+                    // masm.ucomiss(asFloatReg(x), (AMD64Address) tasm.asFloatAddr(y));
+                    break;
+                case DCMP:
+                    // masm.ucomisd(asDoubleReg(x), (AMD64Address) tasm.asDoubleAddr(y)); 
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+    }
+}
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Tue Jun 04 11:01:20 2013 +0200
@@ -31,20 +31,195 @@
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.asm.sparc.SPARCAssembler.CC;
+import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Bpe;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Subcc;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.LIRInstruction.*;
 import com.oracle.graal.lir.StandardOp.*;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.nodes.calc.Condition;
 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();
+        }
+    }
+
+    @Opcode("CMOVE")
+    public static class CondMoveOp extends SPARCLIRInstruction {
+
+        @Def({REG, HINT}) protected Value result;
+        @Alive({REG}) protected Value trueValue;
+        @Use({REG, STACK, CONST}) protected Value falseValue;
+
+        private final ConditionFlag condition;
+
+        public CondMoveOp(Variable result, Condition condition, Variable trueValue, Value falseValue) {
+            this.result = result;
+            this.condition = intCond(condition);
+            this.trueValue = trueValue;
+            this.falseValue = falseValue;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+            cmove(tasm, masm, result, false, condition, false, trueValue, falseValue);
+        }
+    }
+
+    @Opcode("CMOVE")
+    public static class FloatCondMoveOp extends SPARCLIRInstruction {
+
+        @Def({REG}) protected Value result;
+        @Alive({REG}) protected Value trueValue;
+        @Alive({REG}) protected Value falseValue;
+        private final ConditionFlag condition;
+        private final boolean unorderedIsTrue;
+
+        public FloatCondMoveOp(Variable result, Condition condition, boolean unorderedIsTrue, Variable trueValue, Variable falseValue) {
+            this.result = result;
+            this.condition = floatCond(condition);
+            this.unorderedIsTrue = unorderedIsTrue;
+            this.trueValue = trueValue;
+            this.falseValue = falseValue;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+            cmove(tasm, masm, result, true, condition, unorderedIsTrue, trueValue, falseValue);
+        }
+    }
+
+    private static void cmove(TargetMethodAssembler tasm, SPARCAssembler masm, Value result, boolean isFloat, ConditionFlag condition, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
+        // check that we don't overwrite an input operand before it is used.
+        assert !result.equals(trueValue);
+
+        SPARCMove.move(tasm, masm, result, falseValue);
+        cmove(tasm, masm, result, condition, trueValue);
+
+        if (isFloat) {
+            if (unorderedIsTrue && !trueOnUnordered(condition)) {
+                // cmove(tasm, masm, result, ConditionFlag.Parity, trueValue);
+            } else if (!unorderedIsTrue && trueOnUnordered(condition)) {
+                // cmove(tasm, masm, result, ConditionFlag.Parity, falseValue);
+            }
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private static void cmove(TargetMethodAssembler tasm, SPARCAssembler masm, Value result, ConditionFlag cond, Value other) {
+        if (isRegister(other)) {
+            assert !asRegister(other).equals(asRegister(result)) : "other already overwritten by previous move";
+            switch (other.getKind()) {
+                case Int:
+                    // masm.cmovl(cond, asRegister(result), asRegister(other));
+                    break;
+                case Long:
+                    // masm.cmovq(cond, asRegister(result), asRegister(other));
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        } else {
+            SPARCAddress addr = (SPARCAddress) tasm.asAddress(other);
+            switch (other.getKind()) {
+                case Int:
+                    // masm.cmovl(cond, asRegister(result), addr);
+                    break;
+                case Long:
+                    // masm.cmovq(cond, asRegister(result), addr);
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+    }
+
+    private static ConditionFlag intCond(Condition cond) {
+        switch (cond) {
+            case EQ:
+                return ConditionFlag.Equal;
+            case NE:
+                return ConditionFlag.NotEqual;
+            case LT:
+                return ConditionFlag.Less;
+            case LE:
+                return ConditionFlag.LessEqual;
+            case GE:
+                return ConditionFlag.GreaterEqual;
+            case GT:
+                return ConditionFlag.Greater;
+            case BE:
+            case AE:
+            case AT:
+            case BT:
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    private static ConditionFlag floatCond(Condition cond) {
+        switch (cond) {
+            case EQ:
+                return ConditionFlag.Equal;
+            case NE:
+                return ConditionFlag.NotEqual;
+            case LT:
+            case LE:
+            case GE:
+            case GT:
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    private static boolean trueOnUnordered(ConditionFlag condition) {
+        switch (condition) {
+            case NotEqual:
+            case Less:
+                return false;
+            case Equal:
+            case GreaterEqual:
+                return true;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
     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 +234,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 +281,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());
@@ -139,18 +306,93 @@
         }
     }
 
+    public static class SwitchRangesOp extends SPARCLIRInstruction implements FallThroughOp {
+
+        private final LabelRef[] keyTargets;
+        private LabelRef defaultTarget;
+        private final int[] lowKeys;
+        private final int[] highKeys;
+        @Alive protected Value key;
+
+        public SwitchRangesOp(int[] lowKeys, int[] highKeys, LabelRef[] keyTargets, LabelRef defaultTarget, Value key) {
+            this.lowKeys = lowKeys;
+            this.highKeys = highKeys;
+            this.keyTargets = keyTargets;
+            this.defaultTarget = defaultTarget;
+            this.key = key;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+            assert isSorted(lowKeys) && isSorted(highKeys);
+
+            @SuppressWarnings("unused")
+            Label actualDefaultTarget = defaultTarget == null ? new Label() : defaultTarget.label();
+            int prevHighKey = 0;
+            boolean skipLowCheck = false;
+            for (int i = 0; i < lowKeys.length; i++) {
+                int lowKey = lowKeys[i];
+                int highKey = highKeys[i];
+                if (lowKey == highKey) {
+                    // masm.cmpl(asIntReg(key), lowKey);
+                    // masm.jcc(ConditionFlag.Equal, keyTargets[i].label());
+                    skipLowCheck = false;
+                } else {
+                    if (!skipLowCheck || (prevHighKey + 1) != lowKey) {
+                        // masm.cmpl(asIntReg(key), lowKey);
+                        // masm.jcc(ConditionFlag.Less, actualDefaultTarget);
+                    }
+                    // masm.cmpl(asIntReg(key), highKey);
+                    // masm.jcc(ConditionFlag.LessEqual, keyTargets[i].label());
+                    skipLowCheck = true;
+                }
+                prevHighKey = highKey;
+            }
+            if (defaultTarget != null) {
+                // masm.jmp(defaultTarget.label());
+            } else {
+                // masm.bind(actualDefaultTarget);
+                // masm.hlt();
+            }
+        }
+
+        @Override
+        protected void verify() {
+            super.verify();
+            assert lowKeys.length == keyTargets.length;
+            assert highKeys.length == keyTargets.length;
+            assert key.getKind() == Kind.Int;
+        }
+
+        @Override
+        public LabelRef fallThroughTarget() {
+            return defaultTarget;
+        }
+
+        @Override
+        public void setFallThroughTarget(LabelRef target) {
+            defaultTarget = target;
+        }
+
+        private static boolean isSorted(int[] values) {
+            for (int i = 1; i < values.length; i++) {
+                if (values[i - 1] >= values[i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
     public static class TableSwitchOp extends SPARCLIRInstruction {
 
         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 +402,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;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java	Tue Jun 04 11:01:20 2013 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.lir.sparc;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.sparc.SPARCAssembler;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fsqrtd;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.asm.*;
+
+public class SPARCMathIntrinsicOp extends SPARCLIRInstruction {
+
+    public enum IntrinsicOpcode {
+        SQRT, SIN, COS, TAN, LOG, LOG10
+    }
+
+    @Opcode private final IntrinsicOpcode opcode;
+    @Def protected Value result;
+    @Use protected Value input;
+
+    public SPARCMathIntrinsicOp(IntrinsicOpcode opcode, Value result, Value input) {
+        this.opcode = opcode;
+        this.result = result;
+        this.input = input;
+    }
+
+    @Override
+    @SuppressWarnings("unused")
+    public void emitCode(TargetMethodAssembler tasm, SPARCAssembler asm) {
+        switch (opcode) {
+            case SQRT:
+                new Fsqrtd(asm, asDoubleReg(result), asDoubleReg(input));
+                break;
+            case LOG:
+            case LOG10:
+            case SIN:
+            case COS:
+            case TAN:
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+}
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Tue Jun 04 11:01:20 2013 +0200
@@ -22,18 +22,35 @@
  */
 package com.oracle.graal.lir.sparc;
 
-import static com.oracle.graal.api.code.ValueUtil.asRegister;
-import static com.oracle.graal.api.code.ValueUtil.isConstant;
-import static com.oracle.graal.api.code.ValueUtil.isRegister;
+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.*;
+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.Membar;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Or;
+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.asm.sparc.SPARCMacroAssembler.Setuw;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
 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 {
 
@@ -52,32 +69,33 @@
         }
 
         @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());
+                    new Ldsb(masm, addr, asRegister(result));
                     break;
                 case Short:
-                    // masm.ld_global_s16(asRegister(result), addr.getBase(), addr.getDisplacement());
+                    new Ldsh(masm, addr, asRegister(result));
                     break;
                 case Char:
-                    // masm.ld_global_u16(asRegister(result), addr.getBase(), addr.getDisplacement());
+                    new Lduw(masm, addr, asRegister(result));
                     break;
                 case Int:
-                    // masm.ld_global_s32(asRegister(result), addr.getBase(), addr.getDisplacement());
+                    new Ldsw(masm, addr, asRegister(result));
                     break;
                 case Long:
-                    // masm.ld_global_s64(asRegister(result), addr.getBase(), addr.getDisplacement());
+                    new Ldx(masm, addr, asRegister(result));
                     break;
                 case Float:
-                    // masm.ld_global_f32(asRegister(result), addr.getBase(), addr.getDisplacement());
+                    new Ldf(masm, addr, asRegister(result));
                     break;
                 case Double:
-                    // masm.ld_global_f64(asRegister(result), addr.getBase(), addr.getDisplacement());
+                    new Lddf(masm, addr, asRegister(result));
                     break;
                 case Object:
-                    // masm.ld_global_u32(asRegister(result), addr.getBase(), addr.getDisplacement());
+                    new Ldx(masm, addr, asRegister(result));
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
@@ -85,49 +103,18 @@
         }
     }
 
-    public static class StoreOp extends SPARCLIRInstruction {
+    @SuppressWarnings("unused")
+    public static class MembarOp extends SPARCLIRInstruction {
 
-        private final Kind kind;
-        @Use({COMPOSITE}) protected SPARCAddressValue address;
-        @Use({REG}) protected AllocatableValue input;
-        @State protected LIRFrameState state;
+        private final int barriers;
 
-        public StoreOp(Kind kind, SPARCAddressValue address, AllocatableValue input, LIRFrameState state) {
-            this.kind = kind;
-            this.address = address;
-            this.input = input;
-            this.state = state;
+        public MembarOp(final int barriers) {
+            this.barriers = barriers;
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
-            assert isRegister(input);
-            @SuppressWarnings("unused") 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());
-            }
+        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler asm) {
+            new Membar(asm, barriers);
         }
     }
 
@@ -185,6 +172,88 @@
         }
     }
 
+    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));
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static class StackLoadAddressOp extends SPARCLIRInstruction {
+
+        @Def({REG}) protected AllocatableValue result;
+        @Use({STACK, UNINITIALIZED}) protected StackSlot slot;
+
+        public StackLoadAddressOp(AllocatableValue result, StackSlot slot) {
+            this.result = result;
+            this.slot = slot;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler asm) {
+            new Ldx(asm, (SPARCAddress) tasm.asAddress(slot), asLongReg(result));
+        }
+    }
+
+    public static class StoreOp extends SPARCLIRInstruction {
+
+        private final Kind kind;
+        @Use({COMPOSITE}) protected SPARCAddressValue address;
+        @Use({REG}) protected AllocatableValue input;
+        @State protected LIRFrameState state;
+
+        public StoreOp(Kind kind, SPARCAddressValue address, AllocatableValue input, LIRFrameState state) {
+            this.kind = kind;
+            this.address = address;
+            this.input = input;
+            this.state = state;
+        }
+
+        @Override
+        @SuppressWarnings("unused")
+        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+            assert isRegister(input);
+            SPARCAddress addr = address.toAddress();
+            switch (kind) {
+                case Byte:
+                    new Stb(masm, asRegister(input), addr);
+                    break;
+                case Short:
+                    new Sth(masm, asRegister(input), addr);
+                    break;
+                case Int:
+                    new Stw(masm, asRegister(input), addr);
+                    break;
+                case Long:
+                    new Stx(masm, asRegister(input), addr);
+                    break;
+                case Float:
+                    new Stx(masm, asRegister(input), addr);
+                    break;
+                case Double:
+                    new Stx(masm, asRegister(input), addr);
+                    break;
+                case Object:
+                    new Stx(masm, asRegister(input), addr);
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere("missing: " + address.getKind());
+            }
+        }
+    }
+
     public static void move(TargetMethodAssembler tasm, SPARCAssembler masm, Value result, Value input) {
         if (isRegister(input)) {
             if (isRegister(result)) {
@@ -203,25 +272,26 @@
         }
     }
 
-    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));
+                new Or(masm, SPARC.r0, asRegister(input), asRegister(result));
                 break;
             case Long:
-             // masm.mov_s64(asRegister(result), asRegister(input));
+                new Or(masm, SPARC.r0, asRegister(input), asRegister(result));
                 break;
             case Float:
-             // masm.mov_f32(asRegister(result), asRegister(input));
+                new Or(masm, SPARC.r0, asRegister(input), asRegister(result));
                 break;
             case Double:
-             // masm.mov_f64(asRegister(result), asRegister(input));
+                new Or(masm, SPARC.r0, asRegister(input), asRegister(result));
                 break;
             case Object:
-             // masm.mov_u64(asRegister(result), asRegister(input));
+                new Or(masm, SPARC.r0, asRegister(input), asRegister(result));
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere("missing: " + input.getKind());
@@ -235,22 +305,22 @@
                 if (tasm.runtime.needsDataPatch(input)) {
                     tasm.recordDataReferenceInCode(input, 0, true);
                 }
-             // masm.mov_s32(asRegister(result), input.asInt());
+                new Setuw(masm, input.asInt(), asRegister(result));
                 break;
             case Long:
                 if (tasm.runtime.needsDataPatch(input)) {
                     tasm.recordDataReferenceInCode(input, 0, true);
                 }
-             // masm.mov_s64(asRegister(result), input.asLong());
+                new Setx(masm, input.asInt(), null, asRegister(result));
                 break;
             case Object:
                 if (input.isNull()) {
-                 // masm.mov_u64(asRegister(result), 0x0L);
+                    new Setx(masm, 0x0L, null, asRegister(result));
                 } else if (tasm.target.inlineObjects) {
                     tasm.recordDataReferenceInCode(input, 0, true);
-                 // masm.mov_u64(asRegister(result), 0xDEADDEADDEADDEADL);
+                    new Setx(masm, 0xDEADDEADDEADDEADL, null, asRegister(result));
                 } else {
-                 // masm.mov_u64(asRegister(result), tasm.recordDataReferenceInCode(input, 0, false));
+                    throw new InternalError("NYI");
                 }
                 break;
             default:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java	Tue Jun 04 11:01:20 2013 +0200
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.lir.sparc;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+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.SPARCAssembler.Ldsw;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.asm.*;
+
+public class SPARCTestOp extends SPARCLIRInstruction {
+
+    @Use({REG}) protected Value x;
+    @Use({REG, STACK, CONST}) protected Value y;
+
+    public SPARCTestOp(Value x, Value y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    @Override
+    @SuppressWarnings("unused")
+    public void emitCode(TargetMethodAssembler tasm, SPARCAssembler asm) {
+        if (isRegister(y)) {
+            switch (x.getKind()) {
+                case Int:
+                    new Cmp(asm, asIntReg(x), asIntReg(y));
+                    break;
+                case Long:
+                    new Cmp(asm, asLongReg(x), asLongReg(y));
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        } else if (isConstant(y)) {
+            switch (x.getKind()) {
+                case Int:
+                    new Cmp(asm, asIntReg(x), tasm.asIntConst(y));
+                    break;
+                case Long:
+                    new Cmp(asm, asLongReg(x), tasm.asIntConst(y));
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        } else {
+            switch (x.getKind()) {
+                case Int:
+                    new Ldsw(asm, (SPARCAddress) tasm.asIntAddr(y), asIntReg(y));
+                    new Cmp(asm, asIntReg(x), asIntReg(y));
+                    break;
+                case Long:
+                    new Ldx(asm, (SPARCAddress) tasm.asLongAddr(y), asLongReg(y));
+                    new Cmp(asm, asLongReg(x), asLongReg(y));
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+    }
+
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Tue Jun 04 11:01:20 2013 +0200
@@ -45,12 +45,12 @@
         super(object, ConstantLocationNode.create(locationIdentity, kind, displacement, object.graph()), StampFactory.forKind(kind));
     }
 
-    private ReadNode(ValueNode object, ValueNode location, GuardingNode guard) {
+    private ReadNode(ValueNode object, ValueNode location, ValueNode guard) {
         /*
          * Used by node intrinsics. Since the initial value for location is a parameter, i.e., a
          * LocalNode, the constructor cannot use the declared type LocationNode.
          */
-        super(object, location, StampFactory.forNodeIntrinsic(), guard, WriteBarrierType.NONE, false);
+        super(object, location, StampFactory.forNodeIntrinsic(), (GuardingNode) guard, WriteBarrierType.NONE, false);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java	Tue Jun 04 11:01:20 2013 +0200
@@ -74,7 +74,7 @@
             int index = indexValue.isConstant() ? indexValue.asConstant().asInt() : -1;
             if (index >= 0 && index < arrayState.getVirtualObject().entryCount()) {
                 ResolvedJavaType componentType = arrayState.getVirtualObject().type().getComponentType();
-                if (componentType.isPrimitive() || value.objectStamp().alwaysNull() || componentType.isAssignableFrom(value.objectStamp().type())) {
+                if (componentType.isPrimitive() || value.objectStamp().alwaysNull() || (value.objectStamp().type() != null && componentType.isAssignableFrom(value.objectStamp().type()))) {
                     tool.setVirtualEntry(arrayState, index, value());
                     tool.delete();
                 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.options/src/META-INF/services/javax.annotation.processing.Processor	Tue Jun 04 11:01:20 2013 +0200
@@ -0,0 +1,1 @@
+com.oracle.graal.options.OptionProcessor
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/Option.java	Tue Jun 04 11:01:20 2013 +0200
@@ -0,0 +1,44 @@
+/*
+ * 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.options;
+
+import java.lang.annotation.*;
+
+/**
+ * Describes the attributes of an option whose {@link OptionValue value} is in a static field
+ * annotated by this annotation type.
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.FIELD)
+public @interface Option {
+
+    /**
+     * Gets a help message for the option.
+     */
+    String help();
+
+    /**
+     * The name of the option. By default, the name of the annotated field should be used.
+     */
+    String name() default "";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java	Tue Jun 04 11:01:20 2013 +0200
@@ -0,0 +1,230 @@
+/*
+ * 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.options;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import javax.annotation.processing.*;
+import javax.lang.model.*;
+import javax.lang.model.element.*;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.type.*;
+import javax.lang.model.util.*;
+import javax.tools.Diagnostic.Kind;
+import javax.tools.*;
+
+/**
+ * Processes static fields annotated with {@link Option}. An {@link OptionProvider} is generated for
+ * each such field that can be accessed as a {@linkplain ServiceLoader service} as follows:
+ * 
+ * <pre>
+ * ServiceLoader&lt;OptionProvider&gt; sl = ServiceLoader.loadInstalled(OptionProvider.class);
+ * for (OptionProvider provider : sl) {
+ *     // use provider
+ * }
+ * </pre>
+ */
+@SupportedSourceVersion(SourceVersion.RELEASE_7)
+@SupportedAnnotationTypes({"com.oracle.graal.options.Option"})
+public class OptionProcessor extends AbstractProcessor {
+
+    private final Set<Element> processed = new HashSet<>();
+
+    private void processElement(Element element) {
+        if (processed.contains(element)) {
+            return;
+        }
+        processed.add(element);
+
+        if (!element.getModifiers().contains(Modifier.STATIC)) {
+            processingEnv.getMessager().printMessage(Kind.ERROR, "Option field must be static", element);
+            return;
+        }
+
+        Option annotation = element.getAnnotation(Option.class);
+        assert annotation != null;
+        assert element instanceof VariableElement;
+        assert element.getKind() == ElementKind.FIELD;
+        VariableElement field = (VariableElement) element;
+        String fieldName = field.getSimpleName().toString();
+
+        Elements elements = processingEnv.getElementUtils();
+        Types types = processingEnv.getTypeUtils();
+
+        TypeMirror fieldType = field.asType();
+        if (fieldType.getKind() != TypeKind.DECLARED) {
+            processingEnv.getMessager().printMessage(Kind.ERROR, "Option field must be of type " + OptionValue.class.getName(), element);
+            return;
+        }
+        DeclaredType declaredFieldType = (DeclaredType) fieldType;
+
+        TypeMirror optionValueType = elements.getTypeElement(OptionValue.class.getName()).asType();
+        if (!types.isSubtype(fieldType, types.erasure(optionValueType))) {
+            String msg = String.format("Option field type %s is not a subclass of %s", fieldType, optionValueType);
+            processingEnv.getMessager().printMessage(Kind.ERROR, msg, element);
+            return;
+        }
+
+        if (!field.getModifiers().contains(Modifier.STATIC)) {
+            processingEnv.getMessager().printMessage(Kind.ERROR, "Option field must be static", element);
+            return;
+        }
+
+        String optionName = annotation.name();
+        if (optionName.equals("")) {
+            optionName = fieldName;
+        }
+
+        String optionType = declaredFieldType.getTypeArguments().get(0).toString();
+        if (optionType.startsWith("java.lang.")) {
+            optionType = optionType.substring("java.lang.".length());
+        }
+
+        String pkg = null;
+        Element enclosing = element.getEnclosingElement();
+        String declaringClass = "";
+        String separator = "";
+        while (enclosing != null) {
+            if (enclosing.getKind() == ElementKind.CLASS || enclosing.getKind() == ElementKind.INTERFACE) {
+                if (enclosing.getModifiers().contains(Modifier.PRIVATE)) {
+                    String msg = String.format("Option field cannot be declared in a private %s %s", enclosing.getKind().name().toLowerCase(), enclosing);
+                    processingEnv.getMessager().printMessage(Kind.ERROR, msg, element);
+                    return;
+                }
+                declaringClass = enclosing.getSimpleName() + separator + declaringClass;
+                separator = ".";
+            } else {
+                assert enclosing.getKind() == ElementKind.PACKAGE;
+                pkg = ((PackageElement) enclosing).getQualifiedName().toString();
+            }
+            enclosing = enclosing.getEnclosingElement();
+        }
+
+        String providerClassName = declaringClass.replace('.', '_') + "_" + fieldName;
+
+        Filer filer = processingEnv.getFiler();
+        try (PrintWriter out = createSourceFile(element, pkg, providerClassName, filer)) {
+
+            out.println("/*");
+            out.println(" * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.");
+            out.println(" * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.");
+            out.println(" *");
+            out.println(" * This code is free software; you can redistribute it and/or modify it");
+            out.println(" * under the terms of the GNU General Public License version 2 only, as");
+            out.println(" * published by the Free Software Foundation.");
+            out.println(" *");
+            out.println(" * This code is distributed in the hope that it will be useful, but WITHOUT");
+            out.println(" * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or");
+            out.println(" * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License");
+            out.println(" * version 2 for more details (a copy is included in the LICENSE file that");
+            out.println(" * accompanied this code).");
+            out.println(" *");
+            out.println(" * You should have received a copy of the GNU General Public License version");
+            out.println(" * 2 along with this work; if not, write to the Free Software Foundation,");
+            out.println(" * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.");
+            out.println(" *");
+            out.println(" * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA");
+            out.println(" * or visit www.oracle.com if you need additional information or have any");
+            out.println(" * questions.");
+            out.println(" */");
+
+            out.println("package " + pkg + ";");
+            out.println("");
+            if (element.getModifiers().contains(Modifier.PRIVATE)) {
+                out.println("import " + Field.class.getName() + ";");
+            }
+            out.println("import " + OptionValue.class.getName() + ";");
+            out.println("import " + OptionProvider.class.getName() + ";");
+            out.println("");
+            out.println("public class " + providerClassName + " implements " + OptionProvider.class.getSimpleName() + " {");
+            out.println("    public String getHelp() {");
+            out.println("        return \"" + annotation.help() + "\";");
+            out.println("    }");
+            out.println("    public String getName() {");
+            out.println("        return \"" + optionName + "\";");
+            out.println("    }");
+            out.println("    public Class getType() {");
+            out.println("        return " + optionType + ".class;");
+            out.println("    }");
+            out.println("    public " + OptionValue.class.getSimpleName() + "<?> getOptionValue() {");
+            if (!element.getModifiers().contains(Modifier.PRIVATE)) {
+                out.println("        return " + declaringClass + "." + fieldName + ";");
+            } else {
+                out.println("        try {");
+                out.println("            Field field = " + declaringClass + ".class.getDeclaredField(\"" + fieldName + "\");");
+                out.println("            field.setAccessible(true);");
+                out.println("            return (" + OptionValue.class.getSimpleName() + ") field.get(null);");
+                out.println("        } catch (Exception e) {");
+                out.println("            throw (InternalError) new InternalError().initCause(e);");
+                out.println("        }");
+            }
+            out.println("    }");
+            out.println("}");
+        }
+
+        try {
+            createProviderFile(field, pkg, providerClassName);
+        } catch (IOException e) {
+            processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage(), field);
+        }
+    }
+
+    private void createProviderFile(Element field, String pkg, String providerClassName) throws IOException {
+        String filename = "META-INF/providers/" + pkg + "." + providerClassName;
+        FileObject file = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", filename, field);
+        PrintWriter writer = new PrintWriter(new OutputStreamWriter(file.openOutputStream(), "UTF-8"));
+        writer.println(OptionProvider.class.getName());
+        writer.close();
+    }
+
+    protected PrintWriter createSourceFile(Element element, String pkg, String relativeName, Filer filer) {
+        try {
+            // Ensure Unix line endings to comply with Graal code style guide checked by Checkstyle
+            JavaFileObject sourceFile = filer.createSourceFile(pkg + "." + relativeName, element);
+            return new PrintWriter(sourceFile.openWriter()) {
+
+                @Override
+                public void println() {
+                    print("\n");
+                }
+            };
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        if (roundEnv.processingOver()) {
+            return true;
+        }
+
+        for (Element element : roundEnv.getElementsAnnotatedWith(Option.class)) {
+            processElement(element);
+        }
+
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProvider.java	Tue Jun 04 11:01:20 2013 +0200
@@ -0,0 +1,54 @@
+/*
+ * 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.options;
+
+import java.util.*;
+
+/**
+ * Describes the attributes of an {@linkplain Option option} and provides access to its
+ * {@linkplain OptionValue value}. The {@link OptionProcessor} auto-generates instances of this
+ * interface that are accessible as a {@linkplain ServiceLoader service}.
+ */
+public interface OptionProvider {
+
+    /**
+     * Gets the type of values stored in the option.
+     */
+    Class getType();
+
+    /**
+     * Gets a descriptive help message for the option.
+     */
+    String getHelp();
+
+    /**
+     * Gets the name of the option. It's up to the client of this object how to use the name to get
+     * a user specified value for the option from the environment.
+     */
+    String getName();
+
+    /**
+     * Gets the boxed option value.
+     */
+    OptionValue<?> getOptionValue();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java	Tue Jun 04 11:01:20 2013 +0200
@@ -0,0 +1,79 @@
+/*
+ * 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.options;
+
+import java.util.*;
+
+/**
+ * A settable option value.
+ * <p>
+ * To access {@link OptionProvider} instances via a {@link ServiceLoader} for working with options,
+ * instances of this class should be assigned to static final fields that are annotated with
+ * {@link Option}.
+ */
+public class OptionValue<T> {
+
+    /**
+     * The raw option value.
+     */
+    protected T value;
+
+    /**
+     * Guards whether {@link #initialValue()} should be called to give a subclass an opportunity to
+     * provide a context-sensitive initial value for this option.
+     */
+    protected boolean initialValueCalled;
+
+    /**
+     * Create an option.
+     * 
+     * @param value the initial/default value of the option
+     */
+    public OptionValue(T value) {
+        this.value = value;
+    }
+
+    protected T initialValue() {
+        return value;
+    }
+
+    /**
+     * Gets the value of this option.
+     */
+    public final T getValue() {
+        if (!initialValueCalled) {
+            value = initialValue();
+            initialValueCalled = true;
+        }
+        return value;
+    }
+
+    /**
+     * Sets the value of this option.
+     */
+    @SuppressWarnings("unchecked")
+    public final void setValue(Object v) {
+        this.value = (T) v;
+        this.initialValueCalled = true;
+    }
+}
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Tue Jun 04 11:01:20 2013 +0200
@@ -1033,20 +1033,29 @@
                 holder = receiverType;
                 if (receiverStamp.isExactType()) {
                     assert targetMethod.getDeclaringClass().isAssignableFrom(holder) : holder + " subtype of " + targetMethod.getDeclaringClass() + " for " + targetMethod;
-                    return getExactInlineInfo(data, invoke, replacements, optimisticOpts, holder.resolveMethod(targetMethod));
+                    ResolvedJavaMethod resolvedMethod = holder.resolveMethod(targetMethod);
+                    if (resolvedMethod != null) {
+                        return getExactInlineInfo(data, invoke, replacements, optimisticOpts, resolvedMethod);
+                    }
                 }
             }
         }
 
         if (holder.isArray()) {
             // arrays can be treated as Objects
-            return getExactInlineInfo(data, invoke, replacements, optimisticOpts, holder.resolveMethod(targetMethod));
+            ResolvedJavaMethod resolvedMethod = holder.resolveMethod(targetMethod);
+            if (resolvedMethod != null) {
+                return getExactInlineInfo(data, invoke, replacements, optimisticOpts, resolvedMethod);
+            }
         }
 
         if (assumptions.useOptimisticAssumptions()) {
             ResolvedJavaType uniqueSubtype = holder.findUniqueConcreteSubtype();
             if (uniqueSubtype != null) {
-                return getAssumptionInlineInfo(data, invoke, replacements, optimisticOpts, uniqueSubtype.resolveMethod(targetMethod), new Assumptions.ConcreteSubtype(holder, uniqueSubtype));
+                ResolvedJavaMethod resolvedMethod = uniqueSubtype.resolveMethod(targetMethod);
+                if (resolvedMethod != null) {
+                    return getAssumptionInlineInfo(data, invoke, replacements, optimisticOpts, resolvedMethod, new Assumptions.ConcreteSubtype(holder, uniqueSubtype));
+                }
             }
 
             ResolvedJavaMethod concrete = holder.findUniqueConcreteMethod(targetMethod);
@@ -1122,6 +1131,9 @@
             ArrayList<Double> concreteMethodsProbabilities = new ArrayList<>();
             for (int i = 0; i < ptypes.length; i++) {
                 ResolvedJavaMethod concrete = ptypes[i].getType().resolveMethod(targetMethod);
+                if (concrete == null) {
+                    return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "could not resolve method");
+                }
                 int index = concreteMethods.indexOf(concrete);
                 double curProbability = ptypes[i].getProbability();
                 if (index < 0) {
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Tue Jun 04 11:01:20 2013 +0200
@@ -34,11 +34,6 @@
     private static final boolean ____ = false;
     // Checkstyle: resume
 
-    public static int     Threads;
-    static {
-        Threads = Runtime.getRuntime().availableProcessors();
-    }
-
     public static String  CompilerConfiguration              = "basic";
     public static String  GraalRuntime                       = "basic";
 
@@ -80,10 +75,6 @@
     public static int     MatureExecutionsTypeProfile        = 1;
 
     // comilation queue
-    public static int     TimedBootstrap                     = -1;
-    public static boolean PriorityCompileQueue               = true;
-    public static int     SlowQueueCutoff                    = 100000;
-    public static boolean SlowCompileThreads                 = ____;
     public static boolean DynamicCompilePriority             = ____;
     public static String  CompileTheWorld                    = null;
     public static int     CompileTheWorldStartAt             = 1;
@@ -115,21 +106,7 @@
     public static String  PrintFilter                        = null;
 
     // Debug settings:
-    public static boolean Debug                              = true;
-    public static boolean DebugReplacements                  = ____;
     public static boolean BootstrapReplacements              = ____;
-    public static boolean PerThreadDebugValues               = ____;
-    public static boolean SummarizeDebugValues               = ____;
-    public static boolean SummarizePerPhase                  = ____;
-    public static String  Dump                               = null;
-    public static String  Meter                              = null;
-    public static String  Time                               = null;
-    public static String  Log                                = null;
-    public static String  LogFile                            = null;
-    public static String  MethodFilter                       = null;
-    public static boolean DumpOnError                        = ____;
-    public static boolean GenericDynamicCounters             = ____;
-    public static String  BenchmarkDynamicCounters           = null;
 
     // Ideal graph visualizer output settings
     public static boolean PrintBinaryGraphs                  = true;
@@ -140,7 +117,6 @@
     public static int     PrintBinaryGraphPort               = 4445;
 
     // Other printing settings
-    public static boolean PrintQueue                         = ____;
     public static boolean PrintCompilation                   = ____;
     public static boolean PrintProfilingInformation          = ____;
     public static boolean PrintIRWithLIR                     = ____;
@@ -212,7 +188,6 @@
     public static boolean OptDevirtualizeInvokesOptimistically = true;
     public static boolean OptPushThroughPi                   = true;
 
-
     // Intrinsification settings
     public static boolean IntrinsifyObjectClone              = ____;
     public static boolean IntrinsifyArrayCopy                = true;
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java	Tue Jun 04 11:01:20 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.printer;
 
+import static com.oracle.graal.compiler.GraalDebugConfig.*;
+
 import java.io.*;
 import java.util.*;
 
@@ -41,7 +43,7 @@
             }
             dumpHandlers.add(new CFGPrinterObserver());
         }
-        GraalDebugConfig hotspotDebugConfig = new GraalDebugConfig(GraalOptions.Log, GraalOptions.Meter, GraalOptions.Time, GraalOptions.Dump, GraalOptions.MethodFilter, log, dumpHandlers);
+        GraalDebugConfig hotspotDebugConfig = new GraalDebugConfig(Log.getValue(), Meter.getValue(), Time.getValue(), Dump.getValue(), MethodFilter.getValue(), log, dumpHandlers);
         Debug.setConfig(hotspotDebugConfig);
     }
 }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BranchProbabilityNode.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BranchProbabilityNode.java	Tue Jun 04 11:01:20 2013 +0200
@@ -92,6 +92,9 @@
                 }
             }
             if (!couldSet) {
+                if (isSubstitutionGraph()) {
+                    return this;
+                }
                 throw new GraalInternalError("Wrong usage of branch probability injection!");
             }
             return condition;
@@ -99,6 +102,10 @@
         return this;
     }
 
+    private boolean isSubstitutionGraph() {
+        return usages().count() == 1 && usages().first() instanceof ReturnNode;
+    }
+
     /**
      * This intrinsic should only be used for the condition of an if statement. The parameter
      * condition should also only denote a simple condition and not a combined condition involving
--- a/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java	Tue Jun 04 11:01:20 2013 +0200
@@ -74,6 +74,33 @@
     public static final Register r30 = new Register(30, 30, "r30", CPU);
     public static final Register r31 = new Register(31, 31, "r31", CPU);
 
+    public static final Register g0 = r0;
+    public static final Register g1 = r1;
+    public static final Register g2 = r2;
+    public static final Register g3 = r3;
+    public static final Register g4 = r4;
+    public static final Register g5 = r5;
+    public static final Register g6 = r6;
+    public static final Register g7 = r7;
+
+    public static final Register i0 = r24;
+    public static final Register i1 = r25;
+    public static final Register i2 = r26;
+    public static final Register i3 = r27;
+    public static final Register i4 = r28;
+    public static final Register i5 = r29;
+    public static final Register i6 = r30;
+    public static final Register i7 = r31;
+
+    public static final Register o0 = r8;
+    public static final Register o1 = r9;
+    public static final Register o2 = r10;
+    public static final Register o3 = r11;
+    public static final Register o4 = r12;
+    public static final Register o5 = r13;
+    public static final Register o6 = r14;
+    public static final Register o7 = r15;
+
     public static final Register[] gprRegisters = {
         r0,  r1,  r2,  r3,  r4,  r5,  r6,  r7,
          r8,  r9, r10, r11, r12, r13, r14, r15,
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Tue Jun 04 11:01:20 2013 +0200
@@ -1843,19 +1843,29 @@
 
             builder.startCall(execType.getMethodName());
 
-            List<ActualParameter> signatureParameters = getModel().getSignatureParameters();
             int index = 0;
             for (ActualParameter parameter : execType.getParameters()) {
 
                 if (!parameter.getSpecification().isSignature()) {
                     builder.string(parameter.getLocalName());
                 } else {
-                    if (index < signatureParameters.size()) {
-                        ActualParameter specializationParam = signatureParameters.get(index);
+                    if (index < targetField.getExecuteWith().size()) {
+                        NodeChildData child = targetField.getExecuteWith().get(index);
+
+                        ParameterSpec spec = getModel().getSpecification().findParameterSpec(child.getName());
+                        List<ActualParameter> specializationParams = getModel().findParameters(spec);
+
+                        if (specializationParams.isEmpty()) {
+                            builder.defaultValue(parameter.getType());
+                            continue;
+                        }
+
+                        ActualParameter specializationParam = specializationParams.get(0);
 
                         TypeData targetType = parameter.getTypeSystemType();
                         TypeData sourceType = specializationParam.getTypeSystemType();
                         String localName = specializationParam.getLocalName();
+
                         if (unexpectedParameter != null && unexpectedParameter.getLocalName().equals(specializationParam.getLocalName())) {
                             localName = "ex.getResult()";
                             sourceType = getModel().getNode().getTypeSystem().getGenericTypeData();
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java	Tue Jun 04 11:01:20 2013 +0200
@@ -133,6 +133,16 @@
         return parameters;
     }
 
+    public List<ActualParameter> findParameters(ParameterSpec spec) {
+        List<ActualParameter> foundParameters = new ArrayList<>();
+        for (ActualParameter param : getReturnTypeAndParameters()) {
+            if (param.getSpecification().equals(spec)) {
+                foundParameters.add(param);
+            }
+        }
+        return foundParameters;
+    }
+
     public ActualParameter findParameter(String valueName) {
         for (ActualParameter param : getReturnTypeAndParameters()) {
             if (param.getLocalName().equals(valueName)) {
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionDefinitionNode.java	Tue Jun 04 10:55:13 2013 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionDefinitionNode.java	Tue Jun 04 11:01:20 2013 +0200
@@ -61,6 +61,6 @@
 
     @Override
     public String toString() {
-        return "Function " + name + "@" + Integer.toHexString(hashCode());
+        return "Function " + name;
     }
 }
--- a/make/build-graal.xml	Tue Jun 04 10:55:13 2013 +0200
+++ b/make/build-graal.xml	Tue Jun 04 11:01:20 2013 +0200
@@ -42,6 +42,7 @@
       <src path="${src.dir}/com.oracle.graal.phases"/>
       <src path="${src.dir}/com.oracle.graal.phases.common"/>
       <src path="${src.dir}/com.oracle.graal.virtual"/>
+      <src path="${src.dir}/com.oracle.graal.options"/>
       <src path="${src.dir}/com.oracle.graal.loop"/>
       <src path="${src.dir}/com.oracle.graal.alloc"/>
       <src path="${src.dir}/com.oracle.graal.asm"/>
@@ -59,8 +60,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"/>
@@ -80,9 +81,34 @@
         <provider classname="com.oracle.graal.hotspot.replacements.HotSpotNmethodIntrinsics"/>
         <provider classname="com.oracle.graal.replacements.GraalMethodSubstitutions"/>
       </service>
+      <service type="com.oracle.graal.options.OptionProvider">
+        <provider classname="com.oracle.graal.compiler.GraalCompiler_VerifyUsageWithEquals"/>
+        <provider classname="com.oracle.graal.compiler.GraalDebugConfig_DebugEnabled"/>
+        <provider classname="com.oracle.graal.compiler.GraalDebugConfig_Dump"/>
+        <provider classname="com.oracle.graal.compiler.GraalDebugConfig_DumpOnError"/>
+        <provider classname="com.oracle.graal.compiler.GraalDebugConfig_Log"/>
+        <provider classname="com.oracle.graal.compiler.GraalDebugConfig_Meter"/>
+        <provider classname="com.oracle.graal.compiler.GraalDebugConfig_MethodFilter"/>
+        <provider classname="com.oracle.graal.compiler.GraalDebugConfig_PerThreadDebugValues"/>
+        <provider classname="com.oracle.graal.compiler.GraalDebugConfig_SummarizeDebugValues"/>
+        <provider classname="com.oracle.graal.compiler.GraalDebugConfig_SummarizePerPhase"/>
+        <provider classname="com.oracle.graal.compiler.GraalDebugConfig_Time"/>
+        <provider classname="com.oracle.graal.hotspot.CompilationTask_SlowQueueCutoff"/>
+        <provider classname="com.oracle.graal.hotspot.bridge.VMToCompilerImpl_BenchmarkDynamicCounters"/>
+        <provider classname="com.oracle.graal.hotspot.bridge.VMToCompilerImpl_GenericDynamicCounters"/>
+        <provider classname="com.oracle.graal.hotspot.bridge.VMToCompilerImpl_LogFile"/>
+        <provider classname="com.oracle.graal.hotspot.bridge.VMToCompilerImpl_PrintQueue"/>
+        <provider classname="com.oracle.graal.hotspot.bridge.VMToCompilerImpl_PriorityCompileQueue"/>
+        <provider classname="com.oracle.graal.hotspot.bridge.VMToCompilerImpl_SlowCompileThreads"/>
+        <provider classname="com.oracle.graal.hotspot.bridge.VMToCompilerImpl_Threads"/>
+        <provider classname="com.oracle.graal.hotspot.bridge.VMToCompilerImpl_TimedBootstrap"/>
+      </service>
       <service type="com.oracle.graal.phases.tiers.CompilerConfiguration">
         <provider classname="com.oracle.graal.compiler.phases.BasicCompilerConfiguration"/>
       </service>
+      <service type="javax.annotation.processing.Processor">
+        <provider classname="com.oracle.graal.options.OptionProcessor"/>
+      </service>
     </jar>
   </target>
   <target name="cleanclasses">
--- a/mx/projects	Tue Jun 04 10:55:13 2013 +0200
+++ b/mx/projects	Tue Jun 04 11:01:20 2013 +0200
@@ -100,7 +100,7 @@
 project@com.oracle.graal.hotspot@sourceDirs=src
 project@com.oracle.graal.hotspot@dependencies=com.oracle.graal.replacements,com.oracle.graal.printer
 project@com.oracle.graal.hotspot@checkstyle=com.oracle.graal.graph
-project@com.oracle.graal.hotspot@annotationProcessors=com.oracle.graal.replacements.verifier, com.oracle.graal.service.processor
+project@com.oracle.graal.hotspot@annotationProcessors=com.oracle.graal.replacements.verifier,com.oracle.graal.service.processor,com.oracle.graal.options
 project@com.oracle.graal.hotspot@javaCompliance=1.7
 
 # graal.hotspot.amd64
@@ -138,6 +138,12 @@
 project@com.oracle.graal.hotspot.amd64.test@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.hotspot.amd64.test@javaCompliance=1.7
 
+# graal.options
+project@com.oracle.graal.options@subDir=graal
+project@com.oracle.graal.options@sourceDirs=src
+project@com.oracle.graal.options@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.options@javaCompliance=1.7
+
 # graal.graph
 project@com.oracle.graal.graph@subDir=graal
 project@com.oracle.graal.graph@sourceDirs=src
@@ -188,7 +194,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
 
@@ -273,10 +279,10 @@
 # graal.compiler
 project@com.oracle.graal.compiler@subDir=graal
 project@com.oracle.graal.compiler@sourceDirs=src
-project@com.oracle.graal.compiler@dependencies=com.oracle.graal.api.runtime,com.oracle.graal.virtual,com.oracle.graal.loop,com.oracle.graal.alloc,com.oracle.graal.lir
+project@com.oracle.graal.compiler@dependencies=com.oracle.graal.api.runtime,com.oracle.graal.virtual,com.oracle.graal.options,com.oracle.graal.loop,com.oracle.graal.alloc,com.oracle.graal.lir
 project@com.oracle.graal.compiler@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.compiler@javaCompliance=1.7
-project@com.oracle.graal.compiler@annotationProcessors=com.oracle.graal.service.processor
+project@com.oracle.graal.compiler@annotationProcessors=com.oracle.graal.service.processor,com.oracle.graal.options
 
 # graal.compiler.amd64
 project@com.oracle.graal.compiler.amd64@subDir=graal
@@ -399,7 +405,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
 
--- a/mxtool/mx	Tue Jun 04 10:55:13 2013 +0200
+++ b/mxtool/mx	Tue Jun 04 11:01:20 2013 +0200
@@ -43,7 +43,7 @@
     python_exe=python2.7
 else
     type python2 > /dev/null 2>&1
-    if [ $? -eq 0]; then
+    if [ $? -eq 0 ]; then
         python_exe=python2
     else
         python_exe=python
--- a/mxtool/mx.py	Tue Jun 04 10:55:13 2013 +0200
+++ b/mxtool/mx.py	Tue Jun 04 11:01:20 2013 +0200
@@ -1700,6 +1700,11 @@
             try:
                 zf = zipfile.ZipFile(tmp, 'w')
                 for p in sorted_deps(d.deps):
+                    # skip a  Java project if its Java compliance level is "higher" than the configured JDK
+                    if java().javaCompliance < p.javaCompliance:
+                        log('Excluding {0} from {2} (Java compliance level {1} required)'.format(p.name, p.javaCompliance, d.path))
+                        continue
+
                     outputDir = p.output_dir()
                     for root, _, files in os.walk(outputDir):
                         relpath = root[len(outputDir) + 1:]