changeset 19689:9d2ff2e8360d

Merge with fa75218e39424f24e05d31ee58dfd5c2bb4c8319
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Tue, 03 Mar 2015 17:13:51 -0800
parents 33bdafbf285d (current diff) fa75218e3942 (diff)
children c152a485d747
files graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/TimerCloseable.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java
diffstat 90 files changed, 2418 insertions(+), 5224 deletions(-) [+]
line wrap: on
line diff
--- a/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapSet.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapSet.java	Tue Mar 03 17:13:51 2015 -0800
@@ -65,9 +65,6 @@
       }
     }
 
-    public void visitValueLocation(Address valueAddr) {
-    }
-
     public void visitNarrowOopLocation(Address narrowOopAddr) {
       addressVisitor.visitCompOopAddress(narrowOopAddr);
     }
@@ -198,9 +195,9 @@
       }
     }
 
-    // We want narow oop, value and oop oop_types
+    // We want narow oop and  oop oop_types
     OopMapValue.OopTypes[] values = new OopMapValue.OopTypes[] {
-      OopMapValue.OopTypes.OOP_VALUE, OopMapValue.OopTypes.VALUE_VALUE, OopMapValue.OopTypes.NARROWOOP_VALUE
+      OopMapValue.OopTypes.OOP_VALUE, OopMapValue.OopTypes.NARROWOOP_VALUE
     };
 
     {
@@ -213,8 +210,6 @@
             // to detect in the debugging system
             // assert(Universe::is_heap_or_null(*loc), "found non oop pointer");
             visitor.visitOopLocation(loc);
-          } else if (omv.getType() == OopMapValue.OopTypes.VALUE_VALUE) {
-            visitor.visitValueLocation(loc);
           } else if (omv.getType() == OopMapValue.OopTypes.NARROWOOP_VALUE) {
             visitor.visitNarrowOopLocation(loc);
           }
--- a/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapValue.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapValue.java	Tue Mar 03 17:13:51 2015 -0800
@@ -49,7 +49,6 @@
   // Types of OopValues
   static int UNUSED_VALUE;
   static int OOP_VALUE;
-  static int VALUE_VALUE;
   static int NARROWOOP_VALUE;
   static int CALLEE_SAVED_VALUE;
   static int DERIVED_OOP_VALUE;
@@ -73,7 +72,6 @@
     REGISTER_MASK_IN_PLACE = db.lookupIntConstant("OopMapValue::register_mask_in_place").intValue();
     UNUSED_VALUE           = db.lookupIntConstant("OopMapValue::unused_value").intValue();
     OOP_VALUE              = db.lookupIntConstant("OopMapValue::oop_value").intValue();
-    VALUE_VALUE            = db.lookupIntConstant("OopMapValue::value_value").intValue();
     NARROWOOP_VALUE        = db.lookupIntConstant("OopMapValue::narrowoop_value").intValue();
     CALLEE_SAVED_VALUE     = db.lookupIntConstant("OopMapValue::callee_saved_value").intValue();
     DERIVED_OOP_VALUE      = db.lookupIntConstant("OopMapValue::derived_oop_value").intValue();
@@ -82,7 +80,6 @@
   public static abstract class OopTypes {
     public static final OopTypes UNUSED_VALUE       = new OopTypes() { int getValue() { return OopMapValue.UNUSED_VALUE;       }};
     public static final OopTypes OOP_VALUE          = new OopTypes() { int getValue() { return OopMapValue.OOP_VALUE;          }};
-    public static final OopTypes VALUE_VALUE        = new OopTypes() { int getValue() { return OopMapValue.VALUE_VALUE;        }};
     public static final OopTypes NARROWOOP_VALUE    = new OopTypes() { int getValue() { return OopMapValue.NARROWOOP_VALUE;         }};
     public static final OopTypes CALLEE_SAVED_VALUE = new OopTypes() { int getValue() { return OopMapValue.CALLEE_SAVED_VALUE; }};
     public static final OopTypes DERIVED_OOP_VALUE  = new OopTypes() { int getValue() { return OopMapValue.DERIVED_OOP_VALUE;  }};
@@ -105,7 +102,6 @@
 
   // Querying
   public boolean isOop()         { return (getValue() & TYPE_MASK_IN_PLACE) == OOP_VALUE;          }
-  public boolean isValue()       { return (getValue() & TYPE_MASK_IN_PLACE) == VALUE_VALUE;        }
   public boolean isNarrowOop()   { return (getValue() & TYPE_MASK_IN_PLACE) == NARROWOOP_VALUE;    }
   public boolean isCalleeSaved() { return (getValue() & TYPE_MASK_IN_PLACE) == CALLEE_SAVED_VALUE; }
   public boolean isDerivedOop()  { return (getValue() & TYPE_MASK_IN_PLACE) == DERIVED_OOP_VALUE;  }
@@ -117,7 +113,6 @@
     int which = (getValue() & TYPE_MASK_IN_PLACE);
          if (which == UNUSED_VALUE) return OopTypes.UNUSED_VALUE;
     else if (which == OOP_VALUE)    return OopTypes.OOP_VALUE;
-    else if (which == VALUE_VALUE)  return OopTypes.VALUE_VALUE;
     else if (which == NARROWOOP_VALUE)   return OopTypes.NARROWOOP_VALUE;
     else if (which == CALLEE_SAVED_VALUE) return OopTypes.CALLEE_SAVED_VALUE;
     else if (which == DERIVED_OOP_VALUE)  return OopTypes.DERIVED_OOP_VALUE;
--- a/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapVisitor.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapVisitor.java	Tue Mar 03 17:13:51 2015 -0800
@@ -31,6 +31,5 @@
 public interface OopMapVisitor {
   public void visitOopLocation(Address oopAddr);
   public void visitDerivedOopLocation(Address baseOopAddr, Address derivedOopAddr);
-  public void visitValueLocation(Address valueAddr);
   public void visitNarrowOopLocation(Address narrowOopAddr);
 }
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java	Tue Mar 03 17:13:51 2015 -0800
@@ -544,9 +544,6 @@
       }
     }
 
-    public void visitValueLocation(Address valueAddr) {
-    }
-
     public void visitNarrowOopLocation(Address compOopAddr) {
       addressVisitor.visitCompOopAddress(compOopAddr);
     }
--- a/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Tue Mar 03 17:13:51 2015 -0800
@@ -1222,9 +1222,6 @@
       oms = new OopMapStream(map, OopMapValue.OopTypes.NARROWOOP_VALUE);
       buf.append(omvIterator.iterate(oms, "NarrowOops:", false));
 
-      oms = new OopMapStream(map, OopMapValue.OopTypes.VALUE_VALUE);
-      buf.append(omvIterator.iterate(oms, "Values:", false));
-
       oms = new OopMapStream(map, OopMapValue.OopTypes.CALLEE_SAVED_VALUE);
       buf.append(omvIterator.iterate(oms, "Callee saved:",  true));
 
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java	Tue Mar 03 17:13:51 2015 -0800
@@ -66,7 +66,7 @@
      * Note that the number of locals and the number of stack slots may be smaller than the maximum
      * number of locals and stack slots as specified in the compiled method.
      */
-    public final JavaValue[] values;
+    public final Value[] values;
 
     /**
      * The number of locals in the values array.
@@ -144,7 +144,7 @@
      * @param numStack the depth of the stack
      * @param numLocks the number of locked objects
      */
-    public BytecodeFrame(BytecodeFrame caller, ResolvedJavaMethod method, int bci, boolean rethrowException, boolean duringCall, JavaValue[] values, int numLocals, int numStack, int numLocks) {
+    public BytecodeFrame(BytecodeFrame caller, ResolvedJavaMethod method, int bci, boolean rethrowException, boolean duringCall, Value[] values, int numLocals, int numStack, int numLocks) {
         super(caller, method, bci);
         assert values != null;
         this.rethrowException = rethrowException;
@@ -183,7 +183,7 @@
      * @param i the local variable index
      * @return the value that can be used to reconstruct the local's current value
      */
-    public JavaValue getLocalValue(int i) {
+    public Value getLocalValue(int i) {
         return values[i];
     }
 
@@ -193,7 +193,7 @@
      * @param i the stack index
      * @return the value that can be used to reconstruct the stack slot's current value
      */
-    public JavaValue getStackValue(int i) {
+    public Value getStackValue(int i) {
         return values[i + numLocals];
     }
 
@@ -203,7 +203,7 @@
      * @param i the lock index
      * @return the value that can be used to reconstruct the lock's current value
      */
-    public JavaValue getLockValue(int i) {
+    public Value getLockValue(int i) {
         return values[i + numLocals + numStack];
     }
 
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/StackLockValue.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/StackLockValue.java	Tue Mar 03 17:13:51 2015 -0800
@@ -33,22 +33,22 @@
 
     private static final long serialVersionUID = 8241681800464483691L;
 
-    private JavaValue owner;
+    private Value owner;
     private StackSlotValue slot;
     private final boolean eliminated;
 
-    public StackLockValue(JavaValue owner, StackSlotValue slot, boolean eliminated) {
+    public StackLockValue(Value object, StackSlotValue slot, boolean eliminated) {
         super(LIRKind.Illegal);
-        this.owner = owner;
+        this.owner = object;
         this.slot = slot;
         this.eliminated = eliminated;
     }
 
-    public JavaValue getOwner() {
+    public Value getOwner() {
         return owner;
     }
 
-    public void setOwner(JavaValue newOwner) {
+    public void setOwner(Value newOwner) {
         this.owner = newOwner;
     }
 
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java	Tue Mar 03 17:13:51 2015 -0800
@@ -36,7 +36,7 @@
     private static final long serialVersionUID = -2907197776426346021L;
 
     private final ResolvedJavaType type;
-    private JavaValue[] values;
+    private Value[] values;
     private final int id;
 
     /**
@@ -54,18 +54,18 @@
      *            position in the compiled code.
      * @return a new {@link VirtualObject} instance.
      */
-    public static VirtualObject get(ResolvedJavaType type, JavaValue[] values, int id) {
+    public static VirtualObject get(ResolvedJavaType type, Value[] values, int id) {
         return new VirtualObject(type, values, id);
     }
 
-    private VirtualObject(ResolvedJavaType type, JavaValue[] values, int id) {
+    private VirtualObject(ResolvedJavaType type, Value[] values, int id) {
         super(LIRKind.reference(Kind.Object));
         this.type = type;
         this.values = values;
         this.id = id;
     }
 
-    private static StringBuilder appendValue(StringBuilder buf, JavaValue value, Set<VirtualObject> visited) {
+    private static StringBuilder appendValue(StringBuilder buf, Value value, Set<VirtualObject> visited) {
         if (value instanceof VirtualObject) {
             VirtualObject vo = (VirtualObject) value;
             buf.append("vobject:").append(vo.type.toJavaName(false)).append(':').append(vo.id);
@@ -120,7 +120,7 @@
     /**
      * Returns an array containing all the values to be stored into the object when it is recreated.
      */
-    public JavaValue[] getValues() {
+    public Value[] getValues() {
         return values;
     }
 
@@ -132,7 +132,7 @@
         return id;
     }
 
-    private static boolean checkValues(ResolvedJavaType type, JavaValue[] values) {
+    private static boolean checkValues(ResolvedJavaType type, Value[] values) {
         if (values != null) {
             if (!type.isArray()) {
                 ResolvedJavaField[] fields = type.getInstanceFields(true);
@@ -140,8 +140,8 @@
                 for (int i = 0; i < values.length; i++) {
                     ResolvedJavaField field = fields[fieldIndex++];
                     Kind valKind = values[i].getKind().getStackKind();
-                    if (field.getKind() == Kind.Object && values[i] instanceof Value) {
-                        assert ((Value) values[i]).getLIRKind().isReference(0) : field + ": " + valKind + " != " + field.getKind();
+                    if (field.getKind() == Kind.Object) {
+                        assert values[i].getLIRKind().isReference(0) : field + ": " + valKind + " != " + field.getKind();
                     } else {
                         if ((valKind == Kind.Double || valKind == Kind.Long) && field.getKind() == Kind.Int) {
                             assert fields[fieldIndex].getKind() == Kind.Int;
@@ -156,9 +156,7 @@
                 Kind componentKind = type.getComponentType().getKind().getStackKind();
                 if (componentKind == Kind.Object) {
                     for (int i = 0; i < values.length; i++) {
-                        if (values[i] instanceof Value) {
-                            assert ((Value) values[i]).getLIRKind().isReference(0) : values[i].getKind() + " != " + componentKind;
-                        }
+                        assert values[i].getLIRKind().isReference(0) : values[i].getKind() + " != " + componentKind;
                     }
                 } else {
                     for (int i = 0; i < values.length; i++) {
@@ -177,7 +175,7 @@
      * @param values an array containing all the values to be stored into the object when it is
      *            recreated.
      */
-    public void setValues(JavaValue[] values) {
+    public void setValues(Value[] values) {
         assert checkValues(type, values);
         this.values = values;
     }
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Tue Mar 03 17:13:51 2015 -0800
@@ -22,6 +22,11 @@
  */
 package com.oracle.graal.asm.sparc;
 
+import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Op3s.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.sparc.SPARC.*;
 
@@ -31,6 +36,7 @@
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.calc.*;
 import com.oracle.graal.sparc.*;
+import com.oracle.graal.sparc.SPARC.CPUFeature;
 
 /**
  * This class implements an assembler that can encode most SPARC instructions.
@@ -49,10 +55,6 @@
         super(target);
     }
 
-    public interface AssemblerEmittable {
-        void emit(SPARCAssembler masm);
-    }
-
     public static final int CCR_ICC_SHIFT = 0;
     public static final int CCR_XCC_SHIFT = 4;
     public static final int CCR_C_SHIFT = 0;
@@ -60,1437 +62,32 @@
     public static final int CCR_Z_SHIFT = 2;
     public static final int CCR_N_SHIFT = 3;
 
-    // @formatter:off
-    /**
-     * Instruction format for Fmt00 instructions. This abstraction is needed as it
-     * makes the patching easier later on.
-     * <pre>
-     * | 00  |  ??    | op2 |               ??                        |
-     * |31 30|29    25|24 22|21                                      0|
-     * </pre>
-     */
-    // @formatter:on
-    public abstract static class Fmt00 implements AssemblerEmittable {
-
-        protected static final int OP_SHIFT = 30;
-        protected static final int CBCOND_SHIFT = 28;
-        protected static final int OP2_SHIFT = 22;
-        protected static final int A_SHIFT = 29;
-
-        // @formatter:off
-        protected static final int A_MASK        = 0b0010_0000_0000_0000_0000_0000_0000_0000;
-        protected static final int OP_MASK     = 0b1100_0000_0000_0000_0000_0000_0000_0000;
-        protected static final int CBCOND_MASK = 0b0001_0000_0000_0000_0000_0000_0000_0000; // Used for distinguish CBcond and BPr instructions
-        protected static final int OP2_MASK    = 0b0000_0001_1100_0000_0000_0000_0000_0000;
-        // @formatter:off
-
-        private int op2;
-
-        public Fmt00(int op2) {
-            this.op2 = op2;
-        }
-
-        public static Fmt00 read(SPARCAssembler masm, int pos) {
-            final int inst = masm.getInt(pos);
-            Op2s op2 = Op2s.byValue((inst & OP2_MASK) >> OP2_SHIFT);
-            switch(op2) {
-                case Br:
-                case Fb:
-                    return Fmt00b.read(masm, op2, pos);
-                case Sethi:
-                case Illtrap:
-                    return Fmt00a.read(masm, pos);
-                case Bp:
-                    return Fmt00c.read(masm, pos);
-                case Bpr:
-                    boolean isCBcond = (inst & CBCOND_MASK) != 0;
-                    if (isCBcond) {
-                        return Fmt00e.read(masm, pos);
-                    } else {
-                        return Fmt00d.read(masm, pos);
-                    }
-                default:
-                    throw GraalInternalError.shouldNotReachHere("Unknown op2 " + op2);
-            }
-        }
-
-        public void write(SPARCAssembler masm, int pos) {
-            verify();
-            masm.emitInt(getInstructionBits(), pos);
-        }
-
-        public Op2s getOp2s() {
-            return Op2s.byValue(op2);
-        }
-
-        protected int getInstructionBits() {
-            return Ops.BranchOp.getValue() << OP_SHIFT | op2 << OP2_SHIFT;
-        }
-
-        public void verify() {
-            assert ((op2 << OP2_SHIFT) & OP2_MASK) == (op2 << OP2_SHIFT) : Integer.toHexString(op2);
-            assert Op2s.byValue(op2) != null : op2;
-        }
-        /**
-         * Sets the immediate (displacement) value on this instruction.
-         *
-         * @see SPARCAssembler#patchJumpTarget(int, int)
-         * @param imm Displacement/imediate value. Can either be a 22 or 19 bit immediate (dependent on the instruction)
-         */
-        public abstract void setImm(int imm);
-
-        public abstract void emit(SPARCAssembler masm);
-
-        public boolean hasDelaySlot() {
-            return true;
-        }
-
-        public int getA() {
-            throw GraalInternalError.shouldNotReachHere();
-        }
-        public void setA(@SuppressWarnings("unused") int a) {
-            throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
-    // @formatter:off
-    /**
-     * Instruction format for sethi.
-     * <pre>
-     * | 00  |  rd    | op2 |               imm22                     |
-     * |31 30|29    25|24 22|21                                      0|
-     * </pre>
-     */
-    // @formatter:on
-    public static class Fmt00a extends Fmt00 implements AssemblerEmittable {
-
-        private static final int RD_SHIFT = 25;
-        private static final int IMM22_SHIFT = 0;
-
-        // @formatter:off
-        private static final int RD_MASK    = 0b00111110000000000000000000000000;
-        private static final int IMM22_MASK = 0b00000000001111111111111111111111;
-        // @formatter:on
-
-        private int rd;
-        private int imm22;
-
-        private Fmt00a(int rd, int op2, int imm22) {
-            super(op2);
-            this.rd = rd;
-            this.imm22 = imm22;
-            verify();
-        }
-
-        public Fmt00a(Op2s op2, int imm22, Register rd) {
-            this(rd.encoding(), op2.getValue(), imm22);
-        }
-
-        @Override
-        protected int getInstructionBits() {
-            return super.getInstructionBits() | rd << RD_SHIFT | (imm22 & IMM22_MASK) << IMM22_SHIFT;
-        }
-
-        public static Fmt00a read(SPARCAssembler masm, int pos) {
-            final int inst = masm.getInt(pos);
-
-            // Make sure it's the right instruction:
-            final int op = (inst & OP_MASK) >> OP_SHIFT;
-            assert op == Ops.BranchOp.getValue();
-
-            // Get the instruction fields:
-            final int rd = (inst & RD_MASK) >> RD_SHIFT;
-            final int op2 = (inst & OP2_MASK) >> OP2_SHIFT;
-            final int imm22 = (inst & IMM22_MASK) >> IMM22_SHIFT;
-
-            return new Fmt00a(op2, imm22, rd);
-        }
-
-        @Override
-        public void emit(SPARCAssembler masm) {
-            verify();
-            masm.emitInt(getInstructionBits());
-        }
-
-        @Override
-        public void verify() {
-            super.verify();
-            assert ((rd << RD_SHIFT) & RD_MASK) == (rd << RD_SHIFT);
-            assert ((imm22 << IMM22_SHIFT) & IMM22_MASK) == (imm22 << IMM22_SHIFT) : String.format("imm22: %d (%x)", imm22, imm22);
-        }
-
-        @Override
-        public void setImm(int imm) {
-            setImm22(imm);
-        }
-
-        public void setImm22(int imm22) {
-            this.imm22 = imm22;
-        }
-
-        @Override
-        public boolean hasDelaySlot() {
-            return false;
-        }
-    }
-
-    // @formatter:off
-    /**
-     * Instruction format for branches.
-     * <pre>
-     * | 00  |a | cond | op2 |             disp22                      |
-     * |31 30|29|28  25|24 22|21                                      0|
-     * </pre>
-     */
-    // @formatter:on
-    public static class Fmt00b extends Fmt00 {
-        private int a;
-        private int cond;
-        private int disp22;
-        private Label label;
-
-        private static final int COND_SHIFT = 25;
-        private static final int DISP22_SHIFT = 0;
-
-        // @formatter:off
-        private static final int COND_MASK   = 0b00011110000000000000000000000000;
-        private static final int DISP22_MASK = 0b00000000001111111111111111111111;
-        // @formatter:on
-
-        public Fmt00b(boolean annul, ConditionFlag cond, Op2s op2, Label label) {
-            this(annul ? 1 : 0, cond.getValue(), op2.getValue(), 0, label);
-        }
-
-        public Fmt00b(boolean annul, FCond cond, Op2s op2, Label label) {
-            this(annul ? 1 : 0, cond.getValue(), op2.getValue(), 0, label);
-        }
-
-        public Fmt00b(int annul, int cond, int op2, Label label) {
-            this(annul, cond, op2, 0, label);
-        }
-
-        public Fmt00b(boolean annul, FCond cond, Op2s op2, int disp22) {
-            this(annul ? 1 : 0, cond.getValue(), op2.getValue(), disp22, null);
-        }
-
-        public Fmt00b(int annul, int cond, int op2, int disp22) {
-            this(annul, cond, op2, disp22, null);
-        }
-
-        public Fmt00b(int a, int cond, int op2, int disp22, Label label) {
-            super(op2);
-            setA(a);
-            setCond(cond);
-            setDisp22(disp22);
-            setLabel(label);
-        }
-
-        @Override
-        public void emit(SPARCAssembler masm) {
-            if (label != null) {
-                final int pos = label.isBound() ? label.position() : patchUnbound(masm, label);
-                final int disp = pos - masm.position();
-                setDisp22(disp);
-            }
-            verify();
-            masm.emitInt(getInstructionBits());
-        }
-
-        private static int patchUnbound(SPARCAssembler masm, Label label) {
-            label.addPatchAt(masm.position());
-            return 0;
-        }
-
-        @Override
-        protected int getInstructionBits() {
-            int inst = super.getInstructionBits() | a << A_SHIFT | cond << COND_SHIFT | (disp22 & DISP22_MASK) << DISP22_SHIFT;
-            return inst;
-        }
-
-        protected static Fmt00b read(SPARCAssembler masm, Op2s op2, int pos) {
-            final int inst = masm.getInt(pos);
-
-            // Make sure it's the right instruction:
-            final int op = (inst & OP_MASK) >> OP_SHIFT;
-            assert op == Ops.BranchOp.getValue();
-            final int op2Read = (inst & OP2_MASK) >> OP2_SHIFT;
-            assert op2Read == op2.getValue() : "Op2 value read: " + op2Read + " Required op2: " + op2;
-
-            // Get the instruction fields:
-            final int a = (inst & A_MASK) >> A_SHIFT;
-            final int cond = (inst & COND_MASK) >> COND_SHIFT;
-            final int disp22 = (inst & DISP22_MASK) >> DISP22_SHIFT << 2;
-
-            Fmt00b fmt = new Fmt00b(a, cond, op2.getValue(), disp22);
-            fmt.verify();
-            return fmt;
-        }
-
-        @Override
-        public int getA() {
-            return a;
-        }
-
-        @Override
-        public void setA(int a) {
-            this.a = a;
-        }
-
-        public int getCond() {
-            return cond;
-        }
-
-        public void setCond(int cond) {
-            this.cond = cond;
-        }
-
-        public int getDisp22() {
-            return disp22 << 2;
-        }
-
-        @Override
-        public void setImm(int imm) {
-            setDisp22(imm);
-        }
-
-        public void setDisp22(int disp22) {
-            this.disp22 = disp22 >> 2;
-        }
-
-        public Label getLabel() {
-            return label;
-        }
-
-        public void setLabel(Label label) {
-            this.label = label;
-        }
-
-        @Override
-        public void verify() {
-            super.verify();
-            assert (getA() << A_SHIFT & ~A_MASK) == 0 : getA();
-            assert (getCond() << COND_SHIFT & ~COND_MASK) == 0 : getCond();
-        }
-    }
-
-    // @formatter:off
-    /**
-     * Instruction format for conditional branches.
-     * <pre>
-     * | 00  |a | cond | op2 |cc1|cc0|p |             disp19           |
-     * |31 30|29|28  25|24 22|21 |20 |19|                             0|
-     * </pre>
-     */
-    // @formatter:on
-    public static class Fmt00c extends Fmt00 {
-
-        private static final int COND_SHIFT = 25;
-        private static final int CC_SHIFT = 20;
-        private static final int P_SHIFT = 19;
-        private static final int DISP19_SHIFT = 0;
-
-        // @formatter:off
-        private static final int COND_MASK   = 0b00011110000000000000000000000000;
-        private static final int CC_MASK     = 0b00000000001100000000000000000000;
-        private static final int P_MASK      = 0b00000000000010000000000000000000;
-        private static final int DISP19_MASK = 0b00000000000001111111111111111111;
-        // @formatter:on
-
-        private int a;
-        private int cond;
-        private int cc;
-        private int p;
-        private int disp19;
-        private Label label;
-
-        private Fmt00c(int a, int cond, int op2, int cc, int p, int disp19) {
-            super(op2);
-            setA(a);
-            setCond(cond);
-            setCc(cc);
-            setP(p);
-            setDisp19(disp19);
-            verify();
-        }
+    protected static final int OP_SHIFT = 30;
+    protected static final int CBCOND_SHIFT = 28;
+    protected static final int OP2_SHIFT = 22;
+    protected static final int A_SHIFT = 29;
 
-        public Fmt00c(int a, ConditionFlag cond, Op2s op2, CC cc, int p, int disp19) {
-            this(a, cond.getValue(), op2.getValue(), cc.getValue(), p, disp19);
-        }
-
-        public Fmt00c(int a, ConditionFlag cond, Op2s op2, CC cc, int p, Label label) {
-            this(a, cond.getValue(), op2.getValue(), cc.getValue(), p, 0);
-            this.label = label;
-        }
-
-        @Override
-        public int getA() {
-            return a;
-        }
-
-        @Override
-        public void setA(int a) {
-            this.a = a;
-        }
-
-        public int getCond() {
-            return cond;
-        }
-
-        public void setCond(int cond) {
-            this.cond = cond;
-        }
-
-        public int getCc() {
-            return cc;
-        }
-
-        public void setCc(int cc) {
-            this.cc = cc;
-        }
-
-        public int getP() {
-            return p;
-        }
-
-        public void setP(int p) {
-            this.p = p;
-        }
-
-        /**
-         * Return the displacement in bytes.
-         */
-        public int getDisp19() {
-            return disp19 << 2;
-        }
-
-        /**
-         * The instructions requires displacements to be word-sized.
-         */
-        public void setDisp19(int disp19) {
-            this.disp19 = disp19 >> 2;
-        }
-
-        @Override
-        public void setImm(int imm) {
-            setDisp19(imm);
-        }
-
-        @Override
-        protected int getInstructionBits() {
-            return super.getInstructionBits() | a << A_SHIFT | cond << COND_SHIFT | cc << CC_SHIFT | p << P_SHIFT | (disp19 & DISP19_MASK) << DISP19_SHIFT;
-        }
-
-        public static Fmt00c read(SPARCAssembler masm, int pos) {
-            final int inst = masm.getInt(pos);
-
-            // Make sure it's the right instruction:
-            final int op = (inst & OP_MASK) >> OP_SHIFT;
-            assert op == Ops.BranchOp.getValue();
-
-            // Get the instruction fields:
-            final int a = (inst & A_MASK) >> A_SHIFT;
-            final int cond = (inst & COND_MASK) >> COND_SHIFT;
-            final int op2 = (inst & OP2_MASK) >> OP2_SHIFT;
-            final int cc = (inst & CC_MASK) >> CC_SHIFT;
-            final int p = (inst & P_MASK) >> P_SHIFT;
-            final int disp19 = (inst & DISP19_MASK) >> DISP19_SHIFT << 2;
-
-            Fmt00c fmt = new Fmt00c(a, cond, op2, cc, p, disp19);
-            fmt.verify();
-            return fmt;
-        }
-
-        @Override
-        public void emit(SPARCAssembler masm) {
-            if (label != null) {
-                final int pos = label.isBound() ? label.position() : patchUnbound(masm, label);
-                final int disp = pos - masm.position();
-                setDisp19(disp);
-            }
-            verify();
-            masm.emitInt(getInstructionBits());
-        }
-
-        private static int patchUnbound(SPARCAssembler masm, Label label) {
-            label.addPatchAt(masm.position());
-            return 0;
-        }
-
-        @Override
-        public void verify() {
-            super.verify();
-            assert p < 2;
-            assert cond < 0x10;
-        }
-
-        @Override
-        public String toString() {
-            return "Fmt00c [a=" + a + ", cond=" + cond + ", cc=" + cc + ", p=" + p + ", disp19=" + disp19 + ", label=" + label + "]";
-        }
-    }
-
-    // @formatter:off
-    /**
-     * Instruction format for Branch on Integer Register with Prediction.
-     * <pre>
-     * |00   |a |- |rcond | 011 |d16hi|p | rs1 |          d16lo           |
-     * |31 30|29|28|27  25|24 22|21 20|19|18 14|                         0|
-     * </pre>
-     */
-    // @formatter:on
-    public static class Fmt00d extends Fmt00 {
-
-        private static final int RCOND_SHIFT = 25;
-        private static final int D16HI_SHIFT = 20;
-        private static final int P_SHIFT = 19;
-        private static final int RS1_SHIFT = 14;
-        private static final int D16LO_SHIFT = 0;
-
-        // @formatter:off
-        private static final int RCOND_MASK    = 0b0000_1110_0000_0000_0000_0000_0000_0000;
-        private static final int D16HI_MASK    = 0b0000_0000_0011_0000_0000_0000_0000_0000;
-        private static final int P_MASK        = 0b0000_0000_0000_1000_0000_0000_0000_0000;
-        private static final int RS1_MASK      = 0b0000_0000_0000_0111_1100_0000_0000_0000;
-        private static final int D16LO_MASK    = 0b0000_0000_0000_0000_0011_1111_1111_1111;
-        // @formatter:on
-
-        private int annul;
-        private int rCondition;
-        private int disp16;
-        private int predictTaken;
-        private int rs1;
-        private Label label;
-
-        public Fmt00d(int op2, int rCondition, int predictTaken, int annul, int d16, int rs1, Label label) {
-            super(op2);
-            this.annul = annul;
-            this.rCondition = rCondition;
-            setDisp16(d16);
-            this.predictTaken = predictTaken;
-            this.rs1 = rs1;
-            this.label = label;
-        }
-
-        @Override
-        public void setImm(int imm) {
-            setDisp16(imm);
-        }
-
-        public void setDisp16(int disp16) {
-            this.disp16 = disp16 >> 2;
-        }
-
-        @Override
-        public int getA() {
-            return annul;
-        }
-
-        @Override
-        public void emit(SPARCAssembler masm) {
-            if (label != null) {
-                final int pos = label.isBound() ? label.position() : patchUnbound(masm, label);
-                final int disp = pos - masm.position();
-                setDisp16(disp);
-            }
-            verify();
-            masm.emitInt(getInstructionBits());
-        }
-
-        private static int patchUnbound(SPARCAssembler masm, Label label) {
-            label.addPatchAt(masm.position());
-            return 0;
-        }
-
-        @Override
-        protected int getInstructionBits() {
-            int d16Split = 0;
-            d16Split |= (disp16 & 0b1100_0000_0000_0000) << D16HI_SHIFT - 14;
-            d16Split |= (disp16 & 0b0011_1111_1111_1111) << D16LO_SHIFT;
-            return super.getInstructionBits() | annul << A_SHIFT | rCondition << RCOND_SHIFT | d16Split | predictTaken << P_SHIFT | rs1 << RS1_SHIFT;
-        }
-
-        public static Fmt00d read(SPARCAssembler masm, int pos) {
-            final int inst = masm.getInt(pos);
-
-            // Make sure it's the right instruction:
-            final int op = (inst & OP_MASK) >> OP_SHIFT;
-            final int op2 = (inst & OP2_MASK) >> OP2_SHIFT;
-            final int condFlag = (inst & CBCOND_MASK) >> CBCOND_SHIFT;
-            assert op2 == Op2s.Bpr.getValue() && op == Ops.BranchOp.getValue() && condFlag == 0 : "0x" + Integer.toHexString(inst);
-
-            // Get the instruction fields:
-            final int a = (inst & A_MASK) >> A_SHIFT;
-            final int cond = (inst & RCOND_MASK) >> RCOND_SHIFT;
-            final int p = (inst & P_MASK) >> P_SHIFT;
-            final int rs1 = (inst & RS1_MASK) >> RS1_SHIFT;
-            final int d16hi = (inst & D16HI_MASK) >> D16HI_SHIFT;
-            assert (d16hi & ~0b11) == 0;
-            final int d16lo = (inst & D16LO_MASK) >> D16LO_SHIFT;
-            assert (d16lo & ~((1 << 14) - 1)) == 0;
-            final int d16 = (short) (((d16hi << 14) | d16lo) << 2); // times 4 and sign extend
-            Fmt00d fmt = new Fmt00d(op2, cond, p, a, d16, rs1, null);
-            fmt.verify();
-            return fmt;
-        }
-
-        @Override
-        public void verify() {
-            super.verify();
-            assert (annul & ~1) == 0 : annul;
-            assert (rCondition & ~0b111) == 0 : rCondition;
-            assert isSimm(disp16, 16) : disp16;
-            assert (predictTaken & ~1) == 0 : predictTaken;
-            assert (rs1 & ~((1 << 5) - 1)) == 0 : rs1;
-        }
-    }
-
-    // @formatter:off
-    /**
-     * Instruction format CBcond.
-     * <pre>
-     * |00   |chi|1 | clo | 011 |cc2|d10hi|rs1  |i |d10lo|rs2/simm5|
-     * |31 30|29 |28|27 25|24 22|21 |20 19|18 14|13|12  5|4       0|
-     * </pre>
-     */
-    // @formatter:on
-    public static class Fmt00e extends Fmt00 {
-        private static final int CHI_SHIFT = 29;
-        private static final int CLO_SHIFT = 25;
-        private static final int CC2_SHIFT = 21;
-        private static final int D10HI_SHIFT = 19;
-        private static final int RS1_SHIFT = 14;
-        private static final int I_SHIFT = 13;
-        private static final int D10LO_SHIFT = 5;
-        private static final int RS2_SHIFT = 0;
-
-        // @formatter:off
-        private static final int CHI_MASK      = 0b0010_0000_0000_0000_0000_0000_0000_0000;
-        private static final int CLO_MASK      = 0b0000_1110_0000_0000_0000_0000_0000_0000;
-        private static final int CC2_MASK      = 0b0000_0000_0010_0000_0000_0000_0000_0000;
-        private static final int D10HI_MASK    = 0b0000_0000_0001_1000_0000_0000_0000_0000;
-        private static final int RS1_MASK      = 0b0000_0000_0000_0111_1100_0000_0000_0000;
-        private static final int I_MASK        = 0b0000_0000_0000_0000_0010_0000_0000_0000;
-        private static final int D10LO_MASK    = 0b0000_0000_0000_0000_0001_1111_1110_0000;
-        private static final int RS2_MASK      = 0b0000_0000_0000_0000_0000_0000_0001_1111;
-        // @formatter:on
-
-        private int c;
-        private int cc2;
-        private int disp10;
-        private int rs1;
-        private int i;
-        private int regOrImmediate;
-        private Label label;
-
-        public Fmt00e(int c, int cc2, int rs1, int disp10, int i, int regOrImmediate, Label label) {
-            super(Op2s.Bpr.getValue());
-            this.c = c;
-            this.cc2 = cc2;
-            this.rs1 = rs1;
-            setDisp10(disp10);
-            this.i = i;
-            this.regOrImmediate = regOrImmediate;
-            this.label = label;
-        }
-
-        @Override
-        public void setImm(int imm) {
-            setDisp10(imm);
-        }
-
-        public void setDisp10(int disp10) {
-            this.disp10 = disp10 >> 2;
-            if (!isSimm10(this.disp10)) {
-                throw GraalInternalError.shouldNotReachHere("" + this.disp10);
-            }
-            assert isSimm10(this.disp10) : this.disp10;
-        }
-
-        @Override
-        public void emit(SPARCAssembler masm) {
-            assert masm.hasFeature(CPUFeature.CBCOND);
-            if (label != null) {
-                if (label.isBound()) {
-                    final int disp = label.position() - masm.position();
-                    setDisp10(disp);
-                } else {
-                    patchUnbound(masm, label);
-                    setDisp10(0);
-                }
-            }
-            verify();
-            masm.emitInt(getInstructionBits());
-        }
-
-        private static int patchUnbound(SPARCAssembler masm, Label label) {
-            label.addPatchAt(masm.position());
-            return 0;
-        }
-
-        @Override
-        protected int getInstructionBits() {
-            int cSplit = 0;
-            cSplit |= (c & 0b1000) << CHI_SHIFT - 3;
-            cSplit |= (c & 0b0111) << CLO_SHIFT;
-            int d10Split = 0;
-            d10Split |= (disp10 & 0b11_0000_0000) << D10HI_SHIFT - 8;
-            d10Split |= (disp10 & 0b00_1111_1111) << D10LO_SHIFT;
-            int bits = super.getInstructionBits() | 1 << 28 | cSplit | cc2 << CC2_SHIFT | d10Split | rs1 << RS1_SHIFT | i << I_SHIFT | (regOrImmediate & 0b1_1111) << RS2_SHIFT;
-            int hibits = (bits & 0xFF000000);
-            if (hibits == 0xFF000000 || hibits == 0) {
-                throw GraalInternalError.shouldNotReachHere();
-            }
-            return bits;
-        }
-
-        public static Fmt00e read(SPARCAssembler masm, int pos) {
-            assert masm.hasFeature(CPUFeature.CBCOND);
-            final int inst = masm.getInt(pos);
-
-            // Make sure it's the right instruction:
-            final int op = (inst & OP_MASK) >> OP_SHIFT;
-            final int op2 = (inst & OP2_MASK) >> OP2_SHIFT;
-            final int condFlag = (inst & CBCOND_MASK) >> CBCOND_SHIFT;
-            assert op2 == Op2s.Bpr.getValue() && op == Ops.BranchOp.getValue() && condFlag == 1 : "0x" + Integer.toHexString(inst);
-
-            // @formatter:off
-            // Get the instruction fields:
-            final int chi =            (inst & CHI_MASK)   >> CHI_SHIFT;
-            final int clo =            (inst & CLO_MASK)   >> CLO_SHIFT;
-            final int cc2 =            (inst & CC2_MASK)   >> CC2_SHIFT;
-            final int d10hi =          (inst & D10HI_MASK) >> D10HI_SHIFT;
-            final int rs1 =            (inst & RS1_MASK)   >> RS1_SHIFT;
-            final int i =              (inst & I_MASK)     >> I_SHIFT;
-            final int d10lo =          (inst & D10LO_MASK) >> D10LO_SHIFT;
-                  int regOrImmediate = (inst & RS2_MASK)   >> RS2_SHIFT;
-            // @formatter:on
-            if (i == 1) { // if immediate, we do sign extend
-                int shiftcnt = 31 - 4;
-                regOrImmediate = (regOrImmediate << shiftcnt) >> shiftcnt;
-            }
-            int c = chi << 3 | clo;
+    protected static final int A_MASK = 0b0010_0000_0000_0000_0000_0000_0000_0000;
+    protected static final int OP_MASK = 0b1100_0000_0000_0000_0000_0000_0000_0000;
+    protected static final int CBCOND_MASK = 0b0001_0000_0000_0000_0000_0000_0000_0000; // Used for
+    // distinguish CBcond and BPr instructions
+    protected static final int OP2_MASK = 0b0000_0001_1100_0000_0000_0000_0000_0000;
 
-            assert (d10lo & ~((1 << 8) - 1)) == 0;
-            final int d10 = ((short) (((d10hi << 8) | d10lo) << 6)) >> 4; // Times 4 and sign extend
-            Fmt00e fmt = new Fmt00e(c, cc2, rs1, d10, i, regOrImmediate, null);
-            fmt.verify();
-            return fmt;
-        }
-
-        @Override
-        public void verify() {
-            super.verify();
-            assert (c & ~0b1111) == 0 : c;
-            assert (cc2 & ~1) == 0 : cc2;
-            assert isSimm(disp10, 10) : disp10;
-            assert (rs1 & ~0b1_1111) == 0 : rs1;
-            assert (i & ~1) == 0 : i;
-            if (i == 1) {
-                assert isSimm(regOrImmediate, 5) : regOrImmediate;
-            } else {
-                assert (regOrImmediate & ~0b1_1111) == 0 : regOrImmediate;
-            }
-        }
-
-        @Override
-        public boolean hasDelaySlot() {
-            return false;
-        }
-    }
-
-    // @formatter:off
-    /**
-     * Instruction format for calls.
-     * <pre>
-     * | 01  |                      disp30                             |
-     * |31 30|29                                                      0|
-     * </pre>
-     */
-    // @formatter:on
-    public static class Fmt01 {
-
-        private static final int OP_SHIFT = 30;
-        private static final int DISP30_SHIFT = 0;
-
-        // @formatter:off
-        private static final int OP_MASK     = 0b11000000000000000000000000000000;
-        private static final int DISP30_MASK = 0b00111111111111111111111111111111;
-        // @formatter:on
-
-        private int disp30;
-
-        public Fmt01(int disp30) {
-            setDisp30(disp30);
-        }
-
-        /**
-         * Return the displacement in bytes.
-         */
-        public int getDisp30() {
-            return disp30 << 2;
-        }
-
-        /**
-         * The instructions requires displacements to be word-sized.
-         */
-        public void setDisp30(int disp30) {
-            this.disp30 = disp30 >> 2;
-        }
-
-        private int getInstructionBits() {
-            return Ops.CallOp.getValue() << OP_SHIFT | (disp30 & DISP30_MASK) << DISP30_SHIFT;
-        }
-
-        public static Fmt01 read(SPARCAssembler masm, int pos) {
-            final int inst = masm.getInt(pos);
-
-            // Make sure it's the right instruction:
-            final int op = (inst & OP_MASK) >> OP_SHIFT;
-            assert op == Ops.CallOp.getValue();
-
-            // Get the instruction fields:
-            final int disp30 = (inst & DISP30_MASK) >> DISP30_SHIFT << 2;
-
-            Fmt01 fmt = new Fmt01(disp30);
-            fmt.verify();
-            return fmt;
-        }
-
-        public void write(SPARCAssembler masm, int pos) {
-            verify();
-            masm.emitInt(getInstructionBits(), pos);
-        }
-
-        public void emit(SPARCAssembler masm) {
-            verify();
-            masm.emitInt(getInstructionBits());
-        }
-
-        public void verify() {
-            assert isDisp30(disp30) : disp30;
-        }
-    }
-
-    public static class Fmt3f {
-
-        public Fmt3f(SPARCAssembler masm, int op, int op3, int rcond, int rs1, int simm10, int rd) {
-            assert op == 2 || op == 3;
-            assert op3 >= 0 && op3 < 0x40;
-            assert rs1 >= 0 && rs1 < 0x20;
-            assert rd >= 0 && rd < 0x20;
-
-            masm.emitInt(op << 30 | rd << 25 | op3 << 19 | ImmedTrue | rs1 << 14 | rcond << 10 | (simm10 & 0x000003ff));
-        }
-    }
-
-    public static class Fmt3n {
-        private int op;
-        private int op3;
-        private int opf;
-        private int rs2;
-        private int rd;
-
-        public Fmt3n(int op, int op3, int opf, int rs2, int rd) {
-            this.op = op;
-            this.op3 = op3;
-            this.opf = opf;
-            this.rs2 = rs2;
-            this.rd = rd;
-        }
-
-        public void emit(SPARCAssembler masm) {
-            verify();
-            masm.emitInt(op << 30 | rd << 25 | op3 << 19 | opf << 5 | rs2);
-        }
-
-        public void verify() {
-            assert op == 2 || op == 3;
-            assert op3 >= 0 && op3 < 0x40;
-            assert opf >= 0 && opf < 0x200;
-            assert rs2 >= 0 && rs2 < 0x20;
-            assert rd >= 0 && rd < 0x20;
-        }
-    }
-
-    public static class Fmt3p {
-
-        private int op;
-        private int op3;
-        private int opf;
-        private int rs1;
-        private int rs2;
-        private int rd;
-
-        public Fmt3p(Ops op, Op3s op3, Opfs opf, Register rs1, Register rs2, Register rd) {
-            this.op = op.getValue();
-            this.op3 = op3.getValue();
-            this.opf = opf.getValue();
-            this.rs1 = rs1.encoding();
-            this.rs2 = rs2.encoding();
-            this.rd = rd.encoding();
-        }
-
-        public void emit(SPARCAssembler masm) {
-            assert op == 2 || op == 3 : op;
-            assert op3 >= 0 && op3 < 0x40 : op3;
-            assert opf >= 0 && opf < 0x200 : opf;
-            assert rs1 >= 0 && rs1 < 0x20 : rs1;
-            assert rs2 >= 0 && rs2 < 0x20 : rs2;
-            assert rd >= 0 && rd < 0x20 : rd;
-
-            masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | opf << 5 | rs2);
-        }
-    }
+    protected static final int DISP22_SHIFT = 0;
+    protected static final int DISP22_MASK = 0b00000000001111111111111111111111;
 
-    // @formatter:off
-    /**
-     * Instruction format for fcmp.
-     * <pre>
-     * | 10  | --- |cc1|cc0|desc |   rs1   |   opf  | rs2 |
-     * |31 30|29 27|26 |25 |24 19|18     14|13     5|4   0|
-     * </pre>
-     */
-    // @formatter:on
-    public static class Fmt3c {
-        private int op;
-        private int cc;
-        private int desc;
-        private int opf;
-        private int rs1;
-        private int rs2;
-
-        public Fmt3c(Ops op, CC cc, int desc, Opfs opf, Register rs1, Register rs2) {
-            this.op = op.getValue();
-            this.opf = opf.getValue();
-            this.desc = desc;
-            this.rs1 = rs1.encoding();
-            this.rs2 = rs2.encoding();
-            this.cc = cc.getValue();
-        }
-
-        public void emit(SPARCAssembler masm) {
-            assert op == 2 || op == 3;
-            assert cc >= 0 && cc < 0x4;
-            assert opf >= 0 && opf < 0x200;
-            assert rs1 >= 0 && rs1 < 0x20;
-            assert rs2 >= 0 && rs2 < 0x20;
-            assert desc >= 0 && desc < 0x40;
-
-            masm.emitInt(op << 30 | cc << 25 | desc << 19 | rs1 << 14 | opf << 5 | rs2);
-        }
-    }
-
-    // @formatter:off
-    /**
-     * Instruction format for Arithmetic, Logical, Moves, Tcc, Prefetch, and Misc.
-     * <pre>
-     * | 10  |   rd   |   op3   |   rs1   | i|     imm_asi   |   rs2   |
-     * | 10  |   rd   |   op3   |   rs1   | i|          simm13         |
-     * | 10  |   rd   |   op3   |   rs1   | i| x|            |   rs2   |
-     * | 10  |   rd   |   op3   |   rs1   | i| x|            | shcnt32 |
-     * | 10  |   rd   |   op3   |   rs1   | i| x|            | shcnt64 |
-     * |31 30|29    25|24     19|18     14|13|12|11         5|4       0|
-     * </pre>
-     */
-    // @formatter:on
-    public static class Fmt10 implements AssemblerEmittable {
-
-        private static final int OP_SHIFT = 30;
-        private static final int RD_SHIFT = 25;
-        private static final int OP3_SHIFT = 19;
-        private static final int RS1_SHIFT = 14;
-        private static final int I_SHIFT = 13;
-        private static final int X_SHIFT = 12;
-        private static final int IMM_ASI_SHIFT = 5;
-        private static final int RS2_SHIFT = 0;
-        private static final int SIMM13_SHIFT = 0;
-
-        // @formatter:off
-        private static final int OP_MASK      = 0b11000000000000000000000000000000;
-        private static final int RD_MASK      = 0b00111110000000000000000000000000;
-        private static final int OP3_MASK     = 0b00000001111110000000000000000000;
-        private static final int RS1_MASK     = 0b00000000000001111100000000000000;
-        private static final int I_MASK       = 0b00000000000000000010000000000000;
-        private static final int X_MASK       = 0b00000000000000000001000000000000;
-        private static final int IMM_ASI_MASK = 0b00000000000000000001111111100000;
-        private static final int RS2_MASK     = 0b00000000000000000000000000011111;
-        private static final int SIMM13_MASK  = 0b00000000000000000001111111111111;
-        // @formatter:on
-
-        private int rd;
-        private int op3;
-        private int rs1;
-        private int i;
-        private int x;
-        private int immAsi;
-        private int rs2;
-        private int simm13;
-
-        private Fmt10(int rd, int op3, int rs1, int i, int x, int immAsi, int rs2, int simm13) {
-            this.rd = rd;
-            this.op3 = op3;
-            this.rs1 = rs1;
-            this.i = i;
-            this.x = x;
-            this.immAsi = immAsi;
-            this.rs2 = rs2;
-            this.simm13 = simm13;
-            verify();
-        }
-
-        public Fmt10(Op3s op3, Register rs1, Register rs2, Register rd) {
-            this(rd.encoding(), op3.getValue(), rs1.encoding(), 0, getXBit(op3), 0, rs2.encoding(), 0);
-        }
-
-        public Fmt10(Op3s op3, Register rs1, int simm13, Register rd) {
-            this(rd.encoding(), op3.getValue(), rs1.encoding(), 1, getXBit(op3), 0, 0, simm13);
-        }
-
-        /**
-         * Used for trap on Integer Condition Codes (Tcc).
-         *
-         * @param op3
-         * @param rs1
-         * @param simm13
-         * @param cf
-         */
-        public Fmt10(Op3s op3, Register rs1, int simm13, ConditionFlag cf) {
-            this(cf.getValue(), op3.getValue(), rs1.encoding(), 1, getXBit(op3), 0, 0, simm13);
-        }
-
-        public Fmt10(Op3s op3) {
-            this(0, op3.getValue(), 0, 0, getXBit(op3), 0, 0, 0);
-        }
-
-        public Fmt10(Op3s op3, Register rs1, Register rd) {
-            this(rd.encoding(), op3.getValue(), rs1.encoding(), 0, getXBit(op3), 0, 0, 0);
-        }
-
-        /**
-         * Helper method to determine if the instruction needs the X bit set.
-         */
-        private static int getXBit(Op3s op3) {
-            switch (op3) {
-                case Sllx:
-                case Srax:
-                case Srlx:
-                    return 1;
-                default:
-                    return 0;
-            }
-        }
-
-        private int getInstructionBits() {
-            if (i == 0) {
-                return Ops.ArithOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | rs1 << RS1_SHIFT | i << I_SHIFT | x << X_SHIFT | immAsi << IMM_ASI_SHIFT | rs2 << RS2_SHIFT;
-            } else {
-                return Ops.ArithOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | rs1 << RS1_SHIFT | i << I_SHIFT | x << X_SHIFT | ((simm13 << SIMM13_SHIFT) & SIMM13_MASK);
-            }
-        }
-
-        public static Fmt10 read(SPARCAssembler masm, int pos) {
-            final int inst = masm.getInt(pos);
-
-            // Make sure it's the right instruction:
-            final int op = (inst & OP_MASK) >> OP_SHIFT;
-            assert op == Ops.ArithOp.getValue();
-
-            // Get the instruction fields:
-            final int rd = (inst & RD_MASK) >> RD_SHIFT;
-            final int op3 = (inst & OP3_MASK) >> OP3_SHIFT;
-            final int rs1 = (inst & RS1_MASK) >> RS1_SHIFT;
-            final int i = (inst & I_MASK) >> I_SHIFT;
-            final int x = (inst & X_MASK) >> X_SHIFT;
-            final int immAsi = (inst & IMM_ASI_MASK) >> IMM_ASI_SHIFT;
-            final int rs2 = (inst & RS2_MASK) >> RS2_SHIFT;
-            final int simm13 = (inst & SIMM13_MASK) >> SIMM13_SHIFT;
-
-            return new Fmt10(rd, op3, rs1, i, x, immAsi, rs2, simm13);
-        }
-
-        public void write(SPARCAssembler masm, int pos) {
-            verify();
-            masm.emitInt(getInstructionBits(), pos);
-        }
-
-        public void emit(SPARCAssembler masm) {
-            verify();
-            masm.emitInt(getInstructionBits());
-        }
-
-        public void verify() {
-            assert ((rd << RD_SHIFT) & RD_MASK) == (rd << RD_SHIFT) : this;
-            assert ((op3 << OP3_SHIFT) & OP3_MASK) == (op3 << OP3_SHIFT) : this;
-            assert ((rs1 << RS1_SHIFT) & RS1_MASK) == (rs1 << RS1_SHIFT) : this;
-            assert ((i << I_SHIFT) & I_MASK) == (i << I_SHIFT) : this;
-            assert ((x << X_SHIFT) & X_MASK) == (x << X_SHIFT) : this;
-            assert ((immAsi << IMM_ASI_SHIFT) & IMM_ASI_MASK) == (immAsi << IMM_ASI_SHIFT) : this;
-            assert ((rs2 << RS2_SHIFT) & RS2_MASK) == (rs2 << RS2_SHIFT) : this;
-            assert isSimm13(simm13) : this;
-        }
+    protected static final int DISP19_SHIFT = 0;
+    protected static final int DISP19_MASK = 0b00000000000001111111111111111111;
 
-        @Override
-        public String toString() {
-            return String.format("%s: [rd: 0x%x, op3: 0x%x, rs1: 0x%x, i: 0x%x, x: 0x%x, immAsi: 0x%x, rs2: 0x%x, simm13: 0x%x", getClass().getName(), rd, op3, rs1, i, x, immAsi, rs2, simm13);
-        }
-    }
-
-    // @formatter:off
-    /**
-     * Instruction format for Loads, Stores and Misc.
-     * <pre>
-     * | 11  |   rd   |   op3   |   rs1   | i|   imm_asi   |   rs2   |
-     * | 11  |   rd   |   op3   |   rs1   | i|        simm13         |
-     * |31 30|29    25|24     19|18     14|13|12          5|4       0|
-     * </pre>
-     */
-    // @formatter:on
-    public static class Fmt11 {
-
-        private static final int OP_SHIFT = 30;
-        private static final int RD_SHIFT = 25;
-        private static final int OP3_SHIFT = 19;
-        private static final int RS1_SHIFT = 14;
-        private static final int I_SHIFT = 13;
-        private static final int IMM_ASI_SHIFT = 5;
-        private static final int RS2_SHIFT = 0;
-        private static final int SIMM13_SHIFT = 0;
-
-        // @formatter:off
-        private static final int OP_MASK      = 0b11000000000000000000000000000000;
-        private static final int RD_MASK      = 0b00111110000000000000000000000000;
-        private static final int OP3_MASK     = 0b00000001111110000000000000000000;
-        private static final int RS1_MASK     = 0b00000000000001111100000000000000;
-        private static final int I_MASK       = 0b00000000000000000010000000000000;
-        private static final int IMM_ASI_MASK = 0b00000000000000000001111111100000;
-        private static final int RS2_MASK     = 0b00000000000000000000000000011111;
-        private static final int SIMM13_MASK  = 0b00000000000000000001111111111111;
-        // @formatter:on
-
-        private int rd;
-        private int op3;
-        private int rs1;
-        private int i;
-        private int immAsi;
-        private int rs2;
-        private int simm13;
-
-        private Fmt11(int rd, int op3, int rs1, int i, int immAsi, int rs2, int simm13) {
-            this.rd = rd;
-            this.op3 = op3;
-            this.rs1 = rs1;
-            this.i = i;
-            this.immAsi = immAsi;
-            this.rs2 = rs2;
-            this.simm13 = simm13;
-            verify();
-        }
-
-        public Fmt11(Op3s op3, Register rs1, Register rs2, Register rd) {
-            this(rd.encoding(), op3.getValue(), rs1.encoding(), 0, 0, rs2.encoding(), 0);
-        }
-
-        public Fmt11(Op3s op3, Register rs1, int simm13, Register rd) {
-            this(rd.encoding(), op3.getValue(), rs1.encoding(), 1, 0, 0, simm13);
-        }
-
-        public Fmt11(Op3s op3, Register rs1, Register rd) {
-            this(rd.encoding(), op3.getValue(), rs1.encoding(), 0, 0, 0, 0);
-        }
-
-        /**
-         * Special constructor for {@link Casa} and {@link Casxa}.
-         */
-        public Fmt11(Op3s op3, Register rs1, Register rs2, Register rd, Asi asi) {
-            this(rd.encoding(), op3.getValue(), rs1.encoding(), asi.isValid() ? 0 : 1, asi.isValid() ? asi.getValue() : 0, rs2.encoding(), 0);
-            assert asi.isValid() : "default asi is not supported yet";
-        }
-
-        /**
-         * Special constructor for loads and stores.
-         */
-        public Fmt11(Op3s op3, SPARCAddress addr, Register rd) {
-            this(rd.encoding(), op3.getValue(), addr.getBase().encoding(), 0, 0, 0, 0);
-            decodeAddress(addr);
-        }
-
-        /**
-         * Special constructor for {@link Prefetch} and Prefetcha.
-         */
-        public Fmt11(Op3s op3, SPARCAddress addr, Prefetch.Fcn fcn) {
-            this(fcn.getValue(), op3.getValue(), addr.getBase().encoding(), 0, 0, 0, 0);
-            decodeAddress(addr);
-        }
-
-        private void decodeAddress(SPARCAddress addr) {
-            if (!addr.getIndex().equals(Register.None)) {
-                this.rs2 = addr.getIndex().encoding();
-            } else {
-                this.simm13 = addr.getDisplacement();
-                this.i = 1;
-            }
-            verify();
-        }
-
-        private int getInstructionBits() {
-            if (i == 0) {
-                return Ops.LdstOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | rs1 << RS1_SHIFT | i << I_SHIFT | immAsi << IMM_ASI_SHIFT | rs2 << RS2_SHIFT;
-            } else {
-                return Ops.LdstOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | rs1 << RS1_SHIFT | i << I_SHIFT | ((simm13 << SIMM13_SHIFT) & SIMM13_MASK);
-            }
-        }
-
-        public static Fmt11 read(SPARCAssembler masm, int pos) {
-            final int inst = masm.getInt(pos);
-
-            // Make sure it's the right instruction:
-            final int op = (inst & OP_MASK) >> OP_SHIFT;
-            assert op == Ops.LdstOp.getValue();
-
-            // Get the instruction fields:
-            final int rd = (inst & RD_MASK) >> RD_SHIFT;
-            final int op3 = (inst & OP3_MASK) >> OP3_SHIFT;
-            final int rs1 = (inst & RS1_MASK) >> RS1_SHIFT;
-            final int i = (inst & I_MASK) >> I_SHIFT;
-            final int immAsi = (inst & IMM_ASI_MASK) >> IMM_ASI_SHIFT;
-            final int rs2 = (inst & RS2_MASK) >> RS2_SHIFT;
-            final int simm13 = (inst & SIMM13_MASK) >> SIMM13_SHIFT;
-
-            return new Fmt11(rd, op3, rs1, i, immAsi, rs2, simm13);
-        }
-
-        public void write(SPARCAssembler masm, int pos) {
-            verify();
-            masm.emitInt(getInstructionBits(), pos);
-        }
-
-        public void emit(SPARCAssembler masm) {
-            verify();
-            masm.emitInt(getInstructionBits());
-        }
-
-        public void verify() {
-            assert ((rd << RD_SHIFT) & RD_MASK) == (rd << RD_SHIFT) : rd;
-            assert ((op3 << OP3_SHIFT) & OP3_MASK) == (op3 << OP3_SHIFT) : op3;
-            assert ((rs1 << RS1_SHIFT) & RS1_MASK) == (rs1 << RS1_SHIFT) : rs1;
-            assert ((i << I_SHIFT) & I_MASK) == (i << I_SHIFT);
-            assert ((immAsi << IMM_ASI_SHIFT) & IMM_ASI_MASK) == (immAsi << IMM_ASI_SHIFT);
-            assert ((rs2 << RS2_SHIFT) & RS2_MASK) == (rs2 << RS2_SHIFT);
-            assert isSimm13(simm13) : String.format("simm13: %d (%x)", simm13, simm13);
-        }
-    }
-
-    // @formatter:off
-    /**
-     * Instruction format for Movcc.
-     * <pre>
-     * | 10  |   rd   |   op3   |cc2|   cond  | i|cc1|cc0|      -      |   rs2   |
-     * | 10  |   rd   |   op3   |cc2|   cond  | i|cc1|cc0|        simm11         |
-     * |31 30|29    25|24     19| 18|17     14|13| 12| 11|10          5|4       0|
-     * </pre>
-     */
-    // @formatter:on
-    public static class Fmt10c {
-
-        private static final int OP_SHIFT = 30;
-        private static final int RD_SHIFT = 25;
-        private static final int OP3_SHIFT = 19;
-        private static final int CC2_SHIFT = 18;
-        private static final int COND_SHIFT = 14;
-        private static final int I_SHIFT = 13;
-        private static final int CC1_SHIFT = 12;
-        private static final int CC0_SHIFT = 11;
-        private static final int RS2_SHIFT = 0;
-        private static final int SIMM11_SHIFT = 0;
+    protected static final int D16HI_SHIFT = 20;
+    protected static final int D16HI_MASK = 0b0000_0000_0011_0000_0000_0000_0000_0000;
+    protected static final int D16LO_SHIFT = 0;
+    protected static final int D16LO_MASK = 0b0000_0000_0000_0000_0011_1111_1111_1111;
 
-        // @formatter:off
-        private static final int OP_MASK     = 0b11000000000000000000000000000000;
-        private static final int RD_MASK     = 0b00111110000000000000000000000000;
-        private static final int OP3_MASK    = 0b00000001111110000000000000000000;
-        private static final int CC2_MASK    = 0b00000000000001000000000000000000;
-        private static final int COND_MASK   = 0b00000000000000111100000000000000;
-        private static final int I_MASK      = 0b00000000000000000010000000000000;
-        private static final int CC1_MASK    = 0b00000000000000000001000000000000;
-        private static final int CC0_MASK    = 0b00000000000000000000100000000000;
-        private static final int RS2_MASK    = 0b00000000000000000000000000011111;
-        private static final int SIMM11_MASK = 0b00000000000000000000011111111111;
-        // @formatter:on
-
-        private int rd;
-        private int op3;
-        private int cond;
-        private int i;
-        private int cc;
-        private int rs2;
-        private int simm11;
-
-        private Fmt10c(int rd, int op3, int cond, int i, int cc, int rs2, int simm11) {
-            this.rd = rd;
-            this.op3 = op3;
-            this.cond = cond;
-            this.i = i;
-            this.cc = cc;
-            this.rs2 = rs2;
-            this.simm11 = simm11;
-            verify();
-        }
-
-        public Fmt10c(Op3s op3, ConditionFlag cond, CC cc, Register rs2, Register rd) {
-            this(rd.encoding(), op3.getValue(), cond.getValue(), 0, getCC(cc), rs2.encoding(), 0);
-        }
-
-        public Fmt10c(Op3s op3, ConditionFlag cond, CC cc, int simm11, Register rd) {
-            this(rd.encoding(), op3.getValue(), cond.getValue(), 1, getCC(cc), 0, simm11);
-        }
-
-        /**
-         * Converts regular CC codes to CC codes used by Movcc instructions.
-         */
-        public static int getCC(CC cc) {
-            switch (cc) {
-                case Icc:
-                case Xcc:
-                    return 0b100 + cc.getValue();
-                default:
-                    return cc.getValue();
-            }
-        }
-
-        private int getInstructionBits() {
-            if (i == 0) {
-                return Ops.ArithOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | ((cc << (CC2_SHIFT - 2)) & CC2_MASK) | cond << COND_SHIFT | i << I_SHIFT |
-                                ((cc << (CC1_SHIFT - 1)) & CC1_MASK) | ((cc << CC0_SHIFT) & CC0_MASK) | rs2 << RS2_SHIFT;
-            } else {
-                return Ops.ArithOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | ((cc << (CC2_SHIFT - 2)) & CC2_MASK) | cond << COND_SHIFT | i << I_SHIFT |
-                                ((cc << (CC1_SHIFT - 1)) & CC1_MASK) | ((cc << CC0_SHIFT) & CC0_MASK) | ((simm11 << SIMM11_SHIFT) & SIMM11_MASK);
-            }
-        }
-
-        public static Fmt10c read(SPARCAssembler masm, int pos) {
-            final int inst = masm.getInt(pos);
-
-            // Make sure it's the right instruction:
-            final int op = (inst & OP_MASK) >> OP_SHIFT;
-            assert op == Ops.ArithOp.getValue();
-
-            // Get the instruction fields:
-            final int rd = (inst & RD_MASK) >> RD_SHIFT;
-            final int op3 = (inst & OP3_MASK) >> OP3_SHIFT;
-            final int cond = (inst & COND_MASK) >> COND_SHIFT;
-            final int i = (inst & I_MASK) >> I_SHIFT;
-            final int cc = (inst & CC2_MASK) >> CC2_SHIFT | (inst & CC1_MASK) >> CC1_SHIFT | (inst & CC0_MASK) >> CC0_SHIFT;
-            final int rs2 = (inst & RS2_MASK) >> RS2_SHIFT;
-            final int simm11 = (inst & SIMM11_MASK) >> SIMM11_SHIFT;
-
-            return new Fmt10c(rd, op3, cond, i, cc, rs2, simm11);
-        }
-
-        public void write(SPARCAssembler masm, int pos) {
-            verify();
-            masm.emitInt(getInstructionBits(), pos);
-        }
-
-        public void emit(SPARCAssembler masm) {
-            verify();
-            masm.emitInt(getInstructionBits());
-        }
-
-        public void verify() {
-            assert ((rd << RD_SHIFT) & RD_MASK) == (rd << RD_SHIFT);
-            assert ((op3 << OP3_SHIFT) & OP3_MASK) == (op3 << OP3_SHIFT);
-            assert ((cond << COND_SHIFT) & COND_MASK) == (cond << COND_SHIFT);
-            assert ((i << I_SHIFT) & I_MASK) == (i << I_SHIFT);
-            // assert cc >= 0 && cc < 0x8;
-            assert ((rs2 << RS2_SHIFT) & RS2_MASK) == (rs2 << RS2_SHIFT);
-            assert isSimm11(simm11);
-        }
-    }
-
-    // @formatter:off
-    /**
-     * Instruction format for Fmovcc.
-     * <pre>
-     * | 10  |   rd   |   op3   | -|   cond  | opfcc | opf_low |   rs2   |
-     * |31 30|29    25|24     19|18|17     14|13   11|10      5|4       0|
-     * </pre>
-     */
-    // @formatter:on
-    public static class Fmt10d implements AssemblerEmittable {
-
-        private static final int OP_SHIFT = 30;
-        private static final int RD_SHIFT = 25;
-        private static final int OP3_SHIFT = 19;
-        private static final int COND_SHIFT = 14;
-        private static final int OPFCC_SHIFT = 12;
-        private static final int OPF_LOW_SHIFT = 11;
-        private static final int RS2_SHIFT = 0;
-
-        // @formatter:off
-        private static final int RD_MASK      = 0b0011_1110_0000_0000_0000_0000_0000_0000;
-        private static final int OP3_MASK     = 0b0000_0001_1111_1000_0000_0000_0000_0000;
-        private static final int COND_MASK    = 0b0000_0000_0000_0011_1100_0000_0000_0000;
-        private static final int OPFCC_MASK   = 0b0000_0000_0000_0000_0011_1000_0000_0000;
-        private static final int OPF_LOW_MASK = 0b0000_0000_0000_0000_0000_0111_1110_0000;
-        private static final int RS2_MASK     = 0b0000_0000_0000_0000_0000_0000_0001_1111;
-        // @formatter:on
-
-        private int rd;
-        private int op3;
-        private int cond;
-        private int opfcc;
-        private int opfLow;
-        private int rs2;
-
-        public Fmt10d(Op3s op3, Opfs opf, ConditionFlag cond, CC cc, Register rs2, Register rd) {
-            this(rd.encoding(), op3.getValue(), cond.getValue(), Fmt10c.getCC(cc), opf.getValue(), rs2.encoding());
-        }
-
-        public Fmt10d(int rd, int op3, int cond, int opfcc, int opfLow, int rs2) {
-            super();
-            this.rd = rd;
-            this.op3 = op3;
-            this.cond = cond;
-            this.opfcc = opfcc;
-            this.opfLow = opfLow;
-            this.rs2 = rs2;
-        }
-
-        public void emit(SPARCAssembler masm) {
-            verify();
-            masm.emitInt(getInstructionBits());
-        }
-
-        private int getInstructionBits() {
-            return Ops.ArithOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | cond << COND_SHIFT | opfcc << OPFCC_SHIFT | opfLow << OPF_LOW_SHIFT | rs2 << RS2_SHIFT;
-
-        }
-
-        public void verify() {
-            assert ((RD_MASK >> RD_SHIFT) & rd) == rd;
-            assert ((OP3_MASK >> OP3_SHIFT) & op3) == op3;
-            assert ((COND_MASK >> COND_SHIFT) & cond) == cond;
-            assert ((OPFCC_MASK >> OPFCC_SHIFT) & opfcc) == opfcc;
-            assert ((OPF_LOW_MASK >> OPF_LOW_SHIFT) & opfLow) == opfLow;
-            assert ((RS2_MASK >> RS2_SHIFT) & rs2) == rs2;
-        }
-    }
-
-    public static class Fmt5a {
-
-        public Fmt5a(SPARCAssembler masm, int op, int op3, int op5, int rs1, int rs2, int rs3, int rd) {
-            assert op == 2;
-            assert op3 >= 0 && op3 < 0x40;
-            assert op5 >= 0 && op5 < 0x10;
-            assert rs1 >= 0 && rs1 < 0x20;
-            assert rs2 >= 0 && rs2 < 0x20;
-            assert rs3 >= 0 && rs3 < 0x20;
-            assert rd >= 0 && rd < 0x20;
-
-            masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | rs3 << 9 | op5 << 5 | rs2);
-        }
-    }
-
-    public static final int ImmedTrue = 0x00002000;
+    protected static final int D10LO_MASK = 0b0000_0000_0000_0000_0001_1111_1110_0000;
+    protected static final int D10HI_MASK = 0b0000_0000_0001_1000_0000_0000_0000_0000;
+    protected static final int D10LO_SHIFT = 5;
+    protected static final int D10HI_SHIFT = 19;
 
     public enum Ops {
         // @formatter:off
@@ -1518,6 +115,18 @@
         }
     }
 
+    public enum Op {
+        Op00(0b00),
+        Op01(0b01),
+        Op10(0b10),
+        Op11(0b11);
+        int op;
+
+        Op(int op) {
+            this.op = op;
+        }
+    }
+
     public enum Op2s {
         // @formatter:off
 
@@ -1556,117 +165,114 @@
     public enum Op3s {
         // @formatter:off
 
-        Add(0x00, "add"),
-        And(0x01, "and"),
-        Or(0x02, "or"),
-        Xor(0x03, "xor"),
-        Sub(0x04, "sub"),
-        Andn(0x05, "andn"),
-        Orn(0x06, "orn"),
-        Xnor(0x07, "xnor"),
-        Addc(0x08, "addc"),
-        Mulx(0x09, "mulx"),
-        Umul(0x0A, "umul"),
-        Smul(0x0B, "smul"),
-        Subc(0x0C, "subc"),
-        Udivx(0x0D, "udivx"),
-        Udiv(0x0E, "udiv"),
-        Sdiv(0x0F, "sdiv"),
+        Add(0x00, "add", Op10),
+        And(0x01, "and", Op10),
+        Or(0x02, "or", Op10),
+        Xor(0x03, "xor", Op10),
+        Sub(0x04, "sub", Op10),
+        Andn(0x05, "andn", Op10),
+        Orn(0x06, "orn", Op10),
+        Xnor(0x07, "xnor", Op10),
+        Addc(0x08, "addc", Op10),
+        Mulx(0x09, "mulx", Op10),
+        Umul(0x0A, "umul", Op10),
+        Smul(0x0B, "smul", Op10),
+        Subc(0x0C, "subc", Op10),
+        Udivx(0x0D, "udivx", Op10),
+        Udiv(0x0E, "udiv", Op10),
+        Sdiv(0x0F, "sdiv", Op10),
 
-        Addcc(0x10, "addcc"),
-        Andcc(0x11, "andcc"),
-        Orcc(0x12, "orcc"),
-        Xorcc(0x13, "xorcc"),
-        Subcc(0x14, "subcc"),
-        Andncc(0x15, "andncc"),
-        Orncc(0x16, "orncc"),
-        Xnorcc(0x17, "xnorcc"),
-        Addccc(0x18, "addccc"),
-        // dos not exist
-        // Mulxcc(0x19, "mulxcc"),
-        Umulcc(0x1A, "umulcc"),
-        Smulcc(0x1B, "smulcc"),
-        Subccc(0x1C, "subccc"),
-        Udivcc(0x1E, "udivcc"),
-        Sdivcc(0x1F, "sdivcc"),
+        Addcc(0x10, "addcc", Op10),
+        Andcc(0x11, "andcc", Op10),
+        Orcc(0x12, "orcc", Op10),
+        Xorcc(0x13, "xorcc", Op10),
+        Subcc(0x14, "subcc", Op10),
+        Andncc(0x15, "andncc", Op10),
+        Orncc(0x16, "orncc", Op10),
+        Xnorcc(0x17, "xnorcc", Op10),
+        Addccc(0x18, "addccc", Op10),
 
-        Taddcc(0x20, "taddcc"),
-        Tsubcc(0x21, "tsubcc"),
-        Taddcctv(0x22, "taddcctv"),
-        Tsubcctv(0x23, "tsubcctv"),
-        Mulscc(0x24, "mulscc"),
-        Sll(0x25, "sll"),
-        Sllx(0x25, "sllx"),
-        Srl(0x26, "srl"),
-        Srlx(0x26, "srlx"),
-        Sra(0x27, "srax"),
-        Srax(0x27, "srax"),
-        Rdreg(0x28, "rdreg"),
-        Membar(0x28, "membar"),
+        Umulcc(0x1A, "umulcc", Op10),
+        Smulcc(0x1B, "smulcc", Op10),
+        Subccc(0x1C, "subccc", Op10),
+        Udivcc(0x1E, "udivcc", Op10),
+        Sdivcc(0x1F, "sdivcc", Op10),
+
+        Taddcc(0x20, "taddcc", Op10),
+        Tsubcc(0x21, "tsubcc", Op10),
+        Taddcctv(0x22, "taddcctv", Op10),
+        Tsubcctv(0x23, "tsubcctv", Op10),
+        Mulscc(0x24, "mulscc", Op10),
+        Sll(0x25, "sll", Op10),
+        Sllx(0x25, "sllx", Op10),
+        Srl(0x26, "srl", Op10),
+        Srlx(0x26, "srlx", Op10),
+        Sra(0x27, "srax", Op10),
+        Srax(0x27, "srax", Op10),
+        Membar(0x28, "membar", Op10),
 
-        Flushw(0x2B, "flushw"),
-        Movcc(0x2C, "movcc"),
-        Sdivx(0x2D, "sdivx"),
-        Popc(0x2E, "popc"),
-        Movr(0x2F, "movr"),
-
-        Sir(0x30, "sir"),
-        Wrreg(0x30, "wrreg"),
-        Saved(0x31, "saved"),
+        Flushw(0x2B, "flushw", Op10),
+        Movcc(0x2C, "movcc", Op10),
+        Sdivx(0x2D, "sdivx", Op10),
+        Popc(0x2E, "popc", Op10),
+        Movr(0x2F, "movr", Op10),
 
-        Fpop1(0b11_0100, "fpop1"),
-        Fpop2(0b11_0101, "fpop2"),
-        Impdep1(0b11_0110, "impdep1"),
-        Impdep2(0b11_0111, "impdep2"),
-        Jmpl(0x38, "jmpl"),
-        Rett(0x39, "rett"),
-        Trap(0x3a, "trap"),
-        Flush(0x3b, "flush"),
-        Save(0x3c, "save"),
-        Restore(0x3d, "restore"),
-        Done(0x3e, "done"),
-        Retry(0x3e, "retry"),
-        Casa(0b111100, "casa"),
-        Casxa(0b111110, "casxa"),
-        Prefetch(0b101101, "prefetch"),
-        Prefetcha(0b111101, "prefetcha"),
+        Fpop1(0b11_0100, "fpop1", Op10),
+        Fpop2(0b11_0101, "fpop2", Op10),
+        Impdep1(0b11_0110, "impdep1", Op10),
+        Impdep2(0b11_0111, "impdep2", Op10),
+        Jmpl(0x38, "jmpl", Op10),
+        Rett(0x39, "rett", Op10),
+        Trap(0x3a, "trap", Op10),
+        Flush(0x3b, "flush", Op10),
+        Save(0x3c, "save", Op10),
+        Restore(0x3d, "restore", Op10),
+        Retry(0x3e, "retry", Op10),
+
+
+        Casa(0b111100, "casa", Op11),
+        Casxa(0b111110, "casxa", Op11),
+        Prefetch(0b101101, "prefetch", Op11),
+        Prefetcha(0b111101, "prefetcha", Op11),
 
-        Lduw  (0b00_0000, "lduw"),
-        Ldub  (0b00_0001, "ldub"),
-        Lduh  (0b00_0010, "lduh"),
-        Stw   (0b00_0100, "stw"),
-        Stb   (0b00_0101, "stb"),
-        Sth   (0b00_0110, "sth"),
-        Ldsw  (0b00_1000, "ldsw"),
-        Ldsb  (0b00_1001, "ldsb"),
-        Ldsh  (0b00_1010, "ldsh"),
-        Ldx   (0b00_1011, "ldx"),
-        Stx   (0b00_1110, "stx"),
+        Lduw  (0b00_0000, "lduw", Op11),
+        Ldub  (0b00_0001, "ldub", Op11),
+        Lduh  (0b00_0010, "lduh", Op11),
+        Stw   (0b00_0100, "stw", Op11),
+        Stb   (0b00_0101, "stb", Op11),
+        Sth   (0b00_0110, "sth", Op11),
+        Ldsw  (0b00_1000, "ldsw", Op11),
+        Ldsb  (0b00_1001, "ldsb", Op11),
+        Ldsh  (0b00_1010, "ldsh", Op11),
+        Ldx   (0b00_1011, "ldx", Op11),
+        Stx   (0b00_1110, "stx", Op11),
 
-        Ldf   (0b10_0000, "ldf"),
-        Ldfsr (0b10_0001, "ldfsr"),
-        Ldaf  (0b10_0010, "ldaf"),
-        Lddf  (0b10_0011, "lddf"),
-        Stf   (0b10_0100, "stf"),
-        Stfsr (0b10_0101, "stfsr"),
-        Staf  (0x10_0110, "staf"),
-        Rd    (0b10_1000, "rd"),
-        Stdf  (0b10_0111, "stdf"),
+        Ldf   (0b10_0000, "ldf", Op11),
+        Ldfsr (0b10_0001, "ldfsr", Op11),
+        Ldaf  (0b10_0010, "ldaf", Op11),
+        Lddf  (0b10_0011, "lddf", Op11),
+        Stf   (0b10_0100, "stf", Op11),
+        Stfsr (0b10_0101, "stfsr", Op11),
+        Staf  (0x10_0110, "staf", Op11),
+        Stdf  (0b10_0111, "stdf", Op11),
 
-        Wr    (0b11_0000, "wr"),
-        Fcmp  (0b11_0101, "fcmp"),
+        Rd    (0b10_1000, "rd", Op10),
+        Wr    (0b11_0000, "wr", Op10),
+        Fcmp  (0b11_0101, "fcmp", Op10),
 
-        Ldxa  (0b01_1011, "ldxa"),
-        Lduwa (0b01_0000, "lduwa");
+        Ldxa  (0b01_1011, "ldxa", Op11),
+        Lduwa (0b01_0000, "lduwa", Op11);
 
         // @formatter:on
 
         private final int value;
         private final String operator;
+        private final Op op;
 
-        private Op3s(int value, String op) {
+        private Op3s(int value, String name, Op op) {
             this.value = value;
-            this.operator = op;
+            this.operator = name;
+            this.op = op;
         }
 
         public int getValue() {
@@ -1682,31 +288,6 @@
         }
     }
 
-    public enum Op5s {
-        // @formatter:off
-
-        Fmadds(0x1),
-        Fmaddd(0x2),
-        Fmsubs(0x5),
-        Fmsubd(0x6),
-        Fnmsubs(0x9),
-        Fnmsubd(0xA),
-        Fnmadds(0xD),
-        Fnmaddd(0xE);
-
-        // @formatter:on
-
-        private final int value;
-
-        private Op5s(int value) {
-            this.value = value;
-        }
-
-        public int getValue() {
-            return value;
-        }
-    }
-
     public enum Opfs {
         // @formatter:off
 
@@ -1895,6 +476,26 @@
         }
     }
 
+    public enum Annul {
+        ANNUL(1),
+        NOT_ANNUL(0);
+        public final int flag;
+
+        Annul(int flag) {
+            this.flag = flag;
+        }
+    }
+
+    public enum BranchPredict {
+        PREDICT_TAKEN(1),
+        PREDICT_NOT_TAKEN(0);
+        public final int flag;
+
+        BranchPredict(int flag) {
+            this.flag = flag;
+        }
+    }
+
     public enum MembarMask {
         // @formatter:off
 
@@ -1933,25 +534,27 @@
         /**
          * Condition is considered as 32bit operation condition.
          */
-        Icc(0b00, "icc"),
+        Icc(0b00, "icc", false),
         /**
          * Condition is considered as 64bit operation condition.
          */
-        Xcc(0b10, "xcc"),
-        Ptrcc(getHostWordKind() == Kind.Long ? Xcc.getValue() : Icc.getValue(), "ptrcc"),
-        Fcc0(0b00, "fcc0"),
-        Fcc1(0b01, "fcc1"),
-        Fcc2(0b10, "fcc2"),
-        Fcc3(0b11, "fcc3");
+        Xcc(0b10, "xcc", false),
+        Ptrcc(getHostWordKind() == Kind.Long ? Xcc.getValue() : Icc.getValue(), "ptrcc", false),
+        Fcc0(0b00, "fcc0", true),
+        Fcc1(0b01, "fcc1", true),
+        Fcc2(0b10, "fcc2", true),
+        Fcc3(0b11, "fcc3", true);
 
         // @formatter:on
 
         private final int value;
         private final String operator;
+        private boolean isFloat;
 
-        private CC(int value, String op) {
+        private CC(int value, String op, boolean isFloat) {
             this.value = value;
             this.operator = op;
+            this.isFloat = isFloat;
         }
 
         public int getValue() {
@@ -1961,40 +564,21 @@
         public String getOperator() {
             return operator;
         }
-    }
 
-    public enum FCond {
-        Fba(0x8, "fba"),
-        Fbn(0x0, "fbn"),
-        Fbu(0x7, "fbu"),
-        Fbg(0x6, "fbg"),
-        Fbug(0x5, "fbug"),
-        Fbl(0x4, "fbl"),
-        Fbul(0x3, "fbul"),
-        Fblg(0x2, "fblg"),
-        Fbne(0x1, "fbne"),
-        Fbe(0x9, "fbe"),
-        Fbue(0xA, "fbue"),
-        Fbge(0xB, "fbge"),
-        Fbuge(0xC, "fbuge"),
-        Fble(0xD, "fble"),
-        Fbule(0xE, "fbule"),
-        Fbo(0xF, "fbo");
-        private final int value;
-        private final String operator;
-
-        private FCond(int value, String op) {
-            assert value >= 0 && value < 1 << 5 : value; // 4 bits
-            this.value = value;
-            this.operator = op;
-        }
-
-        public int getValue() {
-            return value;
-        }
-
-        public String getOperator() {
-            return operator;
+        public static CC forKind(Kind kind) {
+            boolean isInt = kind == Kind.Boolean || kind == Kind.Byte || kind == Kind.Char || kind == Kind.Short || kind == Kind.Int;
+            boolean isFloat = kind == Kind.Float || kind == Kind.Double;
+            boolean isLong = kind == Kind.Long || kind == Kind.Object;
+            assert isInt || isFloat || isLong;
+            if (isLong) {
+                return Xcc;
+            } else if (isInt) {
+                return Icc;
+            } else if (isFloat) {
+                return Fcc0;
+            } else {
+                throw GraalInternalError.shouldNotReachHere();
+            }
         }
     }
 
@@ -2115,31 +699,56 @@
             return null;
         }
 
+        public ConditionFlag mirror() {
+            switch (this) {
+            //@formatter:off
+                case F_Less                   : return F_Greater;
+                case F_Greater                : return F_Less;
+                case F_LessOrEqual            : return F_GreaterOrEqual;
+                case F_UnorderedGreaterOrEqual: return F_UnorderedOrLessOrEqual;
+                case F_UnorderedOrGreater     : return F_UnorderedOrLess;
+                case F_UnorderedOrLessOrEqual : return F_UnorderedGreaterOrEqual;
+                case F_GreaterOrEqual         : return F_LessOrEqual;
+                case F_UnorderedOrLess        : return F_UnorderedOrGreater;
+                case LessEqual                : return GreaterEqual;
+                case Greater                  : return Less;
+                case Less                     : return Greater;
+                case GreaterEqual             : return LessEqual;
+                case LessEqualUnsigned        : return GreaterEqualUnsigned;
+                case GreaterUnsigned          : return LessUnsigned;
+                case LessUnsigned             : return GreaterUnsigned;
+                case GreaterEqualUnsigned     : return LessEqualUnsigned;
+                default:
+                    return this;
+                //@formatter:on
+            }
+        }
+
         public static ConditionFlag fromCondtition(CC conditionFlagsRegister, Condition cond, boolean unorderedIsTrue) {
             switch (conditionFlagsRegister) {
                 case Xcc:
                 case Icc:
                     switch (cond) {
                         case EQ:
-                            return ConditionFlag.Equal;
+                            return Equal;
                         case NE:
-                            return ConditionFlag.NotEqual;
+                            return NotEqual;
                         case BT:
-                            return ConditionFlag.LessUnsigned;
+                            return LessUnsigned;
                         case LT:
-                            return ConditionFlag.Less;
+                            return Less;
                         case BE:
-                            return ConditionFlag.LessEqualUnsigned;
+                            return LessEqualUnsigned;
                         case LE:
-                            return ConditionFlag.LessEqual;
+                            return LessEqual;
                         case AE:
-                            return ConditionFlag.GreaterEqualUnsigned;
+                            return GreaterEqualUnsigned;
                         case GE:
-                            return ConditionFlag.GreaterEqual;
+                            return GreaterEqual;
                         case AT:
-                            return ConditionFlag.GreaterUnsigned;
+                            return GreaterUnsigned;
                         case GT:
-                            return ConditionFlag.Greater;
+                            return Greater;
                     }
                     throw GraalInternalError.shouldNotReachHere("Unimplemented for: " + cond);
                 case Fcc0:
@@ -2148,17 +757,17 @@
                 case Fcc3:
                     switch (cond) {
                         case EQ:
-                            return unorderedIsTrue ? ConditionFlag.F_UnorderedOrEqual : ConditionFlag.F_Equal;
+                            return unorderedIsTrue ? F_UnorderedOrEqual : F_Equal;
                         case NE:
                             return ConditionFlag.F_NotEqual;
                         case LT:
-                            return unorderedIsTrue ? ConditionFlag.F_UnorderedOrLess : ConditionFlag.F_Less;
+                            return unorderedIsTrue ? F_UnorderedOrLess : F_Less;
                         case LE:
-                            return unorderedIsTrue ? ConditionFlag.F_UnorderedOrLessOrEqual : ConditionFlag.F_LessOrEqual;
+                            return unorderedIsTrue ? F_UnorderedOrLessOrEqual : F_LessOrEqual;
                         case GE:
-                            return unorderedIsTrue ? ConditionFlag.F_UnorderedGreaterOrEqual : ConditionFlag.F_GreaterOrEqual;
+                            return unorderedIsTrue ? F_UnorderedGreaterOrEqual : F_GreaterOrEqual;
                         case GT:
-                            return unorderedIsTrue ? ConditionFlag.F_UnorderedOrGreater : ConditionFlag.F_Greater;
+                            return unorderedIsTrue ? F_UnorderedOrGreater : F_Greater;
                     }
                     throw GraalInternalError.shouldNotReachHere("Unkown condition: " + cond);
             }
@@ -2228,34 +837,43 @@
         }
     }
 
+    public enum Fcn {
+        SeveralWritesAndPossiblyReads(2),
+        SeveralReadsWeak(0),
+        OneRead(1),
+        OneWrite(3),
+        Page(4),
+        NearestUnifiedCache(17),
+        SeveralReadsStrong(20),
+        OneReadStrong(21),
+        SeveralWritesAndPossiblyReadsStrong(22),
+        OneWriteStrong(23);
+
+        private final int value;
+
+        private Fcn(int value) {
+            this.value = value;
+        }
+
+        public int getValue() {
+            return value;
+        }
+    }
+
     public boolean hasFeature(CPUFeature feature) {
         return ((SPARC) this.target.arch).features.contains(feature);
     }
 
-    public static int getFloatEncoding(int reg) {
-        assert reg < 32;
-        return reg;
-    }
-
-    public static int getDoubleEncoding(int reg) {
-        assert reg < 64 && ((reg & 1) == 0);
-        // ignore v8 assertion for now
-        return (reg & 0x1e) | ((reg & 0x20) >> 5);
-    }
-
-    public static int getQuadEncoding(int reg) {
-        assert reg < 64 && ((reg & 3) == 0);
-        // ignore v8 assertion for now
-        return (reg & 0x1c) | ((reg & 0x20) >> 5);
-    }
-
-    public static final int sx1 = 0x00001000;
-
     public static final int simm(int x, int nbits) {
         // assert_signed_range(x, nbits);
         return x & ((1 << nbits) - 1);
     }
 
+    public static final boolean isImm(int x, int nbits) {
+        // assert_signed_range(x, nbits);
+        return simm(x, nbits) == x;
+    }
+
     /**
      * Minimum value for signed immediate ranges.
      */
@@ -2301,10 +919,6 @@
         return NumUtil.isInt(imm) && isSimm(imm, 13);
     }
 
-    public static boolean isDisp30(long imm) {
-        return isSimm(imm, 30);
-    }
-
     public static boolean isWordDisp30(long imm) {
         return isSimm(imm, 30 + 2);
     }
@@ -2317,2238 +931,814 @@
         return x & ((1 << 10) - 1);
     }
 
-    public static class Add extends Fmt10 {
-
-        public Add(Register src1, int simm13, Register dst) {
-            super(Op3s.Add, src1, simm13, dst);
-        }
-
-        public Add(Register src1, Register src2, Register dst) {
-            super(Op3s.Add, src1, src2, dst);
-        }
-    }
-
-    public static class Addc extends Fmt10 {
-
-        public Addc(Register src1, int simm13, Register dst) {
-            super(Op3s.Addc, src1, simm13, dst);
-        }
-
-        public Addc(Register src1, Register src2, Register dst) {
-            super(Op3s.Addc, src1, src2, dst);
-        }
-    }
-
-    public static class Addcc extends Fmt10 {
-
-        public Addcc(Register src1, int simm13, Register dst) {
-            super(Op3s.Addcc, src1, simm13, dst);
-        }
-
-        public Addcc(Register src1, Register src2, Register dst) {
-            super(Op3s.Addcc, src1, src2, dst);
-        }
+    // @formatter:off
+    /**
+     * Instruction format for Fmt00 instructions. This abstraction is needed as it
+     * makes the patching easier later on.
+     * <pre>
+     * | 00  |    a   | op2 |               b                         |
+     * |31 30|29    25|24 22|21                                      0|
+     * </pre>
+     */
+    // @formatter:on
+    protected void fmt00(int a, int op2, int b) {
+        assert isImm(a, 5) && isImm(op2, 3) && isImm(b, 22) : String.format("a: 0x%x op2: 0x%x b: 0x%x", a, op2, b);
+        this.emitInt(a << 25 | op2 << 22 | b);
     }
 
-    public static class Addccc extends Fmt10 {
-
-        public Addccc(Register src1, int simm13, Register dst) {
-            super(Op3s.Addccc, src1, simm13, dst);
-        }
-
-        public Addccc(Register src1, Register src2, Register dst) {
-            super(Op3s.Addccc, src1, src2, dst);
-        }
-    }
-
-    public static class Addxc extends Fmt3p {
-
-        public Addxc(Register src1, Register src2, Register dst) {
-            /* VIS3 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Addxc, src1, src2, dst);
-        }
+    private void op3(Op3s op3, Opfs opf, Register rs1, Register rs2, Register rd) {
+        int b = opf.value << 5 | (rs2 == null ? 0 : rs2.encoding);
+        fmt(op3.op.op, rd.encoding, op3.value, rs1 == null ? 0 : rs1.encoding, b);
     }
 
-    public static class Addxccc extends Fmt3p {
-
-        public Addxccc(Register src1, Register src2, Register dst) {
-            /* VIS3 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Addxccc, src1, src2, dst);
-        }
+    protected void op3(Op3s op3, Register rs1, Register rs2, Register rd) {
+        int b = rs2 == null ? 0 : rs2.encoding;
+        int xBit = getXBit(op3);
+        fmt(op3.op.op, rd.encoding, op3.value, rs1 == null ? 0 : rs1.encoding, b | xBit);
     }
 
-    public static class Alignaddr extends Fmt3p {
-
-        public Alignaddr(Register src1, Register src2, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.AlignAddress, src1, src2, dst);
-        }
-    }
-
-    public static class Alignaddrl extends Fmt3p {
-
-        public Alignaddrl(Register src1, Register src2, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.AlignAddressLittle, src1, src2, dst);
-        }
-    }
-
-    public static class Lzcnt extends Fmt3p {
-
-        public Lzcnt(Register src1, Register dst) {
-            /* VIS3 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Lzcnt, g0, src1, dst);
-        }
+    protected void op3(Op3s op3, Register rs1, int simm13, Register rd) {
+        assert isSimm13(simm13);
+        int i = 1 << 13;
+        int simm13WithX = simm13 | getXBit(op3);
+        fmt(op3.op.op, rd.encoding, op3.value, rs1.encoding, i | simm13WithX & ((1 << 13) - 1));
     }
 
-    public static class And extends Fmt10 {
-
-        public And(Register src1, int simm13, Register dst) {
-            super(Op3s.And, src1, simm13, dst);
-        }
-
-        public And(Register src1, Register src2, Register dst) {
-            super(Op3s.And, src1, src2, dst);
-        }
-    }
-
-    public static class Andcc extends Fmt10 {
-
-        public Andcc(Register src1, int simm13, Register dst) {
-            super(Op3s.Andcc, src1, simm13, dst);
-        }
-
-        public Andcc(Register src1, Register src2, Register dst) {
-            super(Op3s.Andcc, src1, src2, dst);
-        }
-    }
-
-    public static class Andn extends Fmt10 {
-
-        public Andn(Register src1, int simm13, Register dst) {
-            super(Op3s.Andn, src1, simm13, dst);
-        }
-
-        public Andn(Register src1, Register src2, Register dst) {
-            super(Op3s.Andn, src1, src2, dst);
-        }
+    // @formatter:off
+    /**
+     * Branch on Integer Condition Codes.
+     * <pre>
+     * | 00  |annul| cond| 010 |               disp22                 |
+     * |31 30|29   |28 25|24 22|21                                   0|
+     * </pre>
+     */
+    // @formatter:on
+    public void bicc(ConditionFlag cond, Annul annul, Label l) {
+        bcc(Op2s.Br, cond, annul, l);
     }
 
-    public static class Andncc extends Fmt10 {
-
-        public Andncc(Register src1, int simm13, Register dst) {
-            super(Op3s.Andncc, src1, simm13, dst);
-        }
-
-        public Andncc(Register src1, Register src2, Register dst) {
-            super(Op3s.Andncc, src1, src2, dst);
-        }
-    }
-
-    public static class Array8 extends Fmt3p {
-
-        public Array8(Register src1, Register src2, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Array8, src1, src2, dst);
-        }
-
-        @Override
-        public void emit(SPARCAssembler masm) {
-            assert masm.hasFeature(CPUFeature.VIS1);
-            super.emit(masm);
-        }
+    // @formatter:off
+    /**
+     * Branch on Floating-Point Condition Codes.
+     * <pre>
+     * | 00  |annul| cond| 110 |               disp22                 |
+     * |31 30|29   |28 25|24 22|21                                   0|
+     * </pre>
+     */
+    // @formatter:on
+    public void fbcc(ConditionFlag cond, Annul annul, Label l) {
+        bcc(Op2s.Fb, cond, annul, l);
     }
 
-    public static class Array16 extends Fmt3p {
-
-        public Array16(Register src1, Register src2, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Array16, src1, src2, dst);
-        }
-
-        @Override
-        public void emit(SPARCAssembler masm) {
-            assert masm.hasFeature(CPUFeature.VIS1);
-            super.emit(masm);
-        }
-    }
-
-    public static class Array32 extends Fmt3p {
-
-        public Array32(Register src1, Register src2, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Array32, src1, src2, dst);
-        }
-
-        @Override
-        public void emit(SPARCAssembler masm) {
-            assert masm.hasFeature(CPUFeature.VIS2);
-            super.emit(masm);
-        }
+    // @formatter:off
+    /**
+     * Branch on (Integer|Floatingpoint) Condition Codes.
+     * <pre>
+     * | 00  |annul| cond| op2 |               disp22                 |
+     * |31 30|29   |28 25|24 22|21                                   0|
+     * </pre>
+     */
+    // @formatter:on
+    private void bcc(Op2s op2, ConditionFlag cond, Annul annul, Label l) {
+        int pos = !l.isBound() ? patchUnbound(l) : (l.position() - position()) / 4;
+        final int disp = 22;
+        assert isSimm(pos, disp);
+        pos &= (1 << disp) - 1;
+        int a = (annul.flag << 4) | cond.getValue();
+        fmt00(a, op2.getValue(), pos);
     }
 
-    public static class Bmask extends Fmt3p {
-
-        public Bmask(Register src1, Register src2, Register dst) {
-            /* VIS2 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Bmask, src1, src2, dst);
-        }
-
-        @Override
-        public void emit(SPARCAssembler masm) {
-            assert masm.hasFeature(CPUFeature.VIS2);
-            super.emit(masm);
-        }
-    }
-
-    public static class Movwtos extends Fmt3p {
-        public Movwtos(Register src, Register dst) {
-            /* VIS3 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Movwtos, g0, src, dst);
-            assert isSingleFloatRegister(dst);
-        }
-
-        @Override
-        public void emit(SPARCAssembler masm) {
-            assert masm.hasFeature(CPUFeature.VIS3);
-            super.emit(masm);
-        }
-    }
-
-    public static class Umulxhi extends Fmt3p {
-        public Umulxhi(Register src1, Register src2, Register dst) {
-            /* VIS3 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.UMulxhi, src1, src2, dst);
-        }
-
-        @Override
-        public void emit(SPARCAssembler masm) {
-            assert masm.hasFeature(CPUFeature.VIS3);
-            super.emit(masm);
-        }
+    // @formatter:off
+    /**
+     * Branch on Integer Condition Codes with Prediction.
+     * <pre>
+     * | 00  |an|cond | 001 |cc1 2|p |           disp19               |
+     * |31 30|29|28 25|24 22|21 20|19|                               0|
+     * </pre>
+     */
+    // @formatter:on
+    public void bpcc(ConditionFlag cond, Annul annul, Label l, CC cc, BranchPredict predictTaken) {
+        bpcc(Op2s.Bp, cond, annul, l, cc, predictTaken);
     }
 
-    public static class Movxtod extends Fmt3p {
-        public Movxtod(Register src, Register dst) {
-            /* VIS3 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Movxtod, g0, src, dst);
-            assert isDoubleFloatRegister(dst);
-        }
-
-        @Override
-        public void emit(SPARCAssembler masm) {
-            assert masm.hasFeature(CPUFeature.VIS3);
-            super.emit(masm);
-        }
-    }
-
-    public static class Movdtox extends Fmt3p {
-        public Movdtox(Register src, Register dst) {
-            /* VIS3 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Movdtox, g0, src, dst);
-            assert isDoubleFloatRegister(src);
-        }
-
-        @Override
-        public void emit(SPARCAssembler masm) {
-            assert masm.hasFeature(CPUFeature.VIS3);
-            super.emit(masm);
-        }
-    }
-
-    public static class Movstosw extends Fmt3p {
-        public Movstosw(Register src, Register dst) {
-            /* VIS3 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Movstosw, g0, src, dst);
-            assert isSingleFloatRegister(src);
-        }
-
-        @Override
-        public void emit(SPARCAssembler masm) {
-            assert masm.hasFeature(CPUFeature.VIS3);
-            super.emit(masm);
-        }
+    // @formatter:off
+    /**
+     * Branch on Integer Condition Codes with Prediction.
+     * <pre>
+     * | 00  |an|cond | 101 |cc1 2|p |           disp19               |
+     * |31 30|29|28 25|24 22|21 20|19|                               0|
+     * </pre>
+     */
+    // @formatter:on
+    public void fbpcc(ConditionFlag cond, Annul annul, Label l, CC cc, BranchPredict predictTaken) {
+        bpcc(Op2s.Fbp, cond, annul, l, cc, predictTaken);
     }
 
-    public static class Movstouw extends Fmt3p {
-        public Movstouw(Register src, Register dst) {
-            /* VIS3 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Movstouw, g0, src, dst);
-            assert isSingleFloatRegister(src);
-        }
-
-        @Override
-        public void emit(SPARCAssembler masm) {
-            assert masm.hasFeature(CPUFeature.VIS3);
-            super.emit(masm);
-        }
-    }
-
-    public static class Fdtos extends Fmt3p {
-        public Fdtos(Register src, Register dst) {
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fdtos, g0, src, dst);
-            assert isSingleFloatRegister(dst);
-            assert isDoubleFloatRegister(src);
-        }
-    }
-
-    public static class Bpr extends Fmt00d {
-        public Bpr(RCondition rcond, boolean annul, boolean predictTaken, Register rs1, Label label) {
-            super(Op2s.Bpr.getValue(), rcond.getValue(), predictTaken ? 1 : 0, annul ? 1 : 0, 0, rs1.encoding(), label);
-        }
-    }
-
-    public static class Bpa extends Fmt00c {
-
-        public Bpa(int simm19) {
-            super(0, ConditionFlag.Always, Op2s.Bp, CC.Icc, 1, simm19);
-        }
-
-        public Bpa(Label label) {
-            super(0, ConditionFlag.Always, Op2s.Bp, CC.Icc, 1, label);
-        }
+    // @formatter:off
+    /**
+     * Used for fbpcc (Float) and bpcc (Integer).
+     * <pre>
+     * | 00  |an|cond | op2 |cc1 2|p |           disp19               |
+     * |31 30|29|28 25|24 22|21 20|19|                               0|
+     * </pre>
+     */
+    // @formatter:on
+    private void bpcc(Op2s op2, ConditionFlag cond, Annul annul, Label l, CC cc, BranchPredict predictTaken) {
+        int pos = !l.isBound() ? patchUnbound(l) : (l.position() - position()) / 4;
+        final int disp = 19;
+        assert isSimm(pos, disp);
+        pos &= (1 << disp) - 1;
+        int a = (annul.flag << 4) | cond.getValue();
+        int b = (cc.getValue() << 20) | ((predictTaken.flag) << 19) | pos;
+        fmt00(a, op2.getValue(), b);
     }
 
-    public static class Bpcc extends Fmt00c {
-
-        public Bpcc(CC cc, int simm19) {
-            super(0, ConditionFlag.CarryClear, Op2s.Bp, cc, 1, simm19);
-        }
-
-        public Bpcc(CC cc, Label label) {
-            super(0, ConditionFlag.CarryClear, Op2s.Bp, cc, 1, label);
-        }
-
-        public Bpcc(CC cc, boolean annul, boolean predictTaken, Label label) {
-            super(annul ? 1 : 0, ConditionFlag.CarryClear, Op2s.Bp, cc, predictTaken ? 1 : 0, label);
-        }
-    }
-
-    public static class Bpcs extends Fmt00c {
-
-        public Bpcs(CC cc, int simm19) {
-            super(0, ConditionFlag.CarrySet, Op2s.Bp, cc, 1, simm19);
-        }
-
-        public Bpcs(CC cc, Label label) {
-            super(0, ConditionFlag.CarrySet, Op2s.Bp, cc, 1, label);
-        }
-
-        public Bpcs(CC cc, boolean annul, boolean predictTaken, Label label) {
-            super(annul ? 1 : 0, ConditionFlag.CarrySet, Op2s.Bp, cc, predictTaken ? 1 : 0, label);
-        }
+    // @formatter:off
+    /**
+     * Branch on Integer Register with Prediction.
+     * <pre>
+     * | 00  |an| 0|rcond | 011 |d16hi|p | rs1 |    d16lo             |
+     * |31 30|29|28|27 25 |24 22|21 20|19|18 14|                     0|
+     * </pre>
+     */
+    // @formatter:on
+    public void bpr(RCondition cond, Annul annul, Label l, BranchPredict predictTaken, Register rs1) {
+        int pos = !l.isBound() ? patchUnbound(l) : (l.position() - position()) / 4;
+        final int disp = 16;
+        assert isSimm(pos, disp);
+        pos &= (1 << disp) - 1;
+        int a = (annul.flag << 4) | cond.getValue();
+        int d16hi = (pos >> 13) << 13;
+        int d16lo = d16hi ^ pos;
+        int b = (d16hi << 20) | (predictTaken.flag << 19) | (rs1.encoding() << 14) | d16lo;
+        fmt00(a, Op2s.Bpr.getValue(), b);
     }
 
-    public static class Bpe extends Fmt00c {
-
-        public Bpe(CC cc, int simm19) {
-            super(0, ConditionFlag.Equal, Op2s.Bp, cc, 1, simm19);
-        }
+    private int patchUnbound(Label label) {
+        label.addPatchAt(position());
+        return 0;
+    }
 
-        public Bpe(CC cc, Label label, boolean predictTaken) {
-            super(0, ConditionFlag.Equal, Op2s.Bp, cc, predictTaken ? 1 : 0, label);
-        }
-
-        public Bpe(CC cc, boolean annul, boolean predictTaken, Label label) {
-            super(annul ? 1 : 0, ConditionFlag.Equal, Op2s.Bp, cc, predictTaken ? 1 : 0, label);
-        }
-
-        public Bpe(CC cc, Label label) {
-            super(0, ConditionFlag.Equal, Op2s.Bp, cc, 1, label);
-        }
+    public void cbcondw(ConditionFlag cf, Register rs1, Register rs2, Label lab) {
+        cbcond(0, 0, cf, rs1, rs2.encoding, lab);
     }
 
-    public static class Bpg extends Fmt00c {
-
-        public Bpg(CC cc, int simm19) {
-            super(0, ConditionFlag.Greater, Op2s.Bp, cc, 1, simm19);
-        }
+    public void cbcondw(ConditionFlag cf, Register rs1, int rs2, Label lab) {
+        assert isSimm(rs2, 5);
+        cbcond(0, 1, cf, rs1, rs2 & ((1 << 5) - 1), lab);
+    }
 
-        public Bpg(CC cc, Label label) {
-            super(0, ConditionFlag.Greater, Op2s.Bp, cc, 1, label);
-        }
+    public void cbcondx(ConditionFlag cf, Register rs1, Register rs2, Label lab) {
+        cbcond(1, 0, cf, rs1, rs2.encoding, lab);
+    }
 
-        public Bpg(CC cc, boolean annul, boolean predictTaken, Label label) {
-            super(annul ? 1 : 0, ConditionFlag.Greater, Op2s.Bp, cc, predictTaken ? 1 : 0, label);
-        }
+    public void cbcondx(ConditionFlag cf, Register rs1, int rs2, Label lab) {
+        assert isSimm(rs2, 5);
+        cbcond(1, 1, cf, rs1, rs2 & ((1 << 5) - 1), lab);
     }
 
-    public static class Bpge extends Fmt00c {
-
-        public Bpge(CC cc, int simm19) {
-            super(0, ConditionFlag.GreaterEqual, Op2s.Bp, cc, 1, simm19);
-        }
-
-        public Bpge(CC cc, Label label) {
-            super(0, ConditionFlag.GreaterEqual, Op2s.Bp, cc, 1, label);
-        }
-
-        public Bpge(CC cc, boolean annul, boolean predictTaken, Label label) {
-            super(annul ? 1 : 0, ConditionFlag.GreaterEqual, Op2s.Bp, cc, predictTaken ? 1 : 0, label);
-        }
-    }
-
-    public static class Bpgu extends Fmt00c {
-
-        public Bpgu(CC cc, int simm19) {
-            super(0, ConditionFlag.GreaterUnsigned, Op2s.Bp, cc, 1, simm19);
-        }
-
-        public Bpgu(CC cc, Label label) {
-            super(0, ConditionFlag.GreaterUnsigned, Op2s.Bp, cc, 1, label);
-        }
-
-        public Bpgu(CC cc, boolean annul, boolean predictTaken, Label label) {
-            super(annul ? 1 : 0, ConditionFlag.GreaterUnsigned, Op2s.Bp, cc, predictTaken ? 1 : 0, label);
-        }
+    private void cbcond(int cc2, int i, ConditionFlag cf, Register rs1, int rs2, Label l) {
+        int d10 = !l.isBound() ? patchUnbound(l) : (l.position() - position()) / 4;
+        assert isSimm(d10, 10) && isImm(rs2, 5);
+        d10 &= (1 << 10) - 1;
+        final int cLo = cf.value & 0b111;
+        final int cHi = cf.value >> 3;
+        final int d10Lo = d10 & ((1 << 8) - 1);
+        final int d10Hi = d10 >> 8;
+        int a = cHi << 4 | 0b1000 | cLo;
+        int b = cc2 << 21 | d10Hi << D10HI_SHIFT | rs1.encoding << 14 | i << 13 | d10Lo << D10LO_SHIFT | rs2;
+        fmt00(a, Op2s.Bpr.value, b);
     }
 
-    public static class Bpl extends Fmt00c {
-
-        public Bpl(CC cc, int simm19) {
-            super(0, ConditionFlag.Less, Op2s.Bp, cc, 1, simm19);
-        }
-
-        public Bpl(CC cc, Label label) {
-            super(0, ConditionFlag.Less, Op2s.Bp, cc, 1, label);
-        }
-
-        public Bpl(CC cc, boolean annul, boolean predictTaken, Label label) {
-            super(annul ? 1 : 0, ConditionFlag.Less, Op2s.Bp, cc, predictTaken ? 1 : 0, label);
-        }
+    // @formatter:off
+    /**
+     * NOP.
+     * <pre>
+     * | 00  |00000| 100 |                0                    |
+     * |31 30|29 25|24 22|21                                  0|
+     * </pre>
+     */
+    // @formatter:on
+    public void nop() {
+        emitInt(1 << 24);
     }
 
-    public static class Bple extends Fmt00c {
-
-        public Bple(CC cc, int simm19) {
-            super(0, ConditionFlag.LessEqual, Op2s.Bp, cc, 1, simm19);
-        }
-
-        public Bple(CC cc, Label label) {
-            super(0, ConditionFlag.LessEqual, Op2s.Bp, cc, 1, label);
-        }
-
-        public Bple(CC cc, boolean annul, boolean predictTaken, Label label) {
-            super(annul ? 1 : 0, ConditionFlag.LessEqual, Op2s.Bp, cc, predictTaken ? 1 : 0, label);
-        }
-    }
-
-    public static class Bpleu extends Fmt00c {
-
-        public Bpleu(CC cc, int simm19) {
-            super(0, ConditionFlag.LessEqualUnsigned, Op2s.Bp, cc, 1, simm19);
-        }
-
-        public Bpleu(CC cc, Label label) {
-            super(0, ConditionFlag.LessEqualUnsigned, Op2s.Bp, cc, 1, label);
-        }
-
-        public Bpleu(CC cc, boolean annul, boolean predictTaken, Label label) {
-            super(annul ? 1 : 0, ConditionFlag.LessEqualUnsigned, Op2s.Bp, cc, predictTaken ? 1 : 0, label);
-        }
-    }
-
-    public static class Bpn extends Fmt00c {
-
-        public Bpn(CC cc, int simm19) {
-            super(0, ConditionFlag.Never, Op2s.Bp, cc, 1, simm19);
-        }
-
-        public Bpn(CC cc, Label label) {
-            super(0, ConditionFlag.Never, Op2s.Bp, cc, 1, label);
-        }
+    public void sethi(int imm22, Register dst) {
+        fmt00(dst.encoding, Op2s.Sethi.value, imm22);
     }
 
-    public static class Bpne extends Fmt00c {
-
-        public Bpne(CC cc, int simm19) {
-            super(0, ConditionFlag.NotZero, Op2s.Bp, cc, 1, simm19);
-        }
-
-        public Bpne(CC cc, Label label) {
-            super(0, ConditionFlag.NotZero, Op2s.Bp, cc, 1, label);
-        }
-
-        public Bpne(CC cc, boolean annul, boolean predictTaken, Label label) {
-            super(annul ? 1 : 0, ConditionFlag.NotZero, Op2s.Bp, cc, predictTaken ? 1 : 0, label);
-        }
+    // @formatter:off
+    /**
+     * Instruction format for calls.
+     * <pre>
+     * | 01  |                      disp30                             |
+     * |31 30|29                                                      0|
+     * </pre>
+     */
+    // @formatter:on
+    public void call(int disp30) {
+        assert isImm(disp30, 30);
+        int instr = 1 << 30;
+        instr |= disp30;
+        emitInt(instr);
     }
 
-    public static class Bpneg extends Fmt00c {
-
-        public Bpneg(CC cc, int simm19) {
-            super(0, ConditionFlag.Negative, Op2s.Bp, cc, 1, simm19);
-        }
-
-        public Bpneg(CC cc, Label label) {
-            super(0, ConditionFlag.Negative, Op2s.Bp, cc, 1, label);
-        }
+    public void add(Register rs1, Register rs2, Register rd) {
+        op3(Add, rs1, rs2, rd);
     }
 
-    public static class Bppos extends Fmt00c {
-
-        public Bppos(CC cc, int simm19) {
-            super(0, ConditionFlag.Positive, Op2s.Bp, cc, 1, simm19);
-        }
-
-        public Bppos(CC cc, Label label) {
-            super(0, ConditionFlag.Positive, Op2s.Bp, cc, 1, label);
-        }
+    public void add(Register rs1, int simm13, Register rd) {
+        op3(Add, rs1, simm13, rd);
     }
 
-    public static class Bpvc extends Fmt00c {
-
-        public Bpvc(CC cc, int simm19) {
-            super(0, ConditionFlag.OverflowClear, Op2s.Bp, cc, 1, simm19);
-        }
-
-        public Bpvc(CC cc, Label label) {
-            super(0, ConditionFlag.OverflowClear, Op2s.Bp, cc, 1, label);
-        }
+    public void addc(Register rs1, Register rs2, Register rd) {
+        op3(Addc, rs1, rs2, rd);
     }
 
-    public static class Bpvs extends Fmt00c {
+    public void addc(Register rs1, int simm13, Register rd) {
+        op3(Addc, rs1, simm13, rd);
+    }
 
-        public Bpvs(CC cc, int simm19) {
-            super(0, ConditionFlag.OverflowSet, Op2s.Bp, cc, 1, simm19);
-        }
-
-        public Bpvs(CC cc, Label label) {
-            super(0, ConditionFlag.OverflowSet, Op2s.Bp, cc, 1, label);
-        }
+    public void addcc(Register rs1, Register rs2, Register rd) {
+        op3(Addcc, rs1, rs2, rd);
     }
 
-    public static class Bshuffle extends Fmt3p {
-
-        public Bshuffle(Register src1, Register src2, Register dst) {
-            /* VIS2 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Bshuffle, src1, src2, dst);
-        }
+    public void addcc(Register rs1, int simm13, Register rd) {
+        op3(Addcc, rs1, simm13, rd);
     }
 
-    public static class Call extends Fmt01 {
-
-        public Call(int disp30) {
-            super(disp30);
-        }
+    public void and(Register rs1, Register rs2, Register rd) {
+        op3(And, rs1, rs2, rd);
     }
 
-    public static class CammelliaFl extends Fmt3p {
-
-        public CammelliaFl(Register src1, Register src2, Register dst) {
-            /* CAMELLIA only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.CammelliaFl, src1, src2, dst);
-        }
+    public void and(Register rs1, int simm13, Register rd) {
+        op3(And, rs1, simm13, rd);
     }
 
-    public static class CammelliaFli extends Fmt3p {
+    public void andcc(Register rs1, Register rs2, Register rd) {
+        op3(Andcc, rs1, rs2, rd);
+    }
 
-        public CammelliaFli(Register src1, Register src2, Register dst) {
-            /* CAMELLIA only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.CammelliaFli, src1, src2, dst);
-        }
+    public void andcc(Register rs1, int simm13, Register rd) {
+        op3(Andcc, rs1, simm13, rd);
     }
 
-    public static class Casa extends Fmt11 {
-
-        public Casa(Register src1, Register src2, Register dst, Asi asi) {
-            super(Op3s.Casa, src1, src2, dst, asi);
-        }
+    public void andn(Register rs1, Register rs2, Register rd) {
+        op3(Andn, rs1, rs2, rd);
     }
 
-    public static class Casxa extends Fmt11 {
-
-        public Casxa(Register src1, Register src2, Register dst, Asi asi) {
-            super(Op3s.Casxa, src1, src2, dst, asi);
-        }
-    }
-
-    public static class Cmask8 extends Fmt3n {
-
-        public Cmask8(Register src2) {
-            super(Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Cmask8.getValue(), src2.encoding(), 0);
-        }
+    public void andn(Register rs1, int simm13, Register rd) {
+        op3(Andn, rs1, simm13, rd);
     }
 
-    public static class Cmask16 extends Fmt3n {
-
-        public Cmask16(Register src2) {
-            super(Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Cmask16.getValue(), src2.encoding(), 0);
-        }
+    public void andncc(Register rs1, Register rs2, Register rd) {
+        op3(Andncc, rs1, rs2, rd);
     }
 
-    public static class Cmask32 extends Fmt3n {
-
-        public Cmask32(Register src2) {
-            super(Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Cmask32.getValue(), src2.encoding(), 0);
-        }
+    public void andncc(Register rs1, int simm13, Register rd) {
+        op3(Andncc, rs1, simm13, rd);
     }
 
-    public static class Crc32c extends Fmt3p {
-
-        public Crc32c(Register src1, Register src2, Register dst) {
-            /* CRYPTO only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Crc32c, src1, src2, dst);
-        }
+    public void movwtos(Register rs2, Register rd) {
+        op3(Impdep1, Movwtos, null, rs2, rd);
     }
 
-    public static class CBcondw extends Fmt00e {
-        public CBcondw(ConditionFlag flag, Register src1, Register src2, Label label) {
-            super(flag.getValue(), 0, src1.encoding(), -1, 0, src2.encoding(), label);
-        }
-
-        public CBcondw(ConditionFlag flag, Register src1, int simm5, Label label) {
-            super(flag.getValue(), 0, src1.encoding(), -1, 1, simm5, label);
-        }
+    public void umulxhi(Register rs1, Register rs2, Register rd) {
+        op3(Impdep1, UMulxhi, rs1, rs2, rd);
     }
 
-    public static class CBcondx extends Fmt00e {
-        public CBcondx(ConditionFlag flag, Register src1, Register src2, Label label) {
-            super(flag.getValue(), 1, src1.encoding(), -1, 0, src2.encoding(), label);
-        }
-
-        public CBcondx(ConditionFlag flag, Register src1, int simm5, Label label) {
-            super(flag.getValue(), 1, src1.encoding(), -1, 1, simm5, label);
-        }
+    public void fdtos(Register rs2, Register rd) {
+        op3(Fpop1, Fdtos, null, rs2, rd);
     }
 
-    public static class Edge8cc extends Fmt3p {
-
-        public Edge8cc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge8cc, src1, src2, dst);
-        }
+    public void movstouw(Register rs2, Register rd) {
+        op3(Impdep1, Movstosw, null, rs2, rd);
     }
 
-    public static class Edge8n extends Fmt3p {
-
-        public Edge8n(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge8n, src1, src2, dst);
-        }
+    public void movstosw(Register rs2, Register rd) {
+        op3(Impdep1, Movstosw, null, rs2, rd);
     }
 
-    public static class Edge8lcc extends Fmt3p {
-
-        public Edge8lcc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge8lcc, src1, src2, dst);
-        }
+    public void movdtox(Register rs2, Register rd) {
+        op3(Impdep1, Movdtox, null, rs2, rd);
     }
 
-    public static class Edge8ln extends Fmt3p {
-
-        public Edge8ln(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge8ln, src1, src2, dst);
-        }
+    public void movxtod(Register rs2, Register rd) {
+        op3(Impdep1, Movxtod, null, rs2, rd);
     }
 
-    public static class Edge16cc extends Fmt3p {
-
-        public Edge16cc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge16cc, src1, src2, dst);
-        }
+    public void fadds(Register rs1, Register rs2, Register rd) {
+        op3(Fpop1, Fadds, rs1, rs2, rd);
     }
 
-    public static class Edge16n extends Fmt3p {
-
-        public Edge16n(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge16n, src1, src2, dst);
-        }
+    public void faddd(Register rs1, Register rs2, Register rd) {
+        op3(Fpop1, Faddd, rs1, rs2, rd);
     }
 
-    public static class Edge16lcc extends Fmt3p {
-
-        public Edge16lcc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge16lcc, src1, src2, dst);
-        }
+    public void faddq(Register rs1, Register rs2, Register rd) {
+        op3(Fpop1, Faddq, rs1, rs2, rd);
     }
 
-    public static class Edge16ln extends Fmt3p {
-
-        public Edge16ln(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge16ln, src1, src2, dst);
-        }
+    public void fdivs(Register rs1, Register rs2, Register rd) {
+        op3(Fpop1, Fdivs, rs1, rs2, rd);
     }
 
-    public static class Edge32cc extends Fmt3p {
-
-        public Edge32cc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge32cc, src1, src2, dst);
-        }
-    }
-
-    public static class Edge32n extends Fmt3p {
-
-        public Edge32n(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge32n, src1, src2, dst);
-        }
+    public void fdivd(Register rs1, Register rs2, Register rd) {
+        op3(Fpop1, Fdivd, rs1, rs2, rd);
     }
 
-    public static class Edge32lcc extends Fmt3p {
-
-        public Edge32lcc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge32lcc, src1, src2, dst);
-        }
+    public void fmovs(Register rs2, Register rd) {
+        op3(Fpop1, Fmovs, null, rs2, rd);
     }
 
-    public static class Edge32ln extends Fmt3p {
-
-        public Edge32ln(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Edge32ln, src1, src2, dst);
-        }
+    public void fmovd(Register rs2, Register rd) {
+        op3(Fpop1, Fmovd, null, rs2, rd);
     }
 
-    public static class Fadds extends Fmt3p {
-
-        public Fadds(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fadds, src1, src2, dst);
-        }
+    public void fmuls(Register rs1, Register rs2, Register rd) {
+        op3(Fpop1, Fmuls, rs1, rs2, rd);
     }
 
-    public static class Faddd extends Fmt3p {
-
-        public Faddd(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Faddd, src1, src2, dst);
-        }
-    }
-
-    public static class Faddq extends Fmt3p {
-
-        public Faddq(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Faddq, src1, src2, dst);
-        }
+    public void fsmuld(Register rs1, Register rs2, Register rd) {
+        op3(Fpop1, Fsmuld, rs1, rs2, rd);
     }
 
-    public static class Faligndata extends Fmt3p {
-
-        public Faligndata(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Faligndatag, src1, src2, dst);
-        }
+    public void fmuld(Register rs1, Register rs2, Register rd) {
+        op3(Fpop1, Fmuld, rs1, rs2, rd);
     }
 
-    public static class Fdivs extends Fmt3p {
-
-        public Fdivs(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fdivs, src1, src2, dst);
-        }
+    public void fnegs(Register rs2, Register rd) {
+        op3(Fpop1, Fnegs, null, rs2, rd);
     }
 
-    public static class Fdivd extends Fmt3p {
-
-        public Fdivd(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fdivd, src1, src2, dst);
-        }
+    public void fnegd(Register rs2, Register rd) {
+        op3(Fpop1, Fnegd, null, rs2, rd);
     }
 
     /**
-     * Floating-point multiply-add single (fused).
-     */
-    public static class Fmadds extends Fmt5a {
-
-        public Fmadds(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) {
-            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fmadds.getValue(), src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding());
-        }
-    }
-
-    /**
-     * Floating-point multiply-add double (fused).
-     */
-    public static class Fmaddd extends Fmt5a {
-
-        public Fmaddd(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) {
-            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fmaddd.getValue(), src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding());
-        }
-    }
-
-    /**
-     * 16-bit partitioned average.
+     * Helper method to determine if the instruction needs the X bit set.
      */
-    public static class Fmean16 extends Fmt3p {
-
-        public Fmean16(Register src1, Register src2, Register dst) {
-            /* VIS3 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fmean16, src1, src2, dst);
-        }
-    }
-
-    public static class Fmsubs extends Fmt5a {
-
-        public Fmsubs(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) {
-            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fmsubs.getValue(), src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding());
-            assert isSingleFloatRegister(src1);
-            assert isSingleFloatRegister(src2);
-            assert isSingleFloatRegister(src3);
-            assert isSingleFloatRegister(dst);
-        }
-    }
-
-    public static class Fmsubd extends Fmt5a {
-
-        public Fmsubd(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) {
-            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fmsubd.getValue(), src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding());
-            assert isDoubleFloatRegister(src1);
-            assert isDoubleFloatRegister(src2);
-            assert isDoubleFloatRegister(src3);
-            assert isDoubleFloatRegister(dst);
-        }
-    }
-
-    public static class Fmovs extends Fmt3p {
-
-        public Fmovs(Register src, Register dst) {
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fmovs, g0, src, dst);
-            assert isSingleFloatRegister(src);
-            assert isSingleFloatRegister(dst);
-        }
-    }
-
-    public static class Fmovd extends Fmt3p {
-
-        public Fmovd(Register src, Register dst) {
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fmovd, g0, src, dst);
-        }
-    }
-
-    public static class Fmuls extends Fmt3p {
-
-        public Fmuls(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fmuls, src1, src2, dst);
-            assert isSingleFloatRegister(src1);
-            assert isSingleFloatRegister(src2);
-            assert isSingleFloatRegister(dst);
-        }
-    }
-
-    public static class Fmuld extends Fmt3p {
-
-        public Fmuld(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fmuld, src1, src2, dst);
-            assert isDoubleFloatRegister(src1);
-            assert isDoubleFloatRegister(src2);
-            assert isDoubleFloatRegister(dst);
-        }
-    }
-
-    public static class Fsmuld extends Fmt3p {
-
-        public Fsmuld(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fsmuld, src1, src2, dst);
-            assert isSingleFloatRegister(src1);
-            assert isSingleFloatRegister(src2);
-            assert isDoubleFloatRegister(dst);
-        }
-    }
-
-    public static class Fmul8x16 extends Fmt3p {
-
-        public Fmul8x16(Register src1, Register src2, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fmul8x16, src1, src2, dst);
-        }
-    }
-
-    public static class Fmul8x16au extends Fmt3p {
-
-        public Fmul8x16au(Register src1, Register src2, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fmul8x16, src1, src2, dst);
-        }
-    }
-
-    public static class Fmul8x16al extends Fmt3p {
-
-        public Fmul8x16al(Register src1, Register src2, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fmul8x16al, src1, src2, dst);
-        }
-    }
-
-    public static class Fmul8sux16 extends Fmt3p {
-
-        public Fmul8sux16(Register src1, Register src2, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fmul8sux16, src1, src2, dst);
-        }
-    }
-
-    public static class Fmul8ulx16 extends Fmt3p {
-
-        public Fmul8ulx16(Register src1, Register src2, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fmul8ulx16, src1, src2, dst);
-        }
-    }
-
-    public static class Fmuld8sux16 extends Fmt3p {
-
-        public Fmuld8sux16(Register src1, Register src2, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fmuld8sux16, src1, src2, dst);
-        }
-    }
-
-    public static class Fmuld8ulx16 extends Fmt3p {
-
-        public Fmuld8ulx16(Register src1, Register src2, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fmuld8ulx16, src1, src2, dst);
-        }
-    }
-
-    public static class Fnadds extends Fmt3p {
-
-        public Fnadds(Register src1, Register src2, Register dst) {
-            /* VIS3 only */
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fnadds, src1, src2, dst);
-            assert isSingleFloatRegister(src1);
-            assert isSingleFloatRegister(src2);
-            assert isSingleFloatRegister(dst);
+    private static int getXBit(Op3s op3) {
+        switch (op3) {
+            case Sllx:
+            case Srax:
+            case Srlx:
+                return 1 << 12;
+            default:
+                return 0;
         }
     }
 
-    public static class Fnaddd extends Fmt3p {
-
-        public Fnaddd(Register src1, Register src2, Register dst) {
-            /* VIS3 only */
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fnaddd, src1, src2, dst);
-            assert isDoubleFloatRegister(src1);
-            assert isDoubleFloatRegister(src2);
-            assert isDoubleFloatRegister(dst);
-        }
-    }
-
-    public static class Fnegs extends Fmt3n {
-
-        public Fnegs(Register src2, Register dst) {
-            super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fnegs.getValue(), src2.encoding(), dst.encoding());
-            assert isSingleFloatRegister(src2);
-            assert isSingleFloatRegister(dst);
-        }
-    }
-
-    public static class Fnegd extends Fmt3n {
-
-        public Fnegd(Register src2, Register dst) {
-            super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fnegd.getValue(), src2.encoding(), dst.encoding());
-            assert isDoubleFloatRegister(src2);
-            assert isDoubleFloatRegister(dst);
-        }
-    }
-
-    public static class Fnhadds extends Fmt3p {
-
-        public Fnhadds(Register src1, Register src2, Register dst) {
-            /* VIS3 only */
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fnhadds, src1, src2, dst);
-            assert isSingleFloatRegister(src1);
-            assert isSingleFloatRegister(src2);
-            assert isSingleFloatRegister(dst);
-        }
+    public void fstoi(Register rs2, Register rd) {
+        op3(Fpop1, Fstoi, null, rs2, rd);
     }
 
-    public static class Fnhaddd extends Fmt3p {
-
-        public Fnhaddd(Register src1, Register src2, Register dst) {
-            /* VIS3 only */
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fnhaddd, src1, src2, dst);
-            assert isDoubleFloatRegister(src1);
-            assert isDoubleFloatRegister(src2);
-            assert isDoubleFloatRegister(dst);
-        }
-    }
-
-    public static class Fnmadds extends Fmt5a {
-
-        public Fnmadds(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) {
-            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fnmadds.getValue(), src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding());
-            assert isSingleFloatRegister(src1);
-            assert isSingleFloatRegister(src2);
-            assert isSingleFloatRegister(src3);
-            assert isSingleFloatRegister(dst);
-        }
+    public void fstox(Register rs2, Register rd) {
+        op3(Fpop1, Fstox, null, rs2, rd);
     }
 
-    public static class Fnmaddd extends Fmt5a {
-
-        public Fnmaddd(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) {
-            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fnmaddd.getValue(), src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding());
-            assert isDoubleFloatRegister(src1);
-            assert isDoubleFloatRegister(src2);
-            assert isDoubleFloatRegister(src3);
-            assert isDoubleFloatRegister(dst);
-        }
+    public void fdtox(Register rs2, Register rd) {
+        op3(Fpop1, Fdtox, null, rs2, rd);
     }
 
-    public static class Fnmsubs extends Fmt5a {
-
-        public Fnmsubs(SPARCAssembler masm, Register src1, Register src2, Register src3, Register dst) {
-            super(masm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fnmsubs.getValue(), src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding());
-            assert isSingleFloatRegister(src1);
-            assert isSingleFloatRegister(src2);
-            assert isSingleFloatRegister(src3);
-            assert isSingleFloatRegister(dst);
-        }
-    }
-
-    public static class Fnmsubd extends Fmt5a {
-
-        public Fnmsubd(SPARCAssembler masm, Register src1, Register src2, Register src3, Register dst) {
-            super(masm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fnmsubd.getValue(), src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding());
-            assert isDoubleFloatRegister(src1);
-            assert isDoubleFloatRegister(src2);
-            assert isDoubleFloatRegister(src3);
-            assert isDoubleFloatRegister(dst);
-        }
+    public void fstod(Register rs2, Register rd) {
+        op3(Fpop1, Fstod, null, rs2, rd);
     }
 
-    public static class Fnmuls extends Fmt3p {
-
-        public Fnmuls(Register src1, Register src2, Register dst) {
-            /* VIS3 only */
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fnmuls, src1, src2, dst);
-            assert isSingleFloatRegister(src1);
-            assert isSingleFloatRegister(src2);
-            assert isSingleFloatRegister(dst);
-        }
-    }
-
-    public static class Fnmuld extends Fmt3p {
-
-        public Fnmuld(Register src1, Register src2, Register dst) {
-            /* VIS3 only */
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fnmuld, src1, src2, dst);
-            assert isDoubleFloatRegister(src1);
-            assert isDoubleFloatRegister(src2);
-            assert isDoubleFloatRegister(dst);
-        }
+    public void fdtoi(Register rs2, Register rd) {
+        op3(Fpop1, Fdtoi, null, rs2, rd);
     }
 
-    public static class Fnsmuld extends Fmt3p {
-
-        public Fnsmuld(Register src1, Register src2, Register dst) {
-            /* VIS3 only */
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fnsmuld, src1, src2, dst);
-            assert isDoubleFloatRegister(src1);
-            assert isDoubleFloatRegister(src2);
-            assert isDoubleFloatRegister(dst);
-        }
-    }
-
-    public static class Fstoi extends Fmt3n {
-
-        public Fstoi(Register src2, Register dst) {
-            super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fstoi.getValue(), src2.encoding(), dst.encoding());
-            assert isSingleFloatRegister(dst);
-            assert isSingleFloatRegister(src2);
-        }
-    }
-
-    public static class Fstox extends Fmt3n {
-
-        public Fstox(Register src2, Register dst) {
-            super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fstox.getValue(), src2.encoding(), dst.encoding());
-            assert isDoubleFloatRegister(dst);
-            assert isSingleFloatRegister(src2);
-        }
+    public void fitos(Register rs2, Register rd) {
+        op3(Fpop1, Fitos, null, rs2, rd);
     }
 
-    public static class Fdtox extends Fmt3n {
-
-        public Fdtox(Register src2, Register dst) {
-            super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fdtox.getValue(), src2.encoding(), dst.encoding());
-            assert isDoubleFloatRegister(src2);
-            assert isDoubleFloatRegister(dst);
-        }
-    }
-
-    public static class Fstod extends Fmt3n {
-
-        public Fstod(Register src2, Register dst) {
-            super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fstod.getValue(), src2.encoding(), dst.encoding());
-            assert isDoubleFloatRegister(dst);
-            assert isSingleFloatRegister(src2);
-        }
-    }
-
-    /**
-     * Convert Double to 32-bit Integer.
-     */
-    public static class Fdtoi extends Fmt3n {
-
-        public Fdtoi(Register src2, Register dst) {
-            super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fdtoi.getValue(), src2.encoding(), dst.encoding());
-            assert isDoubleFloatRegister(src2);
-            assert isSingleFloatRegister(dst);
-        }
+    public void fitod(Register rs2, Register rd) {
+        op3(Fpop1, Fitod, null, rs2, rd);
     }
 
-    public static class Fitos extends Fmt3n {
-
-        public Fitos(Register src2, Register dst) {
-            super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fitos.getValue(), src2.encoding(), dst.encoding());
-            assert isSingleFloatRegister(src2);
-            assert isSingleFloatRegister(dst);
-        }
+    public void fxtos(Register rs2, Register rd) {
+        op3(Fpop1, Fxtos, null, rs2, rd);
     }
 
-    public static class Fitod extends Fmt3n {
-
-        public Fitod(Register src2, Register dst) {
-            super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fitod.getValue(), src2.encoding(), dst.encoding());
-            assert isSingleFloatRegister(src2);
-            assert isDoubleFloatRegister(dst);
-        }
+    public void fxtod(Register rs2, Register rd) {
+        op3(Fpop1, Fxtod, null, rs2, rd);
     }
 
-    public static class Fxtos extends Fmt3n {
-
-        public Fxtos(Register src2, Register dst) {
-            super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fxtos.getValue(), src2.encoding(), dst.encoding());
-            assert isDoubleFloatRegister(src2);
-            assert isSingleFloatRegister(dst);
-        }
-    }
-
-    public static class Fxtod extends Fmt3n {
-
-        public Fxtod(Register src2, Register dst) {
-            super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fxtod.getValue(), src2.encoding(), dst.encoding());
-            assert isDoubleFloatRegister(src2);
-            assert isDoubleFloatRegister(dst);
-        }
+    public void fzeros(Register rd) {
+        op3(Impdep1, Fzeros, null, null, rd);
     }
 
-    /**
-     * Flush register windows.
-     */
-    public static class Flushw extends Fmt10 {
-
-        public Flushw() {
-            super(Op3s.Flushw);
-        }
-    }
-
-    public static class Fpack16 extends Fmt3p {
-
-        public Fpack16(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpack16, src1, src2, dst);
-        }
-    }
-
-    public static class Fpack32 extends Fmt3p {
-
-        public Fpack32(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpack32, src1, src2, dst);
-        }
+    public void fzerod(Register rd) {
+        op3(Impdep1, Fzerod, null, null, rd);
     }
 
-    public static class Fpackfix extends Fmt3p {
-
-        public Fpackfix(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpackfix, src1, src2, dst);
-        }
-    }
-
-    public static class Fpmaddx extends Fmt5a {
-
-        public Fpmaddx(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) {
-            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), 0, src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding());
-            assert isDoubleFloatRegister(src1);
-            assert isDoubleFloatRegister(src2);
-            assert isDoubleFloatRegister(src3);
-            assert isDoubleFloatRegister(dst);
-        }
-    }
-
-    public static class Fpmaddxhi extends Fmt5a {
-
-        public Fpmaddxhi(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) {
-            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), 4, src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding());
-            assert isDoubleFloatRegister(src1);
-            assert isDoubleFloatRegister(src2);
-            assert isDoubleFloatRegister(src3);
-            assert isDoubleFloatRegister(dst);
-        }
+    public void flushw() {
+        op3(Flushw, g0, g0, g0);
     }
 
-    public static class Fpmerge extends Fmt3p {
-
-        public Fpmerge(Register src1, Register src2, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpmerge, src1, src2, dst);
-            assert isSingleFloatRegister(src1);
-            assert isSingleFloatRegister(src2);
-            assert isDoubleFloatRegister(dst);
-        }
-    }
-
-    public static class Fpsub16 extends Fmt3p {
-
-        public Fpsub16(Register src1, Register src2, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpsub16, src1, src2, dst);
-        }
-    }
-
-    public static class Fpsub16s extends Fmt3p {
-
-        public Fpsub16s(Register src1, Register src2, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpsub16s, src1, src2, dst);
-        }
+    public void fsqrtd(Register rs2, Register rd) {
+        op3(Fpop1, Fsqrtd, null, rs2, rd);
     }
 
-    public static class Fpsub32 extends Fmt3p {
-
-        public Fpsub32(Register src1, Register src2, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpsub32, src1, src2, dst);
-        }
+    public void fsqrts(Register rs2, Register rd) {
+        op3(Fpop1, Fsqrts, null, rs2, rd);
     }
 
-    public static class Fpsub32s extends Fmt3p {
-
-        public Fpsub32s(Register src1, Register src2, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpsub32s, src1, src2, dst);
-        }
-    }
-
-    public static class Fpsub64 extends Fmt3p {
-
-        public Fpsub64(Register src1, Register src2, Register dst) {
-            /* OSA 2011 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpsub64, src1, src2, dst);
-        }
-    }
-
-    public static class Fpsubs16 extends Fmt3p {
-
-        public Fpsubs16(Register src1, Register src2, Register dst) {
-            /* OSA 2011 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpsubs16, src1, src2, dst);
-        }
+    public void fabss(Register rs2, Register rd) {
+        op3(Fpop1, Fabss, null, rs2, rd);
     }
 
-    public static class Fpsubs16s extends Fmt3p {
-
-        public Fpsubs16s(Register src1, Register src2, Register dst) {
-            /* OSA 2011 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpsubs16s, src1, src2, dst);
-        }
-    }
-
-    public static class Fpsubs32 extends Fmt3p {
-
-        public Fpsubs32(Register src1, Register src2, Register dst) {
-            /* OSA 2011 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpsubs32, src1, src2, dst);
-        }
-    }
-
-    public static class Fpsubs32s extends Fmt3p {
-
-        public Fpsubs32s(Register src1, Register src2, Register dst) {
-            /* OSA 2011 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fpsubs32s, src1, src2, dst);
-        }
+    public void fabsd(Register rs2, Register rd) {
+        op3(Fpop1, Fabsd, null, rs2, rd);
     }
 
-    public static class Fsqrtd extends Fmt3p {
-
-        public Fsqrtd(Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fsqrtd, SPARC.r0, src2, dst);
-        }
-    }
-
-    public static class Fsqrts extends Fmt3p {
-
-        public Fsqrts(Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fsqrts, SPARC.r0, src2, dst);
-        }
+    public void fsubs(Register rs1, Register rs2, Register rd) {
+        op3(Fpop1, Fsubs, rs1, rs2, rd);
     }
 
-    public static class Fabss extends Fmt3p {
-        public Fabss(Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fabss, SPARC.r0, src2, dst);
-        }
-    }
-
-    public static class Fabsd extends Fmt3p {
-        public Fabsd(Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fabsd, SPARC.r0, src2, dst);
-        }
-    }
-
-    public static class Fsrc1d extends Fmt3p {
-
-        public Fsrc1d(Register src1, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fsrc1d, src1, SPARC.r0, dst);
-        }
+    public void fsubd(Register rs1, Register rs2, Register rd) {
+        op3(Fpop1, Fsubd, rs1, rs2, rd);
     }
 
-    public static class Fsrc1s extends Fmt3p {
-
-        public Fsrc1s(Register src1, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fsrc1s, src1, SPARC.r0, dst);
-        }
-    }
-
-    public static class Fsrc2d extends Fmt3p {
-
-        public Fsrc2d(Register src2, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fsrc2d, SPARC.r0, src2, dst);
-        }
-    }
-
-    public static class Fsrc2s extends Fmt3p {
-
-        public Fsrc2s(Register src2, Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fsrc2s, SPARC.r0, src2, dst);
-        }
-    }
-
-    public static class Fsubs extends Fmt3p {
-
-        public Fsubs(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fsubs, src1, src2, dst);
-            assert isSingleFloatRegister(src1);
-            assert isSingleFloatRegister(src2);
-            assert isSingleFloatRegister(dst);
-        }
-    }
-
-    public static class Fsubd extends Fmt3p {
-
-        public Fsubd(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fsubd, src1, src2, dst);
-            assert isDoubleFloatRegister(src1);
-            assert isDoubleFloatRegister(src2);
-            assert isDoubleFloatRegister(dst);
-        }
-    }
-
-    public static class Fsubq extends Fmt3p {
-
-        public Fsubq(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fsubq, src1, src2, dst);
-        }
-    }
-
-    public static class Fzeros extends Fmt3n {
-
-        public Fzeros(Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Fzeros.getValue(), 0, dst.encoding());
-            assert isSingleFloatRegister(dst);
-        }
+    // @formatter:off
+    /**
+     * Instruction format for fcmp.
+     * <pre>
+     * | 10  | --- |cc1|cc0|desc |   rs1   |   opf  | rs2 |
+     * |31 30|29 27|26 |25 |24 19|18     14|13     5|4   0|
+     * </pre>
+     */
+    // @formatter:on
+    public void fcmp(CC cc, Opfs opf, Register rs1, Register rs2) {
+        int a = cc.value;
+        int b = opf.value << 5 | rs2.encoding;
+        fmt10(a, Fcmp.value, rs1.encoding, b);
     }
 
-    public static class Fzerod extends Fmt3n {
-
-        public Fzerod(Register dst) {
-            /* VIS1 only */
-            super(Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Fzerod.getValue(), 0, dst.encoding());
-            assert isDoubleFloatRegister(dst);
-        }
-    }
-
-    public static class Fcmp extends Fmt3c {
-
-        public Fcmp(CC cc, Opfs opf, Register r1, Register r2) {
-            super(Ops.ArithOp, cc, 0b110101, opf, r1, r2);
-            assert opf != Opfs.Fcmpd || (isDoubleFloatRegister(r1) && isDoubleFloatRegister(r2));
-            assert opf != Opfs.Fcmps || (isSingleFloatRegister(r1) && isSingleFloatRegister(r2));
-        }
-    }
-
-    public static class Fba extends Fmt00b {
-        public Fba(boolean annul, Label label) {
-            super(annul, FCond.Fba, Op2s.Fb, label);
-        }
-
-        public Fba(boolean annul, int disp) {
-            super(annul, FCond.Fba, Op2s.Fb, disp);
-        }
-    }
-
-    public static class Fbn extends Fmt00b {
-        public Fbn(boolean annul, Label label) {
-            super(annul, FCond.Fbn, Op2s.Fb, label);
-        }
-
-        public Fbn(boolean annul, int disp) {
-            super(annul, FCond.Fbn, Op2s.Fb, disp);
-        }
-    }
-
-    public static class Fbu extends Fmt00b {
-        public Fbu(boolean annul, Label label) {
-            super(annul, FCond.Fbu, Op2s.Fb, label);
-        }
-
-        public Fbu(boolean annul, int disp) {
-            super(annul, FCond.Fbu, Op2s.Fb, disp);
-        }
-    }
-
-    public static class Fbg extends Fmt00b {
-        public Fbg(boolean annul, Label label) {
-            super(annul, FCond.Fbg, Op2s.Fb, label);
-        }
-
-        public Fbg(boolean annul, int disp) {
-            super(annul, FCond.Fbg, Op2s.Fb, disp);
-        }
-    }
-
-    public static class Fbug extends Fmt00b {
-        public Fbug(boolean annul, Label label) {
-            super(annul, FCond.Fbug, Op2s.Fb, label);
-        }
-
-        public Fbug(boolean annul, int disp) {
-            super(annul, FCond.Fbug, Op2s.Fb, disp);
-        }
-    }
-
-    public static class Fbl extends Fmt00b {
-        public Fbl(boolean annul, Label label) {
-            super(annul, FCond.Fbl, Op2s.Fb, label);
-        }
-
-        public Fbl(boolean annul, int disp) {
-            super(annul, FCond.Fbl, Op2s.Fb, disp);
-        }
-    }
-
-    public static class Fbul extends Fmt00b {
-        public Fbul(boolean annul, Label label) {
-            super(annul, FCond.Fbul, Op2s.Fb, label);
-        }
-
-        public Fbul(boolean annul, int disp) {
-            super(annul, FCond.Fbul, Op2s.Fb, disp);
-        }
-    }
-
-    public static class Fblg extends Fmt00b {
-        public Fblg(boolean annul, Label label) {
-            super(annul, FCond.Fblg, Op2s.Fb, label);
-        }
-
-        public Fblg(boolean annul, int disp) {
-            super(annul, FCond.Fblg, Op2s.Fb, disp);
-        }
-    }
-
-    public static class Fbne extends Fmt00b {
-        public Fbne(boolean annul, Label label) {
-            super(annul, FCond.Fbne, Op2s.Fb, label);
-        }
-
-        public Fbne(boolean annul, int disp) {
-            super(annul, FCond.Fbne, Op2s.Fb, disp);
-        }
+    // @formatter:off
+    /**
+     * Instruction format for most arithmetic stuff.
+     * <pre>
+     * |  10 | rd  | op3 | rs1 |   b   |
+     * |31 30|29 25|24 19|18 14|13    0|
+     * </pre>
+     */
+    // @formatter:on
+    protected void fmt10(int rd, int op3, int rs1, int b) {
+        fmt(0b10, rd, op3, rs1, b);
     }
 
-    public static class Fbe extends Fmt00b {
-        public Fbe(boolean annul, Label label) {
-            super(annul, FCond.Fbe, Op2s.Fb, label);
-        }
-
-        public Fbe(boolean annul, int disp) {
-            super(annul, FCond.Fbe, Op2s.Fb, disp);
-        }
-    }
-
-    public static class Fbue extends Fmt00b {
-        public Fbue(boolean annul, Label label) {
-            super(annul, FCond.Fbue, Op2s.Fb, label);
-        }
-
-        public Fbue(boolean annul, int disp) {
-            super(annul, FCond.Fbue, Op2s.Fb, disp);
-        }
-    }
-
-    public static class Fbge extends Fmt00b {
-        public Fbge(boolean annul, Label label) {
-            super(annul, FCond.Fbge, Op2s.Fb, label);
-        }
-
-        public Fbge(boolean annul, int disp) {
-            super(annul, FCond.Fbge, Op2s.Fb, disp);
-        }
-    }
-
-    public static class Fbuge extends Fmt00b {
-        public Fbuge(boolean annul, Label label) {
-            super(annul, FCond.Fbuge, Op2s.Fb, label);
-        }
-
-        public Fbuge(boolean annul, int disp) {
-            super(annul, FCond.Fbuge, Op2s.Fb, disp);
-        }
-    }
-
-    public static class Fble extends Fmt00b {
-        public Fble(boolean annul, Label label) {
-            super(annul, FCond.Fble, Op2s.Fb, label);
-        }
-
-        public Fble(boolean annul, int disp) {
-            super(annul, FCond.Fble, Op2s.Fb, disp);
-        }
+    // @formatter:off
+    /**
+     * Instruction format for most arithmetic stuff.
+     * <pre>
+     * |  op | rd  | op3 | rs1 |   b   |
+     * |31 30|29 25|24 19|18 14|13    0|
+     * </pre>
+     */
+    // @formatter:on
+    protected void fmt(int op, int rd, int op3, int rs1, int b) {
+        assert isImm(rd, 5) && isImm(op3, 6) && isImm(b, 14) : String.format("rd: 0x%x op3: 0x%x b: 0x%x", rd, op3, b);
+        int instr = op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | b;
+        emitInt(instr);
     }
 
-    public static class Fbule extends Fmt00b {
-        public Fbule(boolean annul, Label label) {
-            super(annul, FCond.Fbule, Op2s.Fb, label);
-        }
-
-        public Fbule(boolean annul, int disp) {
-            super(annul, FCond.Fbule, Op2s.Fb, disp);
-        }
+    public void illtrap(int const22) {
+        fmt00(0, Op2s.Illtrap.value, const22);
     }
 
-    public static class Fbo extends Fmt00b {
-        public Fbo(boolean annul, Label label) {
-            super(annul, FCond.Fbo, Op2s.Fb, label);
-        }
-
-        public Fbo(boolean annul, int disp) {
-            super(annul, FCond.Fbo, Op2s.Fb, disp);
-        }
-    }
-
-    public static class Illtrap extends Fmt00a {
-
-        public Illtrap(int const22) {
-            super(Op2s.Illtrap, const22, g0);
-        }
+    public void jmpl(Register rs1, Register rs2, Register rd) {
+        op3(Jmpl, rs1, rs2, rd);
     }
 
-    public static class Jmpl extends Fmt10 {
-
-        public Jmpl(Register src, int simm13, Register dst) {
-            super(Op3s.Jmpl, src, simm13, dst);
-        }
-
-        public Jmpl(Register src1, Register src2, Register dst) {
-            super(Op3s.Jmpl, src1, src2, dst);
-        }
+    public void jmpl(Register rs1, int simm13, Register rd) {
+        op3(Jmpl, rs1, simm13, rd);
     }
 
-    public static class Lddf extends Fmt11 {
-
-        public Lddf(SPARCAddress src, Register dst) {
-            super(Op3s.Lddf, src, dst);
-            assert dst == f0 || dst == f2 || dst == f4 || dst == f6 || isDoubleFloatRegister(dst);
-        }
-
-        public Lddf(Register src, Register dst) {
-            super(Op3s.Lddf, src, dst);
-            assert dst == f0 || dst == f2 || dst == f4 || dst == f6 || isDoubleFloatRegister(dst);
-        }
+    public void fmovdcc(ConditionFlag cond, CC cc, Register rs2, Register rd) {
+        fmovcc(cond, cc, rs2, rd, Fmovdcc.value);
     }
 
-    public static class Ldf extends Fmt11 {
-
-        public Ldf(SPARCAddress src, Register dst) {
-            super(Op3s.Ldf, src, dst);
-            assert isSingleFloatRegister(dst);
-        }
-
-        public Ldf(Register src, Register dst) {
-            super(Op3s.Ldf, src, dst);
-            assert isSingleFloatRegister(dst);
-        }
+    public void fmovscc(ConditionFlag cond, CC cc, Register rs2, Register rd) {
+        fmovcc(cond, cc, rs2, rd, Fmovscc.value);
     }
 
-    public static class Ldsb extends Fmt11 {
-
-        public Ldsb(SPARCAddress src, Register dst) {
-            super(Op3s.Ldsb, src, dst);
-        }
-    }
-
-    public static class Ldsh extends Fmt11 {
-
-        public Ldsh(SPARCAddress src, Register dst) {
-            super(Op3s.Ldsh, src, dst);
-        }
-    }
-
-    public static class Lduh extends Fmt11 {
-
-        public Lduh(SPARCAddress src, Register dst) {
-            super(Op3s.Lduh, src, dst);
-        }
+    private void fmovcc(ConditionFlag cond, CC cc, Register rs2, Register rd, int opfLow) {
+        int opfCC = cc.value;
+        int a = opfCC << 11 | opfLow << 5 | rs2.encoding;
+        fmt10(rd.encoding, Fpop2.value, cond.value, a);
     }
 
-    public static class Ldub extends Fmt11 {
-
-        public Ldub(SPARCAddress src, Register dst) {
-            super(Op3s.Ldub, src, dst);
-        }
-    }
-
-    public static class Ldsw extends Fmt11 {
-
-        public Ldsw(SPARCAddress src, Register dst) {
-            super(Op3s.Ldsw, src, dst);
-        }
-    }
-
-    public static class Lduw extends Fmt11 {
-
-        public Lduw(SPARCAddress src, Register dst) {
-            super(Op3s.Lduw, src, dst);
-        }
-    }
-
-    public static class Ldx extends Fmt11 {
-
-        public Ldx(SPARCAddress src, Register dst) {
-            super(Op3s.Ldx, src, dst);
-        }
+    public void movcc(ConditionFlag conditionFlag, CC cc, Register rs2, Register rd) {
+        movcc(conditionFlag, cc, 0, rs2.encoding, rd);
     }
 
-    public static class Ldxa extends Fmt11 {
-
-        public Ldxa(Register src1, Register src2, Register dst, Asi asi) {
-            super(Op3s.Ldxa, src1, src2, dst, asi);
-        }
-    }
-
-    public static class Lduwa extends Fmt11 {
-
-        public Lduwa(Register src1, Register src2, Register dst, Asi asi) {
-            super(Op3s.Lduwa, src1, src2, dst, asi);
-        }
-    }
-
-    public static class Membar extends Fmt10 {
-
-        public Membar(int barriers) {
-            super(Op3s.Membar, r15, barriers, r0);
-        }
-    }
-
-    public static class Fmovscc extends Fmt10d {
-
-        public Fmovscc(ConditionFlag cond, CC cca, Register src2, Register dst) {
-            super(Op3s.Fpop2, Opfs.Fmovscc, cond, cca, src2, dst);
-        }
+    public void movcc(ConditionFlag conditionFlag, CC cc, int simm11, Register rd) {
+        assert isSimm11(simm11);
+        movcc(conditionFlag, cc, 1, simm11 & ((1 << 11) - 1), rd);
     }
 
-    public static class Fmovdcc extends Fmt10d {
-
-        public Fmovdcc(ConditionFlag cond, CC cca, Register src2, Register dst) {
-            super(Op3s.Fpop2, Opfs.Fmovdcc, cond, cca, src2, dst);
-        }
+    private void movcc(ConditionFlag conditionFlag, CC cc, int i, int imm, Register rd) {
+        int cc01 = 0b11 & cc.value;
+        int cc2 = cc.isFloat ? 0 : 1;
+        int a = cc2 << 4 | conditionFlag.value;
+        int b = cc01 << 11 | i << 13 | imm;
+        fmt10(rd.encoding, Movcc.value, a, b);
     }
 
-    public static class Movcc extends Fmt10c {
-
-        public Movcc(ConditionFlag cond, CC cca, Register src2, Register dst) {
-            super(Op3s.Movcc, cond, cca, src2, dst);
-        }
-
-        public Movcc(ConditionFlag cond, CC cca, int simm11, Register dst) {
-            super(Op3s.Movcc, cond, cca, simm11, dst);
-        }
-    }
-
-    public static class Movr extends Fmt3f {
-
-        public Movr(SPARCAssembler masm, RCondition rc, Register src1, Register src2, Register dst) {
-            super(masm, Ops.ArithOp.getValue(), Op3s.Movr.getValue(), rc.getValue(), src1.encoding(), src2.encoding(), dst.encoding());
-        }
-
-        public Movr(SPARCAssembler masm, RCondition rc, Register src1, int simm10, Register dst) {
-            super(masm, Ops.ArithOp.getValue(), Op3s.Movr.getValue(), rc.getValue(), src1.encoding(), simm10, dst.encoding());
-        }
+    public void mulx(Register rs1, Register rs2, Register rd) {
+        op3(Mulx, rs1, rs2, rd);
     }
 
-    @Deprecated
-    public static class Mulscc extends Fmt10 {
-
-        @Deprecated
-        public Mulscc(Register src1, int simm13, Register dst) {
-            super(Op3s.Mulscc, src1, simm13, dst);
-        }
-
-        @Deprecated
-        public Mulscc(Register src1, Register src2, Register dst) {
-            super(Op3s.Mulscc, src1, src2, dst);
-        }
-    }
-
-    public static class Mulx extends Fmt10 {
-
-        public Mulx(Register src1, int simm13, Register dst) {
-            super(Op3s.Mulx, src1, simm13, dst);
-        }
-
-        public Mulx(Register src1, Register src2, Register dst) {
-            super(Op3s.Mulx, src1, src2, dst);
-        }
+    public void mulx(Register rs1, int simm13, Register rd) {
+        op3(Mulx, rs1, simm13, rd);
     }
 
-    public static class SMulcc extends Fmt10 {
-
-        public SMulcc(Register src1, int simm13, Register dst) {
-            super(Op3s.Smulcc, src1, simm13, dst);
-        }
-
-        public SMulcc(Register src1, Register src2, Register dst) {
-            super(Op3s.Smulcc, src1, src2, dst);
-        }
+    public void or(Register rs1, Register rs2, Register rd) {
+        op3(Or, rs1, rs2, rd);
     }
 
-    public static class Or extends Fmt10 {
-
-        public Or(Register src1, int simm13, Register dst) {
-            super(Op3s.Or, src1, simm13, dst);
-        }
-
-        public Or(Register src1, Register src2, Register dst) {
-            super(Op3s.Or, src1, src2, dst);
-        }
-    }
-
-    public static class Orcc extends Fmt10 {
-
-        public Orcc(Register src1, int simm13, Register dst) {
-            super(Op3s.Orcc, src1, simm13, dst);
-        }
-
-        public Orcc(Register src1, Register src2, Register dst) {
-            super(Op3s.Orcc, src1, src2, dst);
-        }
+    public void or(Register rs1, int simm13, Register rd) {
+        op3(Or, rs1, simm13, rd);
     }
 
-    public static class Orn extends Fmt10 {
-
-        public Orn(Register src1, int simm13, Register dst) {
-            super(Op3s.Orn, src1, simm13, dst);
-        }
-
-        public Orn(Register src1, Register src2, Register dst) {
-            super(Op3s.Orn, src1, src2, dst);
-        }
+    public void popc(Register rs2, Register rd) {
+        op3(Popc, g0, rs2, rd);
     }
 
-    public static class Orncc extends Fmt10 {
-
-        public Orncc(Register src1, int simm13, Register dst) {
-            super(Op3s.Orncc, src1, simm13, dst);
-        }
-
-        public Orncc(Register src1, Register src2, Register dst) {
-            super(Op3s.Orncc, src1, src2, dst);
-        }
+    public void popc(int simm13, Register rd) {
+        op3(Popc, g0, simm13, rd);
     }
 
-    public static class Popc extends Fmt10 {
-
-        public Popc(int simm13, Register dst) {
-            super(Op3s.Popc, r0, simm13, dst);
-        }
-
-        public Popc(Register src2, Register dst) {
-            super(Op3s.Popc, r0, src2, dst);
-        }
-    }
-
-    public static class Prefetch extends Fmt11 {
-
-        public enum Fcn {
-            SeveralWritesAndPossiblyReads(2),
-            SeveralReadsWeak(0),
-            OneRead(1),
-            OneWrite(3),
-            Page(4),
-            NearestUnifiedCache(17),
-            SeveralReadsStrong(20),
-            OneReadStrong(21),
-            SeveralWritesAndPossiblyReadsStrong(22),
-            OneWriteStrong(23);
-
-            private final int value;
-
-            private Fcn(int value) {
-                this.value = value;
-            }
-
-            public int getValue() {
-                return value;
-            }
-        }
-
-        public Prefetch(SPARCAddress addr, Prefetch.Fcn fcn) {
-            super(Op3s.Prefetch, addr, fcn);
+    public void prefetch(SPARCAddress addr, Fcn fcn) {
+        Register rs1 = addr.getBase();
+        if (addr.getIndex().equals(Register.None)) {
+            int dis = addr.getDisplacement();
+            assert isSimm13(dis);
+            fmt(Prefetch.op.op, fcn.value, Prefetch.value, rs1.encoding, 1 << 13 | dis & ((1 << 13) - 1));
+        } else {
+            Register rs2 = addr.getIndex();
+            fmt(Prefetch.op.op, fcn.value, Prefetch.value, rs1.encoding, rs2.encoding);
         }
     }
 
     // A.44 Read State Register
 
-    @Deprecated
-    public static class Rdy extends Fmt10 {
+    public void rdpc(Register rd) {
+        op3(Rd, r5, g0, rd);
+    }
 
-        public Rdy(Register dst) {
-            super(Op3s.Rdreg, r0, dst);
-        }
+    public void restore(Register rs1, Register rs2, Register rd) {
+        op3(Restore, rs1, rs2, rd);
     }
 
-    public static class Rdccr extends Fmt10 {
+    public static final int PC_RETURN_OFFSET = 8;
 
-        public Rdccr(Register dst) {
-            super(Op3s.Rdreg, r2, dst);
-        }
+    public void save(Register rs1, Register rs2, Register rd) {
+        op3(Save, rs1, rs2, rd);
     }
 
-    public static class Rdasi extends Fmt10 {
-
-        public Rdasi(Register dst) {
-            super(Op3s.Rdreg, r3, dst);
-        }
+    public void save(Register rs1, int simm13, Register rd) {
+        op3(Save, rs1, simm13, rd);
     }
 
-    public static class Rdtick extends Fmt10 {
+    public void sdivx(Register rs1, Register rs2, Register rd) {
+        op3(Sdivx, rs1, rs2, rd);
+    }
 
-        public Rdtick(Register dst) {
-            super(Op3s.Rdreg, r4, dst);
-        }
+    public void sdivx(Register rs1, int simm13, Register rd) {
+        op3(Sdivx, rs1, simm13, rd);
     }
 
-    public static class Rdpc extends Fmt10 {
-
-        public Rdpc(Register dst) {
-            super(Op3s.Rdreg, r5, dst);
-        }
+    public void udivx(Register rs1, Register rs2, Register rd) {
+        op3(Udivx, rs1, rs2, rd);
     }
 
-    public static class Rdfprs extends Fmt10 {
-
-        public Rdfprs(Register dst) {
-            super(Op3s.Rdreg, r6, dst);
-        }
+    public void udivx(Register rs1, int simm13, Register rd) {
+        op3(Udivx, rs1, simm13, rd);
     }
 
-    public static class Restore extends Fmt10 {
-
-        public Restore(Register src1, Register src2, Register dst) {
-            super(Op3s.Restore, src1, src2, dst);
-        }
+    public void sll(Register rs1, Register rs2, Register rd) {
+        op3(Sll, rs1, rs2, rd);
     }
 
-    public static class Restored extends Fmt10 {
-
-        public Restored() {
-            super(Op3s.Saved, r0, r0, r1);
-        }
+    public void sll(Register rs1, int shcnt32, Register rd) {
+        assert isImm(shcnt32, 5);
+        op3(Sll, rs1, shcnt32, rd);
     }
 
-    public static class Return extends Fmt10 {
-
-        public Return(Register src1, int simm13) {
-            super(Op3s.Rett, src1, simm13, r0);
-        }
+    public void sllx(Register rs1, Register rs2, Register rd) {
+        op3(Sllx, rs1, rs2, rd);
+    }
 
-        public Return(Register src1, Register src2) {
-            super(Op3s.Rett, src1, src2, r0);
-        }
+    public void sllx(Register rs1, int shcnt64, Register rd) {
+        assert isImm(shcnt64, 6);
+        op3(Sllx, rs1, shcnt64, rd);
+    }
 
-        public static final int PC_RETURN_OFFSET = 8;
+    public void sra(Register rs1, Register rs2, Register rd) {
+        op3(Sra, rs1, rs2, rd);
     }
 
-    public static class Save extends Fmt10 {
+    public void sra(Register rs1, int simm13, Register rd) {
+        op3(Sra, rs1, simm13, rd);
+    }
 
-        public Save(Register src1, Register src2, Register dst) {
-            super(Op3s.Save, src1, src2, dst);
-        }
-
-        public Save(Register src1, int simm13, Register dst) {
-            super(Op3s.Save, src1, simm13, dst);
-        }
+    public void srax(Register rs1, Register rs2, Register rd) {
+        op3(Srax, rs1, rs2, rd);
     }
 
-    public static class Saved extends Fmt10 {
-
-        public Saved() {
-            super(Op3s.Saved, r0, r0, r0);
-        }
+    public void srax(Register rs1, int shcnt64, Register rd) {
+        assert isImm(shcnt64, 6);
+        op3(Srax, rs1, shcnt64, rd);
     }
 
-    @Deprecated
-    public static class Sdiv extends Fmt10 {
+    public void srl(Register rs1, Register rs2, Register rd) {
+        op3(Srl, rs1, rs2, rd);
+    }
 
-        @Deprecated
-        public Sdiv(Register src1, int simm13, Register dst) {
-            super(Op3s.Sdiv, src1, simm13, dst);
-        }
+    public void srl(Register rs1, int simm13, Register rd) {
+        op3(Srl, rs1, simm13, rd);
+    }
 
-        @Deprecated
-        public Sdiv(Register src1, Register src2, Register dst) {
-            super(Op3s.Sdiv, src1, src2, dst);
-        }
+    public void srlx(Register rs1, Register rs2, Register rd) {
+        op3(Srlx, rs1, rs2, rd);
     }
 
-    @Deprecated
-    public static class Sdivcc extends Fmt10 {
+    public void srlx(Register rs1, int shcnt64, Register rd) {
+        assert isImm(shcnt64, 6);
+        op3(Srlx, rs1, shcnt64, rd);
+    }
 
-        @Deprecated
-        public Sdivcc(Register src1, int simm13, Register dst) {
-            super(Op3s.Sdivcc, src1, simm13, dst);
-        }
+    public void fandd(Register rs1, Register rs2, Register rd) {
+        op3(Impdep1, Fandd, rs1, rs2, rd);
+    }
 
-        @Deprecated
-        public Sdivcc(Register src1, Register src2, Register dst) {
-            super(Op3s.Sdivcc, src1, src2, dst);
-        }
+    public void sub(Register rs1, Register rs2, Register rd) {
+        op3(Sub, rs1, rs2, rd);
+    }
+
+    public void sub(Register rs1, int simm13, Register rd) {
+        op3(Sub, rs1, simm13, rd);
     }
 
-    public static class Sdivx extends Fmt10 {
+    public void subcc(Register rs1, Register rs2, Register rd) {
+        op3(Subcc, rs1, rs2, rd);
+    }
 
-        public Sdivx(Register src1, int simm13, Register dst) {
-            super(Op3s.Sdivx, src1, simm13, dst);
-        }
-
-        public Sdivx(Register src1, Register src2, Register dst) {
-            super(Op3s.Sdivx, src1, src2, dst);
-        }
+    public void subcc(Register rs1, int simm13, Register rd) {
+        op3(Subcc, rs1, simm13, rd);
     }
 
-    public static class Sethi extends Fmt00a {
-
-        public Sethi(int imm22, Register dst) {
-            super(Op2s.Sethi, imm22, dst);
-        }
+    public void ta(int trap) {
+        tcc(Icc, Always, trap);
     }
 
-    public static class Sir extends Fmt10 {
-
-        public Sir(int simm13) {
-            super(Op3s.Sir, r0, simm13, r15);
-        }
+    public void tcc(CC cc, ConditionFlag flag, int trap) {
+        assert isImm(trap, 8);
+        int b = cc.value << 11;
+        b |= trap;
+        fmt10(flag.value, trap, 0, b);
     }
 
-    public static class Sll extends Fmt10 {
-
-        public Sll(Register src1, int shcnt32, Register dst) {
-            super(Op3s.Sll, src1, shcnt32, dst);
-        }
-
-        public Sll(Register src1, Register src2, Register dst) {
-            super(Op3s.Sll, src1, src2, dst);
-        }
+    public void wrccr(Register rs1, Register rs2) {
+        op3(Wr, rs1, rs2, r2);
     }
 
-    public static class Sllx extends Fmt10 {
+    public void wrccr(Register rs1, int simm13) {
+        op3(Wr, rs1, simm13, r2);
+    }
 
-        public Sllx(Register src1, int shcnt64, Register dst) {
-            super(Op3s.Sllx, src1, shcnt64, dst);
-        }
-
-        public Sllx(Register src1, Register src2, Register dst) {
-            super(Op3s.Sllx, src1, src2, dst);
-        }
+    public void xor(Register rs1, Register rs2, Register rd) {
+        op3(Xor, rs1, rs2, rd);
     }
 
-    public static class Sra extends Fmt10 {
-
-        public Sra(Register src1, int shcnt32, Register dst) {
-            super(Op3s.Sra, src1, shcnt32, dst);
-        }
-
-        public Sra(Register src1, Register src2, Register dst) {
-            super(Op3s.Sra, src1, src2, dst);
-        }
+    public void xor(Register rs1, int simm13, Register rd) {
+        op3(Xor, rs1, simm13, rd);
     }
 
-    public static class Srax extends Fmt10 {
+    public void xorcc(Register rs1, Register rs2, Register rd) {
+        op3(Xorcc, rs1, rs2, rd);
+    }
 
-        public Srax(Register src1, int shcnt64, Register dst) {
-            super(Op3s.Srax, src1, shcnt64, dst);
-        }
-
-        public Srax(Register src1, Register src2, Register dst) {
-            super(Op3s.Srax, src1, src2, dst);
-        }
+    public void xorcc(Register rs1, int simm13, Register rd) {
+        op3(Xorcc, rs1, simm13, rd);
     }
 
-    public static class Srl extends Fmt10 {
+    public void xnor(Register rs1, Register rs2, Register rd) {
+        op3(Xnor, rs1, rs2, rd);
+    }
 
-        public Srl(Register src1, int shcnt32, Register dst) {
-            super(Op3s.Srl, src1, shcnt32, dst);
-        }
-
-        public Srl(Register src1, Register src2, Register dst) {
-            super(Op3s.Srl, src1, src2, dst);
-        }
+    public void xnor(Register rs1, int simm13, Register rd) {
+        op3(Xnor, rs1, simm13, rd);
     }
 
-    public static class Srlx extends Fmt10 {
-
-        public Srlx(Register src1, int shcnt64, Register dst) {
-            super(Op3s.Srlx, src1, shcnt64, dst);
-        }
-
-        public Srlx(Register src1, Register src2, Register dst) {
-            super(Op3s.Srlx, src1, src2, dst);
-        }
-    }
-
-    public static class Fandd extends Fmt3p {
-        public Fandd(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fandd, src1, src2, dst);
-        }
-    }
-
-    public static class Fxord extends Fmt3p {
-        public Fxord(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fxord, src1, src2, dst);
-        }
-    }
-
-    public static class Fxors extends Fmt3p {
-        public Fxors(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fxors, src1, src2, dst);
+    /*
+     * Load/Store
+     */
+    protected void ld(Op3s op3, SPARCAddress addr, Register rd, Asi asi) {
+        Register rs1 = addr.getBase();
+        if (!addr.getIndex().equals(Register.None)) {
+            Register rs2 = addr.getIndex();
+            if (asi != null) {
+                int b = rs2.encoding;
+                b |= asi.value << 5;
+                fmt(op3.op.op, rd.encoding, op3.value, rs1.encoding, b);
+            } else {
+                op3(op3, rs1, rs2, rd);
+            }
+        } else {
+            int imm = addr.getDisplacement();
+            op3(op3, rs1, imm, rd);
         }
     }
 
-    public static class Fands extends Fmt3p {
-        public Fands(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Fands, src1, src2, dst);
-        }
+    protected void ld(Op3s op3, SPARCAddress addr, Register rd) {
+        ld(op3, addr, rd, null);
     }
 
-    public static class Stb extends Fmt11 {
-
-        public Stb(Register dst, SPARCAddress addr) {
-            super(Op3s.Stb, addr, dst);
-        }
-    }
-
-    public static class Stdf extends Fmt11 {
-
-        public Stdf(Register dst, SPARCAddress src) {
-            super(Op3s.Stdf, src, dst);
-        }
+    public void lddf(SPARCAddress src, Register dst) {
+        ld(Lddf, src, dst);
     }
 
-    public static class Stf extends Fmt11 {
-
-        public Stf(Register dst, SPARCAddress src) {
-            super(Op3s.Stf, src, dst);
-        }
+    public void ldf(SPARCAddress src, Register dst) {
+        ld(Ldf, src, dst);
     }
 
-    public static class Sth extends Fmt11 {
-
-        public Sth(Register dst, SPARCAddress addr) {
-            super(Op3s.Sth, addr, dst);
-        }
+    public void lduh(SPARCAddress src, Register dst) {
+        ld(Lduh, src, dst);
     }
 
-    public static class Stw extends Fmt11 {
-
-        public Stw(Register dst, SPARCAddress addr) {
-            super(Op3s.Stw, addr, dst);
-        }
-    }
-
-    public static class Stx extends Fmt11 {
-
-        public Stx(Register dst, SPARCAddress addr) {
-            super(Op3s.Stx, addr, dst);
-        }
+    public void ldsh(SPARCAddress src, Register dst) {
+        ld(Ldsh, src, dst);
     }
 
-    public static class Sub extends Fmt10 {
-
-        public Sub(Register src1, int simm13, Register dst) {
-            super(Op3s.Sub, src1, simm13, dst);
-        }
-
-        public Sub(Register src1, Register src2, Register dst) {
-            super(Op3s.Sub, src1, src2, dst);
-        }
+    public void ldub(SPARCAddress src, Register dst) {
+        ld(Ldub, src, dst);
     }
 
-    public static class Subc extends Fmt10 {
-
-        public Subc(Register src1, int simm13, Register dst) {
-            super(Op3s.Subc, src1, simm13, dst);
-        }
-
-        public Subc(Register src1, Register src2, Register dst) {
-            super(Op3s.Subc, src1, src2, dst);
-        }
+    public void ldsb(SPARCAddress src, Register dst) {
+        ld(Ldsb, src, dst);
     }
 
-    public static class Subcc extends Fmt10 {
-
-        public Subcc(Register src1, int simm13, Register dst) {
-            super(Op3s.Subcc, src1, simm13, dst);
-        }
-
-        public Subcc(Register src1, Register src2, Register dst) {
-            super(Op3s.Subcc, src1, src2, dst);
-        }
+    public void lduw(SPARCAddress src, Register dst) {
+        ld(Lduw, src, dst);
     }
 
-    public static class Subccc extends Fmt10 {
-
-        public Subccc(Register src1, int simm13, Register dst) {
-            super(Op3s.Subccc, src1, simm13, dst);
-        }
-
-        public Subccc(Register src1, Register src2, Register dst) {
-            super(Op3s.Subccc, src1, src2, dst);
-        }
+    public void ldsw(SPARCAddress src, Register dst) {
+        ld(Ldsw, src, dst);
     }
 
-    public static class Ta extends Fmt10 {
-
-        public Ta(int trap) {
-            super(Op3s.Trap, g0, trap, ConditionFlag.Always);
-        }
+    public void ldx(SPARCAddress src, Register dst) {
+        ld(Ldx, src, dst);
     }
 
-    public static class Tcc extends Fmt10 {
-
-        public Tcc(ConditionFlag flag, int trap) {
-            super(Op3s.Trap, g0, trap, flag);
-        }
+    public void ldxa(Register rs1, Register rs2, Register rd, Asi asi) {
+        ld(Ldxa, new SPARCAddress(rs1, rs2), rd, asi);
     }
 
-    public static class Taddcc extends Fmt10 {
-
-        public Taddcc(Register src1, int simm13, Register dst) {
-            super(Op3s.Taddcc, src1, simm13, dst);
-        }
-
-        public Taddcc(Register src1, Register src2, Register dst) {
-            super(Op3s.Taddcc, src1, src2, dst);
-        }
+    public void lduwa(Register rs1, Register rs2, Register rd, Asi asi) {
+        ld(Lduwa, new SPARCAddress(rs1, rs2), rd, asi);
     }
 
-    public static class Tsubcc extends Fmt10 {
-
-        public Tsubcc(Register src1, int simm13, Register dst) {
-            super(Op3s.Tsubcc, src1, simm13, dst);
-        }
-
-        public Tsubcc(Register src1, Register src2, Register dst) {
-            super(Op3s.Tsubcc, src1, src2, dst);
-        }
+    protected void st(Op3s op3, Register rs1, SPARCAddress dest) {
+        ld(op3, dest, rs1);
     }
 
-    public static class Udivx extends Fmt10 {
-
-        public Udivx(Register src1, int simm13, Register dst) {
-            super(Op3s.Udivx, src1, simm13, dst);
-        }
-
-        public Udivx(Register src1, Register src2, Register dst) {
-            super(Op3s.Udivx, src1, src2, dst);
-        }
+    public void stdf(Register rd, SPARCAddress addr) {
+        st(Stdf, rd, addr);
     }
 
-    @Deprecated
-    public static class Wry extends Fmt10 {
-
-        @Deprecated
-        public Wry(Register src1, int simm13) {
-            super(Op3s.Wrreg, src1, simm13, r0);
-        }
-
-        @Deprecated
-        public Wry(Register src1, Register src2) {
-            super(Op3s.Wrreg, src1, src2, r0);
-        }
+    public void stf(Register rd, SPARCAddress addr) {
+        st(Stf, rd, addr);
     }
 
-    public static class Wrccr extends Fmt10 {
-
-        public Wrccr(Register src1, int simm13) {
-            super(Op3s.Wrreg, src1, simm13, r2);
-        }
-
-        public Wrccr(Register src1, Register src2) {
-            super(Op3s.Wrreg, src1, src2, r2);
-        }
+    public void stb(Register rd, SPARCAddress addr) {
+        st(Stb, rd, addr);
     }
 
-    public static class Wrasi extends Fmt10 {
-
-        public Wrasi(Register src1, int simm13) {
-            super(Op3s.Wrreg, src1, simm13, r3);
-        }
-
-        public Wrasi(Register src1, Register src2) {
-            super(Op3s.Wrreg, src1, src2, r3);
-        }
+    public void sth(Register rd, SPARCAddress addr) {
+        st(Sth, rd, addr);
     }
 
-    public static class Wrfprs extends Fmt10 {
-
-        public Wrfprs(Register src1, int simm13) {
-            super(Op3s.Wrreg, src1, simm13, r6);
-        }
-
-        public Wrfprs(Register src1, Register src2) {
-            super(Op3s.Wrreg, src1, src2, r6);
-        }
+    public void stw(Register rd, SPARCAddress addr) {
+        st(Stw, rd, addr);
     }
 
-    public static class Xor extends Fmt10 {
-
-        public Xor(Register src1, int simm13, Register dst) {
-            super(Op3s.Xor, src1, simm13, dst);
-        }
-
-        public Xor(Register src1, Register src2, Register dst) {
-            super(Op3s.Xor, src1, src2, dst);
-        }
+    public void stx(Register rd, SPARCAddress addr) {
+        st(Stx, rd, addr);
     }
 
-    public static class Xorcc extends Fmt10 {
-
-        public Xorcc(Register src1, int simm13, Register dst) {
-            super(Op3s.Xorcc, src1, simm13, dst);
-        }
-
-        public Xorcc(Register src1, Register src2, Register dst) {
-            super(Op3s.Xorcc, src1, src2, dst);
-        }
+    public void membar(int barriers) {
+        op3(Membar, r15, barriers, g0);
     }
 
-    public static class Xnor extends Fmt10 {
-
-        public Xnor(Register src1, int simm13, Register dst) {
-            super(Op3s.Xnor, src1, simm13, dst);
-        }
-
-        public Xnor(Register src1, Register src2, Register dst) {
-            super(Op3s.Xnor, src1, src2, dst);
-        }
+    public void casa(Register rs1, Register rs2, Register rd, Asi asi) {
+        ld(Casa, new SPARCAddress(rs1, rs2), rd, asi);
     }
 
-    public static class Xnorcc extends Fmt10 {
-
-        public Xnorcc(Register src1, int simm13, Register dst) {
-            super(Op3s.Xnorcc, src1, simm13, dst);
-        }
-
-        public Xnorcc(Register src1, Register src2, Register dst) {
-            super(Op3s.Xnorcc, src1, src2, dst);
-        }
+    public void casxa(Register rs1, Register rs2, Register rd, Asi asi) {
+        ld(Casxa, new SPARCAddress(rs1, rs2), rd, asi);
     }
 }
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Tue Mar 03 17:13:51 2015 -0800
@@ -22,10 +22,15 @@
  */
 package com.oracle.graal.asm.sparc;
 
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*;
 import static com.oracle.graal.sparc.SPARC.*;
 
+import java.util.function.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.asm.*;
+import com.oracle.graal.compiler.common.*;
 
 public class SPARCMacroAssembler extends SPARCAssembler {
 
@@ -42,22 +47,64 @@
     @Override
     public void align(int modulus) {
         while (position() % modulus != 0) {
-            new Nop().emit(this);
+            nop();
         }
     }
 
     @Override
     public void jmp(Label l) {
-        new Bpa(l).emit(this);
-        new Nop().emit(this);  // delay slot
+        bicc(Always, NOT_ANNUL, l);
+        nop();  // delay slot
     }
 
     @Override
     protected final void patchJumpTarget(int branch, int branchTarget) {
-        final int disp = branchTarget - branch;
-        Fmt00 fmt = Fmt00.read(this, branch);
-        fmt.setImm(disp);
-        fmt.write(this, branch);
+        final int disp = (branchTarget - branch) / 4;
+        final int inst = getInt(branch);
+        Op2s op2 = Op2s.byValue((inst & OP2_MASK) >> OP2_SHIFT);
+        int maskBits;
+        int setBits;
+        switch (op2) {
+            case Br:
+            case Fb:
+            case Sethi:
+            case Illtrap:
+                // Disp 22 in the lower 22 bits
+                assert isSimm(disp, 22);
+                setBits = disp << DISP22_SHIFT;
+                maskBits = DISP22_MASK;
+                break;
+            case Fbp:
+            case Bp:
+                // Disp 19 in the lower 19 bits
+                assert isSimm(disp, 19);
+                setBits = disp << DISP19_SHIFT;
+                maskBits = DISP19_MASK;
+                break;
+            case Bpr:
+                boolean isCBcond = (inst & CBCOND_MASK) != 0;
+                if (isCBcond) {
+                    assert isSimm10(disp);
+                    int d10Split = 0;
+                    d10Split |= (disp & 0b11_0000_0000) << D10HI_SHIFT - 8;
+                    d10Split |= (disp & 0b00_1111_1111) << D10LO_SHIFT;
+                    setBits = d10Split;
+                    maskBits = D10LO_MASK | D10HI_MASK;
+                } else {
+                    assert isSimm(disp, 16);
+                    int d16Split = 0;
+                    d16Split |= (disp & 0b1100_0000_0000_0000) << D16HI_SHIFT - 14;
+                    d16Split |= (disp & 0b0011_1111_1111_1111) << D16LO_SHIFT;
+                    setBits = d16Split;
+                    maskBits = D16HI_MASK | D16LO_MASK;
+                }
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere("Unknown op2 " + op2);
+        }
+        int newInst = ~maskBits & inst;
+        newInst |= setBits;
+        emitInt(newInst, branch);
     }
 
     @Override
@@ -72,278 +119,87 @@
 
     @Override
     public final void ensureUniquePC() {
-        new Nop().emit(this);
+        nop();
     }
 
-    public static class Bclr extends Andn {
-
-        public Bclr(Register src, Register dst) {
-            super(dst, src, dst);
-        }
-
-        public Bclr(int simm13, Register dst) {
-            super(dst, simm13, dst);
-        }
+    public void cas(Register rs1, Register rs2, Register rd) {
+        casa(rs1, rs2, rd, Asi.ASI_PRIMARY);
     }
 
-    public static class Bpgeu extends Bpcc {
-
-        public Bpgeu(CC cc, int simm19) {
-            super(cc, simm19);
-        }
-
-        public Bpgeu(CC cc, Label label) {
-            super(cc, label);
-        }
-
-        public Bpgeu(CC cc, boolean annul, boolean predictTaken, Label label) {
-            super(cc, annul, predictTaken, label);
-        }
+    public void casx(Register rs1, Register rs2, Register rd) {
+        casxa(rs1, rs2, rd, Asi.ASI_PRIMARY);
     }
 
-    public static class Bplu extends Bpcs {
-
-        public Bplu(CC cc, int simm19) {
-            super(cc, simm19);
-        }
-
-        public Bplu(CC cc, Label label) {
-            super(cc, label);
-        }
-
-        public Bplu(CC cc, boolean annul, boolean predictTaken, Label label) {
-            super(cc, annul, predictTaken, label);
-        }
+    public void clr(Register dst) {
+        or(g0, g0, dst);
     }
 
-    public static class Bset extends Or {
-
-        public Bset(Register src, Register dst) {
-            super(dst, src, dst);
-        }
-
-        public Bset(int simm13, Register dst) {
-            super(dst, simm13, dst);
-        }
+    public void clrb(SPARCAddress addr) {
+        stb(g0, addr);
     }
 
-    public static class Btst extends Andcc {
-
-        public Btst(Register src1, Register src2) {
-            super(src1, src2, g0);
-        }
-
-        public Btst(Register src1, int simm13) {
-            super(src1, simm13, g0);
-        }
+    public void clrh(SPARCAddress addr) {
+        sth(g0, addr);
     }
 
-    public static class Cas extends Casa {
-
-        public Cas(Register src1, Register src2, Register dst) {
-            super(src1, src2, dst, Asi.ASI_PRIMARY);
-        }
-    }
-
-    public static class Casx extends Casxa {
-
-        public Casx(Register src1, Register src2, Register dst) {
-            super(src1, src2, dst, Asi.ASI_PRIMARY);
-        }
-    }
-
-    public static class Clr extends Or {
-
-        public Clr(Register dst) {
-            super(g0, g0, dst);
-        }
+    public void clrx(SPARCAddress addr) {
+        stx(g0, addr);
     }
 
-    public static class Clrb extends Stb {
-
-        public Clrb(SPARCAddress addr) {
-            super(g0, addr);
-        }
-    }
-
-    public static class Clrh extends Sth {
-
-        public Clrh(SPARCAddress addr) {
-            super(g0, addr);
-        }
-    }
-
-    public static class Clrx extends Stx {
-
-        public Clrx(SPARCAddress addr) {
-            super(g0, addr);
-        }
+    public void cmp(Register rs1, Register rs2) {
+        subcc(rs1, rs2, g0);
     }
 
-    public static class Clruw extends Srl {
-
-        public Clruw(Register src1, Register dst) {
-            super(src1, g0, dst);
-            assert src1.encoding() != dst.encoding();
-        }
-
-        public Clruw(Register dst) {
-            super(dst, g0, dst);
-        }
+    public void cmp(Register rs1, int simm13) {
+        subcc(rs1, simm13, g0);
     }
 
-    public static class Cmp extends Subcc {
-
-        public Cmp(Register a, Register b) {
-            super(a, b, g0);
-        }
-
-        public Cmp(Register a, int simm13) {
-            super(a, simm13, g0);
-        }
+    public void dec(Register rd) {
+        sub(rd, 1, rd);
     }
 
-    public static class Dec extends Sub {
-
-        public Dec(Register dst) {
-            super(dst, 1, dst);
-        }
-
-        public Dec(int simm13, Register dst) {
-            super(dst, simm13, dst);
-        }
+    public void dec(int simm13, Register rd) {
+        sub(rd, simm13, rd);
     }
 
-    public static class Deccc extends Subcc {
-
-        public Deccc(Register dst) {
-            super(dst, 1, dst);
-        }
-
-        public Deccc(int simm13, Register dst) {
-            super(dst, simm13, dst);
-        }
+    public void jmp(SPARCAddress address) {
+        jmpl(address.getBase(), address.getDisplacement(), g0);
     }
 
-    @SuppressWarnings("unused")
-    public static class Inc {
-
-        public Inc(Register dst) {
-            new Add(dst, 1, dst);
-        }
-
-        public Inc(int simm13, Register dst) {
-            new Add(dst, simm13, dst);
-        }
+    public void jmp(Register rd) {
+        jmpl(rd, 0, g0);
     }
 
-    @SuppressWarnings("unused")
-    public static class Inccc {
-
-        public Inccc(Register dst) {
-            new Addcc(dst, 1, dst);
-        }
-
-        public Inccc(int simm13, Register dst) {
-            new Addcc(dst, simm13, dst);
-        }
+    public void neg(Register rs1, Register rd) {
+        sub(g0, rs1, rd);
     }
 
-    public static class Jmp extends Jmpl {
-
-        public Jmp(SPARCAddress address) {
-            super(address.getBase(), address.getDisplacement(), g0);
-        }
-
-        public Jmp(Register reg) {
-            super(reg, 0, g0);
-        }
-    }
-
-    public static class Neg extends Sub {
-
-        public Neg(Register src2, Register dst) {
-            super(g0, src2, dst);
-        }
-
-        public Neg(Register dst) {
-            super(g0, dst, dst);
-        }
+    public void neg(Register rd) {
+        sub(g0, rd, rd);
     }
 
-    public static class Mov extends Or {
-
-        public Mov(Register src1, Register dst) {
-            super(g0, src1, dst);
-            assert src1.encoding() != dst.encoding();
-        }
-
-        public Mov(int simm13, Register dst) {
-            super(g0, simm13, dst);
-        }
+    public void mov(Register rs, Register rd) {
+        or(g0, rs, rd);
     }
 
-    public static class Nop extends Sethi {
-
-        public Nop() {
-            super(0, r0);
-        }
-    }
-
-    public static class Not extends Xnor {
-
-        public Not(Register src1, Register dst) {
-            super(src1, g0, dst);
-        }
-
-        public Not(Register dst) {
-            super(dst, g0, dst);
-        }
-    }
-
-    public static class RestoreWindow extends Restore {
-
-        public RestoreWindow() {
-            super(g0, g0, g0);
-        }
+    public void mov(int simm13, Register rd) {
+        or(g0, simm13, rd);
     }
 
-    public static class Ret extends Jmpl {
-
-        public Ret() {
-            super(i7, 8, g0);
-        }
-    }
-
-    public static class SaveWindow extends Save {
-
-        public SaveWindow() {
-            super(g0, g0, g0);
-        }
+    public void not(Register rs1, Register rd) {
+        xnor(rs1, g0, rd);
     }
 
-    public static class Setuw {
-
-        private int value;
-        private Register dst;
-
-        public Setuw(int value, Register dst) {
-            this.value = value;
-            this.dst = dst;
-        }
+    public void not(Register rd) {
+        xnor(rd, g0, rd);
+    }
 
-        public void emit(SPARCMacroAssembler masm) {
-            if (value == 0) {
-                new Clr(dst).emit(masm);
-            } else if (isSimm13(value)) {
-                new Or(g0, value, dst).emit(masm);
-            } else if (value >= 0 && ((value & 0x3FFF) == 0)) {
-                new Sethi(hi22(value), dst).emit(masm);
-            } else {
-                new Sethi(hi22(value), dst).emit(masm);
-                new Or(dst, lo10(value), dst).emit(masm);
-            }
-        }
+    public void restoreWindow() {
+        restore(g0, g0, g0);
+    }
+
+    public void ret() {
+        jmpl(i7, 8, g0);
     }
 
     /**
@@ -357,7 +213,7 @@
         private Register dst;
         private boolean forceRelocatable;
         private boolean delayed = false;
-        private AssemblerEmittable delayedInstruction;
+        private Consumer<SPARCAssembler> delayedInstructionEmitter;
 
         public Sethix(long value, Register dst, boolean forceRelocatable, boolean delayed) {
             this(value, dst, forceRelocatable);
@@ -375,72 +231,85 @@
             this(value, dst, false);
         }
 
-        private void emitInstruction(AssemblerEmittable insn, SPARCMacroAssembler masm) {
+        private void emitInstruction(Consumer<SPARCAssembler> cb, SPARCMacroAssembler masm) {
             if (delayed) {
-                if (this.delayedInstruction != null) {
-                    delayedInstruction.emit(masm);
+                if (this.delayedInstructionEmitter != null) {
+                    delayedInstructionEmitter.accept(masm);
                 }
-                delayedInstruction = insn;
+                delayedInstructionEmitter = cb;
             } else {
-                insn.emit(masm);
+                cb.accept(masm);
             }
         }
 
         public void emit(SPARCMacroAssembler masm) {
-            int hi = (int) (value >> 32);
-            int lo = (int) (value & ~0);
+            final int hi = (int) (value >> 32);
+            final int lo = (int) (value & ~0);
 
             // This is the same logic as MacroAssembler::internal_set.
             final int startPc = masm.position();
 
             if (hi == 0 && lo >= 0) {
-                emitInstruction(new Sethi(hi22(lo), dst), masm);
+                Consumer<SPARCAssembler> cb = eMasm -> eMasm.sethi(hi22(lo), dst);
+                emitInstruction(cb, masm);
             } else if (hi == -1) {
-                emitInstruction(new Sethi(hi22(~lo), dst), masm);
-                emitInstruction(new Xor(dst, ~lo10(~0), dst), masm);
+                Consumer<SPARCAssembler> cb = eMasm -> eMasm.sethi(hi22(~lo), dst);
+                emitInstruction(cb, masm);
+                cb = eMasm -> eMasm.xor(dst, ~lo10(~0), dst);
+                emitInstruction(cb, masm);
             } else {
-                int shiftcnt = 0;
-                emitInstruction(new Sethi(hi22(hi), dst), masm);
+                final int shiftcnt;
+                final int shiftcnt2;
+                Consumer<SPARCAssembler> cb = eMasm -> eMasm.sethi(hi22(hi), dst);
+                emitInstruction(cb, masm);
                 if ((hi & 0x3ff) != 0) {                                  // Any bits?
                     // msb 32-bits are now in lsb 32
-                    emitInstruction(new Or(dst, hi & 0x3ff, dst), masm);
+                    cb = eMasm -> eMasm.or(dst, hi & 0x3ff, dst);
+                    emitInstruction(cb, masm);
                 }
                 if ((lo & 0xFFFFFC00) != 0) {                             // done?
                     if (((lo >> 20) & 0xfff) != 0) {                      // Any bits set?
                         // Make room for next 12 bits
-                        emitInstruction(new Sllx(dst, 12, dst), masm);
+                        cb = eMasm -> eMasm.sllx(dst, 12, dst);
+                        emitInstruction(cb, masm);
                         // Or in next 12
-                        emitInstruction(new Or(dst, (lo >> 20) & 0xfff, dst), masm);
+                        cb = eMasm -> eMasm.or(dst, (lo >> 20) & 0xfff, dst);
+                        emitInstruction(cb, masm);
                         shiftcnt = 0;                                     // We already shifted
                     } else {
                         shiftcnt = 12;
                     }
                     if (((lo >> 10) & 0x3ff) != 0) {
                         // Make room for last 10 bits
-                        emitInstruction(new Sllx(dst, shiftcnt + 10, dst), masm);
+                        cb = eMasm -> eMasm.sllx(dst, shiftcnt + 10, dst);
+                        emitInstruction(cb, masm);
                         // Or in next 10
-                        emitInstruction(new Or(dst, (lo >> 10) & 0x3ff, dst), masm);
-                        shiftcnt = 0;
+                        cb = eMasm -> eMasm.or(dst, (lo >> 10) & 0x3ff, dst);
+                        emitInstruction(cb, masm);
+                        shiftcnt2 = 0;
                     } else {
-                        shiftcnt = 10;
+                        shiftcnt2 = 10;
                     }
                     // Shift leaving disp field 0'd
-                    emitInstruction(new Sllx(dst, shiftcnt + 10, dst), masm);
+                    cb = eMasm -> eMasm.sllx(dst, shiftcnt2 + 10, dst);
+                    emitInstruction(cb, masm);
                 } else {
-                    emitInstruction(new Sllx(dst, 32, dst), masm);
+                    cb = eMasm -> eMasm.sllx(dst, 32, dst);
+                    emitInstruction(cb, masm);
                 }
             }
             // Pad out the instruction sequence so it can be patched later.
             if (forceRelocatable) {
                 while (masm.position() < (startPc + (INSTRUCTION_SIZE * 4))) {
-                    emitInstruction(new Nop(), masm);
+                    Consumer<SPARCAssembler> cb = eMasm -> eMasm.nop();
+                    emitInstruction(cb, masm);
                 }
             }
         }
 
         public void emitDelayed(SPARCMacroAssembler masm) {
-            assert delayedInstruction != null;
-            delayedInstruction.emit(masm);
+            assert delayedInstructionEmitter != null;
+            delayedInstructionEmitter.accept(masm);
         }
     }
 
@@ -452,7 +321,7 @@
         private boolean delayed = false;
         private boolean delayedFirstEmitted = false;
         private Sethix sethix;
-        private AssemblerEmittable delayedAdd;
+        private Consumer<SPARCMacroAssembler> delayedAdd;
 
         public Setx(long value, Register dst, boolean forceRelocatable, boolean delayed) {
             assert !(forceRelocatable && delayed) : "Cannot use relocatable setx as delayable";
@@ -480,14 +349,14 @@
             sethix.emit(masm);
             int lo = (int) (value & ~0);
             if (lo10(lo) != 0 || forceRelocatable) {
-                Add add = new Add(dst, lo10(lo), dst);
+                Consumer<SPARCMacroAssembler> add = eMasm -> eMasm.add(dst, lo10(lo), dst);
                 if (delayed) {
                     sethix.emitDelayed(masm);
                     sethix = null;
                     delayedAdd = add;
                 } else {
                     sethix = null;
-                    add.emit(masm);
+                    add.accept(masm);
                 }
             }
         }
@@ -505,7 +374,7 @@
             assert delayedFirstEmitted : "First part has not been emitted so far.";
             assert delayedAdd == null && sethix != null || delayedAdd != null && sethix == null : "Either add or sethix must be set";
             if (delayedAdd != null) {
-                delayedAdd.emit(masm);
+                delayedAdd.accept(masm);
             } else {
                 sethix.emitDelayed(masm);
             }
@@ -513,14 +382,11 @@
         }
     }
 
-    public static class Signx extends Sra {
+    public void signx(Register rs, Register rd) {
+        sra(rs, g0, rd);
+    }
 
-        public Signx(Register src1, Register dst) {
-            super(src1, g0, dst);
-        }
-
-        public Signx(Register dst) {
-            super(dst, g0, dst);
-        }
+    public void signx(Register rd) {
+        sra(rd, g0, rd);
     }
 }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlockBase.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlockBase.java	Tue Mar 03 17:13:51 2015 -0800
@@ -34,6 +34,8 @@
 
     private T dominator;
     private List<T> dominated;
+    private int domNumber;
+    private int maxChildDomNumber;
 
     private boolean align;
     private int linearScanNumber;
@@ -43,6 +45,19 @@
         this.linearScanNumber = -1;
     }
 
+    public void setDominatorNumbers(int domNumber, int maxChildDomNumber) {
+        this.domNumber = domNumber;
+        this.maxChildDomNumber = maxChildDomNumber;
+    }
+
+    public int getDominatorNumber() {
+        return domNumber;
+    }
+
+    public int getMaxChildDominatorNumber() {
+        return this.maxChildDomNumber;
+    }
+
     public int getId() {
         return id;
     }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractControlFlowGraph.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractControlFlowGraph.java	Tue Mar 03 17:13:51 2015 -0800
@@ -46,6 +46,7 @@
     /**
      * Computes the dominators of control flow graph.
      */
+    @SuppressWarnings("unchecked")
     static <T extends AbstractBlockBase<T>> void computeDominators(AbstractControlFlowGraph<T> cfg) {
         List<T> reversePostOrder = cfg.getBlocks();
         assert reversePostOrder.get(0).getPredecessorCount() == 0 : "start block has no predecessor and therefore no dominator";
@@ -55,7 +56,7 @@
             T dominator = null;
             for (T pred : block.getPredecessors()) {
                 if (!pred.isLoopEnd()) {
-                    dominator = commonDominatorTyped(dominator, pred);
+                    dominator = (T) ((dominator == null) ? pred : commonDominatorRaw(dominator, pred));
                 }
             }
             // set dominator
@@ -65,21 +66,26 @@
             }
             dominator.getDominated().add(block);
         }
+        calcDominatorRanges(cfg.getStartBlock(), 0);
+    }
+
+    static <T extends AbstractBlockBase<T>> int calcDominatorRanges(T block, int next) {
+        int myNumber = next;
+        int maxNumber = myNumber;
+        for (T dominated : block.getDominated()) {
+            maxNumber = calcDominatorRanges(dominated, maxNumber + 1);
+        }
+        block.setDominatorNumbers(myNumber, maxNumber);
+        return maxNumber;
     }
 
     /**
      * True if block {@code a} is dominated by block {@code b}.
      */
     static boolean isDominatedBy(AbstractBlockBase<?> a, AbstractBlockBase<?> b) {
-        assert a != null && b != null;
-        if (a == b) {
-            return true;
-        }
-        if (a.getDominatorDepth() < b.getDominatorDepth()) {
-            return false;
-        }
-
-        return b == (AbstractBlockBase<?>) a.getDominator(a.getDominatorDepth() - b.getDominatorDepth());
+        int domNumberA = a.getDominatorNumber();
+        int domNumberB = b.getDominatorNumber();
+        return domNumberA >= domNumberB && domNumberA <= b.getMaxChildDominatorNumber();
     }
 
     /**
@@ -101,21 +107,49 @@
     static AbstractBlockBase<?> commonDominator(AbstractBlockBase<?> a, AbstractBlockBase<?> b) {
         if (a == null) {
             return b;
-        }
-        if (b == null) {
+        } else if (b == null) {
             return a;
+        } else {
+            int aDomDepth = a.getDominatorDepth();
+            int bDomDepth = b.getDominatorDepth();
+            AbstractBlockBase<?> aTemp;
+            AbstractBlockBase<?> bTemp;
+            if (aDomDepth > bDomDepth) {
+                aTemp = a;
+                bTemp = b;
+            } else {
+                aTemp = b;
+                bTemp = a;
+            }
+            return commonDominatorHelper(aTemp, bTemp);
         }
+    }
 
-        AbstractBlockBase<?> iterA = a;
-        AbstractBlockBase<?> iterB = b;
+    static AbstractBlockBase<?> commonDominatorHelper(AbstractBlockBase<?> a, AbstractBlockBase<?> b) {
+        int domNumberA = a.getDominatorNumber();
+        AbstractBlockBase<?> result = b;
+        while (domNumberA < result.getDominatorNumber()) {
+            result = result.getDominator();
+        }
+        while (domNumberA > result.getMaxChildDominatorNumber()) {
+            result = result.getDominator();
+        }
+        return result;
+    }
+
+    static AbstractBlockBase<?> commonDominatorRaw(AbstractBlockBase<?> a, AbstractBlockBase<?> b) {
         int aDomDepth = a.getDominatorDepth();
         int bDomDepth = b.getDominatorDepth();
         if (aDomDepth > bDomDepth) {
-            iterA = a.getDominator(aDomDepth - bDomDepth);
+            return commonDominatorRawSameDepth(a.getDominator(aDomDepth - bDomDepth), b);
         } else {
-            iterB = b.getDominator(bDomDepth - aDomDepth);
+            return commonDominatorRawSameDepth(a, b.getDominator(bDomDepth - aDomDepth));
         }
+    }
 
+    static AbstractBlockBase<?> commonDominatorRawSameDepth(AbstractBlockBase<?> a, AbstractBlockBase<?> b) {
+        AbstractBlockBase<?> iterA = a;
+        AbstractBlockBase<?> iterB = b;
         while (iterA != iterB) {
             iterA = iterA.getDominator();
             iterB = iterB.getDominator();
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue Mar 03 17:13:51 2015 -0800
@@ -218,7 +218,7 @@
                     double trueDestinationProbability) {
         Variable left;
         Value right;
-        Condition actualCondition = null;
+        Condition actualCondition;
         if (isConstant(x)) {
             left = load(y);
             right = loadNonConst(x);
@@ -228,7 +228,7 @@
             right = loadNonConst(y);
             actualCondition = cond;
         }
-        SPARCCompare opcode = null;
+        SPARCCompare opcode;
         Kind kind = left.getKind().getStackKind();
         switch (kind) {
             case Object:
@@ -250,7 +250,7 @@
                 opcode = DCMP;
                 break;
             default:
-                GraalInternalError.shouldNotReachHere(kind.toString());
+                throw GraalInternalError.shouldNotReachHere(kind.toString());
         }
         append(new SPARCControlFlow.CompareBranchOp(opcode, left, right, actualCondition, trueDestination, falseDestination, kind, unorderedIsTrue, trueDestinationProbability));
     }
@@ -258,13 +258,13 @@
     @Override
     public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, LIRKind cmpLIRKind, double overflowProbability) {
         Kind cmpKind = (Kind) cmpLIRKind.getPlatformKind();
-        append(new BranchOp(ConditionFlag.OverflowSet, overflow, noOverflow, cmpKind));
+        append(new BranchOp(ConditionFlag.OverflowSet, overflow, noOverflow, cmpKind, overflowProbability));
     }
 
     @Override
     public void emitIntegerTestBranch(Value left, Value right, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) {
         emitIntegerTest(left, right);
-        append(new BranchOp(Condition.EQ, trueDestination, falseDestination, left.getKind().getStackKind()));
+        append(new BranchOp(ConditionFlag.Equal, trueDestination, falseDestination, left.getKind().getStackKind(), trueDestinationProbability));
     }
 
     private void emitIntegerTest(Value a, Value b) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Tue Mar 03 17:13:51 2015 -0800
@@ -60,6 +60,7 @@
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.schedule.*;
+import com.oracle.graal.phases.schedule.SchedulePhase.*;
 import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.phases.util.*;
 import com.oracle.graal.printer.*;
@@ -302,7 +303,8 @@
     }
 
     protected static String getCanonicalGraphString(StructuredGraph graph, boolean excludeVirtual, boolean checkConstants) {
-        SchedulePhase schedule = new SchedulePhase();
+        SchedulePhase schedule = new SchedulePhase(SchedulingStrategy.EARLIEST);
+        schedule.setScheduleConstants(true);
         schedule.apply(graph);
 
         NodeMap<Integer> canonicalId = graph.createNodeMap();
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LongNodeChainTest.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LongNodeChainTest.java	Tue Mar 03 17:13:51 2015 -0800
@@ -28,6 +28,7 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
 import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.debug.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.schedule.*;
@@ -36,9 +37,10 @@
 
 public class LongNodeChainTest extends GraalCompilerTest {
 
-    public static final int N = 100000;
+    public static final int N = 10000;
 
-    @Ignore
+    private static final SchedulingStrategy[] Strategies = new SchedulingStrategy[]{SchedulingStrategy.EARLIEST};
+
     @Test
     public void testLongAddChain() {
         longAddChain(true);
@@ -51,6 +53,9 @@
         ValueNode constant = graph.unique(ConstantNode.forPrimitive(JavaConstant.INT_1));
         ValueNode value = null;
         if (reverse) {
+            // Make sure the constant's stamp is not used to infer the add node's stamp.
+            OpaqueNode opaque = graph.unique(new OpaqueNode(constant));
+            constant = opaque;
             AddNode addNode = graph.unique(new AddNode(constant, constant));
             value = addNode;
             for (int i = 1; i < N; ++i) {
@@ -58,6 +63,7 @@
                 addNode.setY(newAddNode);
                 addNode = newAddNode;
             }
+            opaque.replaceAndDelete(opaque.getValue());
         } else {
             value = constant;
             for (int i = 0; i < N; ++i) {
@@ -67,7 +73,7 @@
         ReturnNode returnNode = graph.add(new ReturnNode(value));
         graph.start().setNext(returnNode);
 
-        for (SchedulingStrategy s : SchedulingStrategy.values()) {
+        for (SchedulingStrategy s : Strategies) {
             new SchedulePhase(s).apply(graph);
         }
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Tue Mar 03 17:13:51 2015 -0800
@@ -38,15 +38,14 @@
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
-import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.lir.gen.*;
+import com.oracle.graal.lir.phases.AllocationPhase.AllocationContext;
 import com.oracle.graal.lir.phases.*;
+import com.oracle.graal.lir.phases.PostAllocationOptimizationPhase.PostAllocationOptimizationContext;
 import com.oracle.graal.lir.phases.PreAllocationOptimizationPhase.PreAllocationOptimizationContext;
-import com.oracle.graal.lir.phases.PostAllocationOptimizationPhase.PostAllocationOptimizationContext;
-import com.oracle.graal.lir.phases.AllocationPhase.AllocationContext;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
 import com.oracle.graal.nodes.spi.*;
@@ -64,6 +63,8 @@
 
     private static final DebugTimer FrontEnd = Debug.timer("FrontEnd");
     private static final DebugTimer BackEnd = Debug.timer("BackEnd");
+    private static final DebugTimer EmitLIR = Debug.timer("EmitLIR");
+    private static final DebugTimer EmitCode = Debug.timer("EmitCode");
 
     /**
      * The set of positive filters specified by the {@code -G:IntrinsificationsEnabled} option. To
@@ -93,6 +94,9 @@
         @Option(help = "Pattern for method(s) to which intrinsification will not be applied. " +
                        "See MethodFilter class for pattern syntax.", type = OptionType.Debug)
         public static final OptionValue<String> IntrinsificationsDisabled = new OptionValue<>(null);
+
+        @Option(help = "Repeatedly run the LIR code generation pass to improve statistical profiling results.", type = OptionType.Debug)
+        public static final OptionValue<Integer> EmitLIRRepeatCount = new OptionValue<>(0);
         // @formatter:on
 
     }
@@ -240,7 +244,7 @@
      */
     public static SchedulePhase emitFrontEnd(Providers providers, TargetDescription target, StructuredGraph graph, Map<ResolvedJavaMethod, StructuredGraph> cache,
                     PhaseSuite<HighTierContext> graphBuilderSuite, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, SpeculationLog speculationLog, Suites suites) {
-        try (Scope s = Debug.scope("FrontEnd"); TimerCloseable a = FrontEnd.start()) {
+        try (Scope s = Debug.scope("FrontEnd"); DebugCloseable a = FrontEnd.start()) {
             if (speculationLog != null) {
                 speculationLog.collectFailedSpeculations();
             }
@@ -276,10 +280,18 @@
 
     public static <T extends CompilationResult> void emitBackEnd(StructuredGraph graph, Object stub, CallingConvention cc, ResolvedJavaMethod installedCodeOwner, Backend backend,
                     TargetDescription target, T compilationResult, CompilationResultBuilderFactory factory, SchedulePhase schedule, RegisterConfig registerConfig, LIRSuites lirSuites) {
-        try (TimerCloseable a = BackEnd.start()) {
+        try (Scope s = Debug.scope("BackEnd"); DebugCloseable a = BackEnd.start()) {
+            // Repeatedly run the LIR code generation pass to improve statistical profiling results.
+            for (int i = 0; i < EmitLIRRepeatCount.getValue(); i++) {
+                SchedulePhase dummySchedule = new SchedulePhase();
+                dummySchedule.setScheduleConstants(true);
+                dummySchedule.apply(graph);
+                emitLIR(backend, target, dummySchedule, graph, stub, cc, registerConfig, lirSuites);
+            }
+
             LIRGenerationResult lirGen = null;
             lirGen = emitLIR(backend, target, schedule, graph, stub, cc, registerConfig, lirSuites);
-            try (Scope s = Debug.scope("CodeGen", lirGen, lirGen.getLIR())) {
+            try (Scope s2 = Debug.scope("CodeGen", lirGen, lirGen.getLIR())) {
                 emitCode(backend, graph.getAssumptions(), graph.method(), graph.getInlinedMethods(), lirGen, compilationResult, installedCodeOwner, factory);
             } catch (Throwable e) {
                 throw Debug.handle(e);
@@ -300,18 +312,21 @@
         }
     }
 
+    private static final DebugTimer lirGenTimeTracker = Debug.timer("LIRGenTime");
+    private static final DebugMemUseTracker lirGenMemUseTracker = Debug.memUseTracker("LIRGenMemUse");
+
     public static LIRGenerationResult emitLIR(Backend backend, TargetDescription target, SchedulePhase schedule, StructuredGraph graph, Object stub, CallingConvention cc,
                     RegisterConfig registerConfig, LIRSuites lirSuites) {
-        List<Block> blocks = schedule.getCFG().getBlocks();
-        Block startBlock = schedule.getCFG().getStartBlock();
-        assert startBlock != null;
-        assert startBlock.getPredecessorCount() == 0;
+        try (Scope ds = Debug.scope("EmitLIR"); DebugCloseable a = EmitLIR.start()) {
+            List<Block> blocks = schedule.getCFG().getBlocks();
+            Block startBlock = schedule.getCFG().getStartBlock();
+            assert startBlock != null;
+            assert startBlock.getPredecessorCount() == 0;
 
-        LIR lir = null;
-        List<Block> codeEmittingOrder = null;
-        List<Block> linearScanOrder = null;
-        try (Scope ds = Debug.scope("MidEnd")) {
-            try (Scope s = Debug.scope("ComputeLinearScanOrder")) {
+            LIR lir = null;
+            List<Block> codeEmittingOrder = null;
+            List<Block> linearScanOrder = null;
+            try (Scope s = Debug.scope("ComputeLinearScanOrder", lir)) {
                 codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blocks.size(), startBlock);
                 linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blocks.size(), startBlock);
 
@@ -320,16 +335,12 @@
             } catch (Throwable e) {
                 throw Debug.handle(e);
             }
-        } catch (Throwable e) {
-            throw Debug.handle(e);
-        }
-        try (Scope ds = Debug.scope("BackEnd", lir)) {
             FrameMapBuilder frameMapBuilder = backend.newFrameMapBuilder(registerConfig);
             LIRGenerationResult lirGenRes = backend.newLIRGenerationResult(lir, frameMapBuilder, graph.method(), stub);
             LIRGeneratorTool lirGen = backend.newLIRGenerator(cc, lirGenRes);
             NodeLIRBuilderTool nodeLirGen = backend.newNodeLIRBuilder(graph, lirGen);
 
-            try (Scope s = Debug.scope("LIRGen", lirGen)) {
+            try (Scope s = Debug.scope("LIRGen", lir, lirGen); AutoCloseable c = lirGenMemUseTracker.start(); AutoCloseable t = lirGenTimeTracker.start()) {
                 for (Block b : linearScanOrder) {
                     emitBlock(nodeLirGen, lirGenRes, b, graph, schedule.getBlockToNodesMap());
                 }
@@ -366,45 +377,49 @@
 
     public static void emitCode(Backend backend, Assumptions assumptions, ResolvedJavaMethod rootMethod, Set<ResolvedJavaMethod> inlinedMethods, LIRGenerationResult lirGenRes,
                     CompilationResult compilationResult, ResolvedJavaMethod installedCodeOwner, CompilationResultBuilderFactory factory) {
-        FrameMap frameMap = lirGenRes.getFrameMap();
-        CompilationResultBuilder crb = backend.newCompilationResultBuilder(lirGenRes, frameMap, compilationResult, factory);
-        backend.emitCode(crb, lirGenRes.getLIR(), installedCodeOwner);
-        crb.finish();
-        if (assumptions != null && !assumptions.isEmpty()) {
-            compilationResult.setAssumptions(assumptions.toArray());
-        }
-        if (inlinedMethods != null) {
-            compilationResult.setMethods(rootMethod, inlinedMethods);
-        }
-
-        if (Debug.isMeterEnabled()) {
-            List<DataPatch> ldp = compilationResult.getDataPatches();
-            Kind[] kindValues = Kind.values();
-            DebugMetric[] dms = new DebugMetric[kindValues.length];
-            for (int i = 0; i < dms.length; i++) {
-                dms[i] = Debug.metric("DataPatches-%s", kindValues[i]);
+        try (DebugCloseable a = EmitCode.start()) {
+            FrameMap frameMap = lirGenRes.getFrameMap();
+            CompilationResultBuilder crb = backend.newCompilationResultBuilder(lirGenRes, frameMap, compilationResult, factory);
+            backend.emitCode(crb, lirGenRes.getLIR(), installedCodeOwner);
+            crb.finish();
+            if (assumptions != null && !assumptions.isEmpty()) {
+                compilationResult.setAssumptions(assumptions.toArray());
+            }
+            if (inlinedMethods != null) {
+                compilationResult.setMethods(rootMethod, inlinedMethods);
             }
 
-            for (DataPatch dp : ldp) {
-                Kind kind = Kind.Illegal;
-                if (dp.reference instanceof ConstantReference) {
-                    VMConstant constant = ((ConstantReference) dp.reference).getConstant();
-                    kind = ((JavaConstant) constant).getKind();
+            if (Debug.isMeterEnabled()) {
+                List<DataPatch> ldp = compilationResult.getDataPatches();
+                Kind[] kindValues = Kind.values();
+                DebugMetric[] dms = new DebugMetric[kindValues.length];
+                for (int i = 0; i < dms.length; i++) {
+                    dms[i] = Debug.metric("DataPatches-%s", kindValues[i]);
                 }
-                dms[kind.ordinal()].add(1);
+
+                for (DataPatch dp : ldp) {
+                    Kind kind = Kind.Illegal;
+                    if (dp.reference instanceof ConstantReference) {
+                        VMConstant constant = ((ConstantReference) dp.reference).getConstant();
+                        kind = ((JavaConstant) constant).getKind();
+                    }
+                    dms[kind.ordinal()].add(1);
+                }
+
+                Debug.metric("CompilationResults").increment();
+                Debug.metric("CodeBytesEmitted").add(compilationResult.getTargetCodeSize());
+                Debug.metric("InfopointsEmitted").add(compilationResult.getInfopoints().size());
+                Debug.metric("DataPatches").add(ldp.size());
+                Debug.metric("ExceptionHandlersEmitted").add(compilationResult.getExceptionHandlers().size());
             }
 
-            Debug.metric("CompilationResults").increment();
-            Debug.metric("CodeBytesEmitted").add(compilationResult.getTargetCodeSize());
-            Debug.metric("InfopointsEmitted").add(compilationResult.getInfopoints().size());
-            Debug.metric("DataPatches").add(ldp.size());
-            Debug.metric("ExceptionHandlersEmitted").add(compilationResult.getExceptionHandlers().size());
+            if (Debug.isLogEnabled()) {
+                Debug.log("%s", backend.getProviders().getCodeCache().disassemble(compilationResult, null));
+            }
+
+            Debug.dump(compilationResult, "After code generation");
+        } catch (Throwable e) {
+            throw Debug.handle(e);
         }
-
-        if (Debug.isLogEnabled()) {
-            Debug.log("%s", backend.getProviders().getCodeCache().disassemble(compilationResult, null));
-        }
-
-        Debug.dump(compilationResult, "After code generation");
     }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java	Tue Mar 03 17:13:51 2015 -0800
@@ -83,7 +83,7 @@
                 for (Entry<VirtualObjectNode, VirtualObject> entry : virtualObjectsCopy.entrySet()) {
                     if (entry.getValue().getValues() == null) {
                         VirtualObjectNode vobj = entry.getKey();
-                        JavaValue[] values = new JavaValue[vobj.entryCount()];
+                        Value[] values = new Value[vobj.entryCount()];
                         if (values.length > 0) {
                             changed = true;
                             VirtualObjectState currentField = (VirtualObjectState) objectStates.get(vobj);
@@ -98,7 +98,7 @@
                                 }
                             }
                             if (pos != vobj.entryCount()) {
-                                JavaValue[] newValues = new JavaValue[pos];
+                                Value[] newValues = new Value[pos];
                                 System.arraycopy(values, 0, newValues, 0, pos);
                                 values = newValues;
                             }
@@ -136,7 +136,7 @@
             int numStack = state.stackSize();
             int numLocks = state.locksSize();
 
-            JavaValue[] values = new JavaValue[numLocals + numStack + numLocks];
+            Value[] values = new Value[numLocals + numStack + numLocks];
             computeLocals(state, numLocals, values);
             computeStack(state, numLocals, numStack, values);
             computeLocks(state, values);
@@ -151,33 +151,33 @@
         }
     }
 
-    protected void computeLocals(FrameState state, int numLocals, JavaValue[] values) {
+    protected void computeLocals(FrameState state, int numLocals, Value[] values) {
         for (int i = 0; i < numLocals; i++) {
             values[i] = computeLocalValue(state, i);
         }
     }
 
-    protected JavaValue computeLocalValue(FrameState state, int i) {
+    protected Value computeLocalValue(FrameState state, int i) {
         return toValue(state.localAt(i));
     }
 
-    protected void computeStack(FrameState state, int numLocals, int numStack, JavaValue[] values) {
+    protected void computeStack(FrameState state, int numLocals, int numStack, Value[] values) {
         for (int i = 0; i < numStack; i++) {
             values[numLocals + i] = computeStackValue(state, i);
         }
     }
 
-    protected JavaValue computeStackValue(FrameState state, int i) {
+    protected Value computeStackValue(FrameState state, int i) {
         return toValue(state.stackAt(i));
     }
 
-    protected void computeLocks(FrameState state, JavaValue[] values) {
+    protected void computeLocks(FrameState state, Value[] values) {
         for (int i = 0; i < state.locksSize(); i++) {
             values[state.localsSize() + state.stackSize() + i] = computeLockValue(state, i);
         }
     }
 
-    protected JavaValue computeLockValue(FrameState state, int i) {
+    protected Value computeLockValue(FrameState state, int i) {
         return toValue(state.lockAt(i));
     }
 
@@ -186,7 +186,7 @@
     private static final DebugMetric STATE_VARIABLES = Debug.metric("StateVariables");
     private static final DebugMetric STATE_CONSTANTS = Debug.metric("StateConstants");
 
-    protected JavaValue toValue(ValueNode value) {
+    protected Value toValue(ValueNode value) {
         try {
             if (value instanceof VirtualObjectNode) {
                 VirtualObjectNode obj = (VirtualObjectNode) value;
@@ -218,7 +218,7 @@
                     STATE_VARIABLES.increment();
                     Value operand = nodeOperands.get(value);
                     assert operand != null && (operand instanceof Variable || operand instanceof JavaConstant) : operand + " for " + value;
-                    return (JavaValue) operand;
+                    return operand;
 
                 } else {
                     // return a dummy value because real value not needed
--- a/graal/com.oracle.graal.debug.test/src/com/oracle/graal/debug/test/DebugTimerTest.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.debug.test/src/com/oracle/graal/debug/test/DebugTimerTest.java	Tue Mar 03 17:13:51 2015 -0800
@@ -29,7 +29,6 @@
 import org.junit.*;
 
 import com.oracle.graal.debug.*;
-import com.oracle.graal.debug.internal.*;
 
 public class DebugTimerTest {
 
@@ -63,9 +62,9 @@
             long spinA;
             long spinB;
 
-            try (TimerCloseable a1 = timerA.start()) {
+            try (DebugCloseable a1 = timerA.start()) {
                 spinA = spin(50);
-                try (TimerCloseable b1 = timerB.start()) {
+                try (DebugCloseable b1 = timerB.start()) {
                     spinB = spin(50);
                 }
             }
@@ -83,15 +82,15 @@
         DebugConfig debugConfig = Debug.fixedConfig(0, 0, false, false, true, false, null, null, System.out);
         try (DebugConfigScope dcs = new DebugConfigScope(debugConfig); Debug.Scope s = Debug.scope("DebugTimerTest")) {
             DebugTimer timerC = Debug.timer("TimerC");
-            try (TimerCloseable c1 = timerC.start()) {
+            try (DebugCloseable c1 = timerC.start()) {
                 spin(50);
-                try (TimerCloseable c2 = timerC.start()) {
+                try (DebugCloseable c2 = timerC.start()) {
                     spin(50);
-                    try (TimerCloseable c3 = timerC.start()) {
+                    try (DebugCloseable c3 = timerC.start()) {
                         spin(50);
-                        try (TimerCloseable c4 = timerC.start()) {
+                        try (DebugCloseable c4 = timerC.start()) {
                             spin(50);
-                            try (TimerCloseable c5 = timerC.start()) {
+                            try (DebugCloseable c5 = timerC.start()) {
                                 spin(50);
                             }
                         }
@@ -115,13 +114,13 @@
             long spinD1;
             long spinE;
 
-            try (TimerCloseable d1 = timerD.start()) {
+            try (DebugCloseable d1 = timerD.start()) {
                 spinD1 = spin(50);
-                try (TimerCloseable e1 = timerE.start()) {
+                try (DebugCloseable e1 = timerE.start()) {
                     spinE = spin(50);
-                    try (TimerCloseable d2 = timerD.start()) {
+                    try (DebugCloseable d2 = timerD.start()) {
                         spin(50);
-                        try (TimerCloseable d3 = timerD.start()) {
+                        try (DebugCloseable d3 = timerD.start()) {
                             spin(50);
                         }
                     }
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Tue Mar 03 17:13:51 2015 -0800
@@ -1131,8 +1131,8 @@
 
     private static final DebugMemUseTracker VOID_MEM_USE_TRACKER = new DebugMemUseTracker() {
 
-        public Closeable start() {
-            return MemUseTrackerImpl.VOID_CLOSEABLE;
+        public DebugCloseable start() {
+            return DebugCloseable.VOID_CLOSEABLE;
         }
 
         public long getCurrentValue() {
@@ -1319,8 +1319,8 @@
 
     private static final DebugTimer VOID_TIMER = new DebugTimer() {
 
-        public TimerCloseable start() {
-            return TimerImpl.VOID_CLOSEABLE;
+        public DebugCloseable start() {
+            return DebugCloseable.VOID_CLOSEABLE;
         }
 
         public void setConditional(boolean flag) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugCloseable.java	Tue Mar 03 17:13:51 2015 -0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug;
+
+/**
+ * An object returned by {@link DebugTimer#start()} that when closed, stops the associated timer and
+ * adds the elapsed time since {@code start()} to the total for the timer.
+ */
+public interface DebugCloseable extends AutoCloseable {
+
+    DebugCloseable VOID_CLOSEABLE = new DebugCloseable() {
+
+        @Override
+        public void close() {
+        }
+    };
+
+    void close();
+}
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugMemUseTracker.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugMemUseTracker.java	Tue Mar 03 17:13:51 2015 -0800
@@ -36,10 +36,6 @@
  */
 public interface DebugMemUseTracker {
 
-    public interface Closeable extends AutoCloseable {
-        void close();
-    }
-
     /**
      * Creates a point from which memory usage will be recorded if memory use tracking is
      * {@linkplain Debug#isMemUseTrackingEnabled() enabled}.
@@ -47,7 +43,7 @@
      * @return an object that must be closed once the activity has completed to add the memory used
      *         since this call to the total for this tracker
      */
-    Closeable start();
+    DebugCloseable start();
 
     /**
      * Gets the current value of this tracker.
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugTimer.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugTimer.java	Tue Mar 03 17:13:51 2015 -0800
@@ -24,8 +24,6 @@
 
 import java.util.concurrent.*;
 
-import com.oracle.graal.debug.internal.*;
-
 /**
  * A timer for some activity of interest. A timer should be deployed using the try-with-resources
  * pattern:
@@ -45,7 +43,7 @@
      * @return an object that must be closed once the activity has completed to add the elapsed time
      *         since this call to the total for this timer
      */
-    TimerCloseable start();
+    DebugCloseable start();
 
     /**
      * Sets a flag determining if this timer is only enabled if timing is
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/AccumulatedDebugValue.java	Tue Mar 03 17:13:51 2015 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug.internal;
+
+public abstract class AccumulatedDebugValue extends DebugValue {
+    protected final DebugValue flat;
+
+    public AccumulatedDebugValue(String name, boolean conditional, DebugValue flat) {
+        super(name + "_Accm", conditional);
+        this.flat = flat;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/CloseableCounterImpl.java	Tue Mar 03 17:13:51 2015 -0800
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug.internal;
+
+import com.oracle.graal.debug.*;
+
+/**
+ * A helper class for DebugValues that can nest and need to split out accumulated and flat values
+ * for some kind of counter-like measurement.
+ */
+abstract class CloseableCounterImpl implements DebugCloseable {
+
+    protected final CloseableCounterImpl parent;
+    protected final AccumulatedDebugValue counter;
+    protected final long start;
+    protected long nestedAmountToSubtract;
+
+    CloseableCounterImpl(CloseableCounterImpl parent, AccumulatedDebugValue counter) {
+        this.parent = parent;
+        this.start = getCounterValue();
+        this.counter = counter;
+    }
+
+    @Override
+    public void close() {
+        long end = getCounterValue();
+        long difference = end - start;
+        if (parent != null) {
+            if (!counter.getName().equals(parent.counter.getName())) {
+                parent.nestedAmountToSubtract += difference;
+
+                // Look for our counter in an outer scope and fix up
+                // the adjustment to the flat count
+                CloseableCounterImpl ancestor = parent.parent;
+                while (ancestor != null) {
+                    if (ancestor.counter.getName().equals(counter.getName())) {
+                        ancestor.nestedAmountToSubtract -= difference;
+                        break;
+                    }
+                    ancestor = ancestor.parent;
+                }
+            }
+        }
+        long flatAmount = difference - nestedAmountToSubtract;
+        counter.addToCurrentValue(difference);
+        counter.flat.addToCurrentValue(flatAmount);
+    }
+
+    abstract long getCounterValue();
+}
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/MemUseTrackerImpl.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/MemUseTrackerImpl.java	Tue Mar 03 17:13:51 2015 -0800
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.debug.internal;
 
+import static com.oracle.graal.debug.DebugCloseable.*;
 import static java.lang.Thread.*;
 
 import java.lang.management.*;
@@ -29,7 +30,7 @@
 import com.oracle.graal.debug.*;
 import com.sun.management.ThreadMXBean;
 
-public final class MemUseTrackerImpl extends DebugValue implements DebugMemUseTracker {
+public final class MemUseTrackerImpl extends AccumulatedDebugValue implements DebugMemUseTracker {
 
     private static final ThreadMXBean threadMXBean = (ThreadMXBean) ManagementFactory.getThreadMXBean();
 
@@ -42,35 +43,25 @@
         return threadMXBean.getThreadAllocatedBytes(currentThread().getId()) - threadMXBeanOverhead;
     }
 
-    public static final Closeable VOID_CLOSEABLE = new Closeable() {
-
-        @Override
-        public void close() {
-        }
-    };
-
     /**
      * Records the most recent active tracker.
      */
-    private static final ThreadLocal<CloseableImpl> currentTracker = new ThreadLocal<>();
-
-    private final DebugValue flat;
+    private static final ThreadLocal<CloseableCounterImpl> currentTracker = new ThreadLocal<>();
 
     public MemUseTrackerImpl(String name) {
-        super(name + "_Accm", true);
-        this.flat = new DebugValue(name + "_Flat", true) {
+        super(name, false, new DebugValue(name + "_Flat", true) {
 
             @Override
             public String toString(long value) {
                 return valueToString(value);
             }
-        };
+        });
     }
 
     @Override
-    public Closeable start() {
+    public DebugCloseable start() {
         if (!isConditional() || Debug.isMemUseTrackingEnabled()) {
-            CloseableImpl result = new CloseableImpl();
+            MemUseCloseableCounterImpl result = new MemUseCloseableCounterImpl(this);
             currentTracker.set(result);
             return result;
         } else {
@@ -87,27 +78,21 @@
         return valueToString(value);
     }
 
-    private final class CloseableImpl implements Closeable {
+    private static final class MemUseCloseableCounterImpl extends CloseableCounterImpl implements DebugCloseable {
 
-        private final CloseableImpl parent;
-        private final long start;
-        private long nestedAmountToSubtract;
+        private MemUseCloseableCounterImpl(AccumulatedDebugValue counter) {
+            super(currentTracker.get(), counter);
+        }
 
-        private CloseableImpl() {
-            this.parent = currentTracker.get();
-            this.start = getCurrentThreadAllocatedBytes();
+        @Override
+        long getCounterValue() {
+            return getCurrentThreadAllocatedBytes();
         }
 
         @Override
         public void close() {
-            long end = getCurrentThreadAllocatedBytes();
-            long allocated = end - start;
-            if (parent != null) {
-                parent.nestedAmountToSubtract += allocated;
-            }
+            super.close();
             currentTracker.set(parent);
-            MemUseTrackerImpl.this.addToCurrentValue(allocated);
-            flat.addToCurrentValue(allocated - nestedAmountToSubtract);
         }
     }
 }
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/TimerCloseable.java	Tue Mar 03 17:11:46 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 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.debug.internal;
-
-import com.oracle.graal.debug.*;
-
-/**
- * An object returned by {@link DebugTimer#start()} that when closed, stops the associated timer and
- * adds the elapsed time since {@code start()} to the total for the timer.
- */
-public interface TimerCloseable extends AutoCloseable {
-
-    void close();
-}
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/TimerImpl.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/TimerImpl.java	Tue Mar 03 17:13:51 2015 -0800
@@ -22,35 +22,27 @@
  */
 package com.oracle.graal.debug.internal;
 
+import static com.oracle.graal.debug.DebugCloseable.*;
+
 import java.lang.management.*;
 import java.util.concurrent.*;
 
 import com.oracle.graal.debug.*;
 
-public final class TimerImpl extends DebugValue implements DebugTimer {
+public final class TimerImpl extends AccumulatedDebugValue implements DebugTimer {
 
     private static final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
 
-    public static final TimerCloseable VOID_CLOSEABLE = new TimerCloseable() {
-
-        @Override
-        public void close() {
-        }
-    };
-
     /**
      * Records the most recent active timer.
      */
-    private static final ThreadLocal<AbstractTimer> currentTimer = new ThreadLocal<>();
-
-    private final FlatTimer flat;
+    private static final ThreadLocal<CloseableCounterImpl> currentTimer = new ThreadLocal<>();
 
     static class FlatTimer extends DebugValue implements DebugTimer {
-        private final TimerImpl accm;
+        private TimerImpl accm;
 
-        public FlatTimer(TimerImpl accm, String name) {
-            super(name + "_Flat", accm.isConditional());
-            this.accm = accm;
+        public FlatTimer(String name, boolean conditional) {
+            super(name + "_Flat", conditional);
         }
 
         @Override
@@ -62,31 +54,24 @@
             return accm.getTimeUnit();
         }
 
-        public TimerCloseable start() {
+        public DebugCloseable start() {
             return accm.start();
         }
     }
 
     public TimerImpl(String name, boolean conditional) {
-        super(name + "_Accm", conditional);
-        this.flat = new FlatTimer(this, name);
+        super(name, conditional, new FlatTimer(name, conditional));
+        ((FlatTimer) flat).accm = this;
     }
 
     @Override
-    public TimerCloseable start() {
+    public DebugCloseable start() {
         if (!isConditional() || Debug.isTimeEnabled()) {
-            long startTime;
-            if (threadMXBean.isCurrentThreadCpuTimeSupported()) {
-                startTime = threadMXBean.getCurrentThreadCpuTime();
-            } else {
-                startTime = System.nanoTime();
-            }
-
             AbstractTimer result;
             if (threadMXBean.isCurrentThreadCpuTimeSupported()) {
-                result = new CpuTimeTimer(this, startTime);
+                result = new CpuTimeTimer(this);
             } else {
-                result = new SystemNanosTimer(this, startTime);
+                result = new SystemNanosTimer(this);
             }
             currentTimer.set(result);
             return result;
@@ -100,7 +85,7 @@
     }
 
     public DebugTimer getFlat() {
-        return flat;
+        return (FlatTimer) flat;
     }
 
     @Override
@@ -112,68 +97,39 @@
         return TimeUnit.NANOSECONDS;
     }
 
-    private abstract static class AbstractTimer implements TimerCloseable {
+    private abstract static class AbstractTimer extends CloseableCounterImpl implements DebugCloseable {
 
-        private final AbstractTimer parent;
-        private final TimerImpl timer;
-        private final long startTime;
-        private long nestedTimeToSubtract;
-
-        private AbstractTimer(TimerImpl timer, long startTime) {
-            this.parent = currentTimer.get();
-            this.timer = timer;
-            this.startTime = startTime;
+        private AbstractTimer(AccumulatedDebugValue counter) {
+            super(currentTimer.get(), counter);
         }
 
         @Override
         public void close() {
-            long endTime = currentTime();
-            long timeSpan = endTime - startTime;
-            if (parent != null) {
-                if (timer != parent.timer) {
-                    parent.nestedTimeToSubtract += timeSpan;
-
-                    // Look for our timer in an outer timing scope and fix up
-                    // the adjustment to the flat time
-                    AbstractTimer ancestor = parent.parent;
-                    while (ancestor != null) {
-                        if (ancestor.timer == timer) {
-                            ancestor.nestedTimeToSubtract -= timeSpan;
-                            break;
-                        }
-                        ancestor = ancestor.parent;
-                    }
-                }
-            }
+            super.close();
             currentTimer.set(parent);
-            long flatTime = timeSpan - nestedTimeToSubtract;
-            timer.addToCurrentValue(timeSpan);
-            timer.flat.addToCurrentValue(flatTime);
         }
-
-        protected abstract long currentTime();
     }
 
     private final class SystemNanosTimer extends AbstractTimer {
 
-        public SystemNanosTimer(TimerImpl timer, long startTime) {
-            super(timer, startTime);
+        public SystemNanosTimer(TimerImpl timer) {
+            super(timer);
         }
 
         @Override
-        protected long currentTime() {
+        protected long getCounterValue() {
             return System.nanoTime();
         }
     }
 
     private final class CpuTimeTimer extends AbstractTimer {
 
-        public CpuTimeTimer(TimerImpl timer, long startTime) {
-            super(timer, startTime);
+        public CpuTimeTimer(TimerImpl timer) {
+            super(timer);
         }
 
         @Override
-        protected long currentTime() {
+        protected long getCounterValue() {
             return threadMXBean.getCurrentThreadCpuTime();
         }
     }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java	Tue Mar 03 17:13:51 2015 -0800
@@ -28,7 +28,6 @@
 
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.debug.*;
-import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.Node.ValueNumberable;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.options.*;
@@ -887,7 +886,7 @@
 
     @SuppressWarnings("all")
     public Map<Node, Node> addDuplicates(Iterable<? extends Node> newNodes, final Graph oldGraph, int estimatedNodeCount, DuplicationReplacement replacements) {
-        try (TimerCloseable s = DuplicateGraph.start()) {
+        try (DebugCloseable s = DuplicateGraph.start()) {
             return NodeClass.addGraphDuplicate(this, oldGraph, estimatedNodeCount, newNodes, replacements);
         }
     }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeBitMap.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeBitMap.java	Tue Mar 03 17:13:51 2015 -0800
@@ -32,6 +32,7 @@
     private long[] bits;
     private int nodeCount;
     private final NodeIdAccessor nodeIdAccessor;
+    private int counter;
 
     public NodeBitMap(Graph graph) {
         nodeCount = graph.nodeIdCount();
@@ -43,6 +44,10 @@
         return (nodeCount + Long.SIZE - 1) >> SHIFT;
     }
 
+    public int getCounter() {
+        return counter;
+    }
+
     private NodeBitMap(NodeBitMap other) {
         this.bits = other.bits.clone();
         this.nodeCount = other.nodeCount;
@@ -63,6 +68,16 @@
         return isMarked(id);
     }
 
+    public boolean checkAndMarkInc(Node node) {
+        if (!isMarked(node)) {
+            this.counter++;
+            this.mark(node);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
     public boolean isMarked(int id) {
         return (bits[id >> SHIFT] & (1L << id)) != 0;
     }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Tue Mar 03 17:13:51 2015 -0800
@@ -34,7 +34,6 @@
 
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.debug.*;
-import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.Edges.Type;
 import com.oracle.graal.graph.Graph.DuplicationReplacement;
 import com.oracle.graal.graph.Node.Input;
@@ -64,7 +63,7 @@
     private static final DebugTimer Init_IterableIds = Debug.timer("NodeClass.Init.IterableIds");
 
     private static <T extends Annotation> T getAnnotationTimed(AnnotatedElement e, Class<T> annotationClass) {
-        try (TimerCloseable s = Init_AnnotationParsing.start()) {
+        try (DebugCloseable s = Init_AnnotationParsing.start()) {
             return e.getAnnotation(annotationClass);
         }
     }
@@ -147,15 +146,15 @@
         this.isSimplifiable = Simplifiable.class.isAssignableFrom(clazz);
 
         NodeFieldsScanner fs = new NodeFieldsScanner(calcOffset, superNodeClass);
-        try (TimerCloseable t = Init_FieldScanning.start()) {
+        try (DebugCloseable t = Init_FieldScanning.start()) {
             fs.scan(clazz, clazz.getSuperclass(), false);
         }
 
-        try (TimerCloseable t1 = Init_Edges.start()) {
+        try (DebugCloseable t1 = Init_Edges.start()) {
             successors = new SuccessorEdges(fs.directSuccessors, fs.successors);
             inputs = new InputEdges(fs.directInputs, fs.inputs);
         }
-        try (TimerCloseable t1 = Init_Data.start()) {
+        try (DebugCloseable t1 = Init_Data.start()) {
             data = new Fields(fs.data);
         }
 
@@ -168,7 +167,7 @@
         assert info != null : "Missing NodeInfo annotation on " + clazz;
         this.nameTemplate = info.nameTemplate();
 
-        try (TimerCloseable t1 = Init_AllowedUsages.start()) {
+        try (DebugCloseable t1 = Init_AllowedUsages.start()) {
             allowedUsageTypes = superNodeClass == null ? EnumSet.noneOf(InputType.class) : superNodeClass.allowedUsageTypes.clone();
             allowedUsageTypes.addAll(Arrays.asList(info.allowedUsageTypes()));
         }
@@ -178,7 +177,7 @@
             this.iterableId = presetIterableId;
         } else if (IterableNodeType.class.isAssignableFrom(clazz)) {
             ITERABLE_NODE_TYPES.increment();
-            try (TimerCloseable t1 = Init_IterableIds.start()) {
+            try (DebugCloseable t1 = Init_IterableIds.start()) {
                 this.iterableId = nextIterableId.getAndIncrement();
 
                 NodeClass<?> snc = superNodeClass;
@@ -335,7 +334,7 @@
             Input inputAnnotation = getAnnotationTimed(field, Node.Input.class);
             OptionalInput optionalInputAnnotation = getAnnotationTimed(field, Node.OptionalInput.class);
             Successor successorAnnotation = getAnnotationTimed(field, Successor.class);
-            try (TimerCloseable s = Init_FieldScanningInner.start()) {
+            try (DebugCloseable s = Init_FieldScanningInner.start()) {
                 Class<?> type = field.getType();
                 int modifiers = field.getModifiers();
 
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Tue Mar 03 17:13:51 2015 -0800
@@ -24,6 +24,10 @@
 
 import static com.oracle.graal.api.code.CallingConvention.Type.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*;
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.compiler.common.UnsafeAccess.*;
 import static com.oracle.graal.sparc.SPARC.*;
@@ -34,14 +38,6 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Bpne;
-import com.oracle.graal.asm.sparc.SPARCAssembler.CC;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Save;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Stx;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.RestoreWindow;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
 import com.oracle.graal.compiler.common.cfg.*;
 import com.oracle.graal.hotspot.*;
@@ -115,12 +111,12 @@
                     // Use SPARCAddress to get the final displacement including the stack bias.
                     SPARCAddress address = new SPARCAddress(sp, -disp);
                     if (SPARCAssembler.isSimm13(address.getDisplacement())) {
-                        new Stx(g0, address).emit(masm);
+                        masm.stx(g0, address);
                     } else {
                         try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
                             Register scratch = sc.getRegister();
                             new Setx(address.getDisplacement(), scratch).emit(masm);
-                            new Stx(g0, new SPARCAddress(sp, scratch)).emit(masm);
+                            masm.stx(g0, new SPARCAddress(sp, scratch));
                         }
                     }
                 }
@@ -150,12 +146,12 @@
             }
 
             if (SPARCAssembler.isSimm13(stackpoinerChange)) {
-                new Save(sp, stackpoinerChange, sp).emit(masm);
+                masm.save(sp, stackpoinerChange, sp);
             } else {
                 try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
                     Register scratch = sc.getRegister();
                     new Setx(stackpoinerChange, scratch).emit(masm);
-                    new Save(sp, scratch, sp).emit(masm);
+                    masm.save(sp, scratch, sp);
                 }
             }
 
@@ -163,7 +159,7 @@
                 final int slotSize = 8;
                 for (int i = 0; i < frameSize / slotSize; ++i) {
                     // 0xC1C1C1C1
-                    new Stx(g0, new SPARCAddress(sp, i * slotSize)).emit(masm);
+                    masm.stx(g0, new SPARCAddress(sp, i * slotSize));
                 }
             }
         }
@@ -171,7 +167,7 @@
         @Override
         public void leave(CompilationResultBuilder crb) {
             SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm;
-            new RestoreWindow().emit(masm);
+            masm.restoreWindow();
         }
     }
 
@@ -236,11 +232,11 @@
                     Register receiver = asRegister(cc.getArgument(0));
                     SPARCAddress src = new SPARCAddress(receiver, config.hubOffset);
 
-                    new Ldx(src, scratch).emit(masm);
-                    new Cmp(scratch, inlineCacheKlass).emit(masm);
+                    masm.ldx(src, scratch);
+                    masm.cmp(scratch, inlineCacheKlass);
                 }
-                new Bpne(CC.Xcc, unverifiedStub).emit(masm);
-                new Nop().emit(masm);  // delay slot
+                masm.bpcc(NotEqual, NOT_ANNUL, unverifiedStub, Xcc, PREDICT_NOT_TAKEN);
+                masm.nop();  // delay slot
             }
 
             masm.align(config.codeEntryAlignment);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java	Tue Mar 03 17:13:51 2015 -0800
@@ -28,8 +28,6 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Stw;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Stx;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
@@ -60,8 +58,8 @@
         SPARCMove.move(crb, masm, thread.asValue(LIRKind.value(Kind.Long)), threadTemp, SPARCDelayedControlTransfer.DUMMY);
 
         // Reset last Java frame, last Java PC and flags.
-        new Stx(g0, new SPARCAddress(thread, threadLastJavaSpOffset)).emit(masm);
-        new Stx(g0, new SPARCAddress(thread, threadLastJavaPcOffset)).emit(masm);
-        new Stw(g0, new SPARCAddress(thread, threadJavaFrameAnchorFlagsOffset)).emit(masm);
+        masm.stx(g0, new SPARCAddress(thread, threadLastJavaSpOffset));
+        masm.stx(g0, new SPARCAddress(thread, threadLastJavaPcOffset));
+        masm.stw(g0, new SPARCAddress(thread, threadJavaFrameAnchorFlagsOffset));
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java	Tue Mar 03 17:13:51 2015 -0800
@@ -28,8 +28,6 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Add;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Stx;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
@@ -54,8 +52,8 @@
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         // Save last Java frame.
-        new Add(stackPointer, STACK_BIAS, g4).emit(masm);
-        new Stx(g4, new SPARCAddress(thread, threadLastJavaSpOffset)).emit(masm);
+        masm.add(stackPointer, STACK_BIAS, g4);
+        masm.stx(g4, new SPARCAddress(thread, threadLastJavaSpOffset));
 
         // Save the thread register when calling out to the runtime.
         SPARCMove.move(crb, masm, threadTemp, thread.asValue(LIRKind.value(Kind.Long)), delayedControlTransfer);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEnterUnpackFramesStackFrameOp.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEnterUnpackFramesStackFrameOp.java	Tue Mar 03 17:13:51 2015 -0800
@@ -22,18 +22,17 @@
  */
 package com.oracle.graal.hotspot.sparc;
 
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 import static com.oracle.graal.sparc.SPARC.*;
-import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
-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.hotspot.*;
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
-import com.oracle.graal.lir.asm.*;
 
 /**
  * Emits code that enters a stack frame which is tailored to call the C++ method
@@ -68,32 +67,32 @@
         Register scratchRegister = asRegister(scratch);
 
         // Save final sender SP to O5_savedSP.
-        new Mov(senderSpRegister, o5).emit(masm);
+        masm.mov(senderSpRegister, o5);
 
         // Load final frame PC.
-        new Mov(framePcRegister, o7).emit(masm);
+        masm.mov(framePcRegister, o7);
 
         // Allocate a full sized frame.
-        new Save(sp, -totalFrameSize, sp).emit(masm);
+        masm.save(sp, -totalFrameSize, sp);
 
-        new Mov(i0, o0).emit(masm);
-        new Mov(i1, o1).emit(masm);
-        new Mov(i2, o2).emit(masm);
-        new Mov(i3, o3).emit(masm);
-        new Mov(i4, o4).emit(masm);
+        masm.mov(i0, o0);
+        masm.mov(i1, o1);
+        masm.mov(i2, o2);
+        masm.mov(i3, o3);
+        masm.mov(i4, o4);
 
         // Set up last Java values.
-        new Add(sp, STACK_BIAS, scratchRegister).emit(masm);
-        new Stx(scratchRegister, new SPARCAddress(thread, threadLastJavaSpOffset)).emit(masm);
+        masm.add(sp, STACK_BIAS, scratchRegister);
+        masm.stx(scratchRegister, new SPARCAddress(thread, threadLastJavaSpOffset));
 
         // Clear last Java PC.
-        new Stx(g0, new SPARCAddress(thread, threadLastJavaPcOffset)).emit(masm);
+        masm.stx(g0, new SPARCAddress(thread, threadLastJavaPcOffset));
 
         /*
          * Safe thread register manually since we are not using LEAF_SP for {@link
          * DeoptimizationStub#UNPACK_FRAMES}.
          */
-        new Mov(thread, l7).emit(masm);
+        masm.mov(thread, l7);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java	Tue Mar 03 17:13:51 2015 -0800
@@ -31,11 +31,6 @@
 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.Jmpl;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Lduw;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Movcc;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.sparc.*;
@@ -67,21 +62,21 @@
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         // Move the values up one level to be the input for the next call.
-        new SPARCMacroAssembler.Mov(asRegister(handlerInCallerPc), i2).emit(masm);
-        new SPARCMacroAssembler.Mov(asRegister(exception), i0).emit(masm);
-        new SPARCMacroAssembler.Mov(asRegister(exceptionPc), i1).emit(masm);
+        masm.mov(asRegister(handlerInCallerPc), i2);
+        masm.mov(asRegister(exception), i0);
+        masm.mov(asRegister(exceptionPc), i1);
         leaveFrame(crb);
 
         // Restore SP from L7 if the exception PC is a method handle call site.
         SPARCAddress dst = new SPARCAddress(thread, isMethodHandleReturnOffset);
         try (SPARCScratchRegister scratch = SPARCScratchRegister.get()) {
             Register scratchReg = scratch.getRegister();
-            new Lduw(dst, scratchReg).emit(masm);
-            new Cmp(scratchReg, scratchReg).emit(masm);
-            new Movcc(ConditionFlag.NotZero, CC.Icc, l7, sp).emit(masm);
+            masm.lduw(dst, scratchReg);
+            masm.cmp(scratchReg, scratchReg);
+            masm.movcc(ConditionFlag.NotZero, CC.Icc, l7, sp);
         }
 
-        new Jmpl(asRegister(handlerInCallerPc), 0, g0).emit(masm);
-        new Nop().emit(masm);
+        masm.jmpl(asRegister(handlerInCallerPc), 0, g0);
+        masm.nop();
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java	Tue Mar 03 17:13:51 2015 -0800
@@ -25,7 +25,6 @@
 import static com.oracle.graal.sparc.SPARC.*;
 
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
@@ -44,11 +43,11 @@
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         // Save O registers over restore.
-        new Mov(o0, i0).emit(masm);
-        new Mov(o1, i1).emit(masm);
-        new Mov(o2, i2).emit(masm);
-        new Mov(o3, i3).emit(masm);
-        new Mov(o4, i4).emit(masm);
+        masm.mov(o0, i0);
+        masm.mov(o1, i1);
+        masm.mov(o2, i2);
+        masm.mov(o3, i3);
+        masm.mov(o4, i4);
 
         crb.frameContext.leave(crb);
     }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveDeoptimizedStackFrameOp.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveDeoptimizedStackFrameOp.java	Tue Mar 03 17:13:51 2015 -0800
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.hotspot.sparc;
 
-import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
 import static com.oracle.graal.sparc.SPARC.*;
 
 import com.oracle.graal.asm.sparc.*;
@@ -45,13 +44,13 @@
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         // Save O registers over restore.
-        new Mov(o0, i0).emit(masm);
-        new Mov(o1, i1).emit(masm);
-        new Mov(o2, i2).emit(masm);
-        new Mov(o3, i3).emit(masm);
-        new Mov(o4, i4).emit(masm);
+        masm.mov(o0, i0);
+        masm.mov(o1, i1);
+        masm.mov(o2, i2);
+        masm.mov(o3, i3);
+        masm.mov(o4, i4);
 
-        new RestoreWindow().emit(masm);
+        masm.restoreWindow();
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveUnpackFramesStackFrameOp.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveUnpackFramesStackFrameOp.java	Tue Mar 03 17:13:51 2015 -0800
@@ -22,15 +22,14 @@
  */
 package com.oracle.graal.hotspot.sparc;
 
-import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
 import static com.oracle.graal.sparc.SPARC.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
-import com.oracle.graal.lir.asm.*;
 
 /**
  * Emits code that leaves a stack frame which is tailored to call the C++ method
@@ -59,17 +58,17 @@
          * Safe thread register manually since we are not using LEAF_SP for {@link
          * DeoptimizationStub#UNPACK_FRAMES}.
          */
-        new Mov(l7, thread).emit(masm);
+        masm.mov(l7, thread);
 
         SPARCAddress lastJavaPc = new SPARCAddress(thread, threadLastJavaPcOffset);
 
         // We borrow the threads lastJavaPC to transfer the value from float to i0
-        new Stdf(SPARCSaveRegistersOp.RETURN_REGISTER_STORAGE, lastJavaPc).emit(masm);
-        new Ldx(lastJavaPc, i0).emit(masm);
+        masm.stdf(SPARCSaveRegistersOp.RETURN_REGISTER_STORAGE, lastJavaPc);
+        masm.ldx(lastJavaPc, i0);
 
         // Clear last Java frame values.
-        new Stx(g0, lastJavaPc).emit(masm);
-        new Stx(g0, new SPARCAddress(thread, threadLastJavaSpOffset)).emit(masm);
-        new Stw(g0, new SPARCAddress(thread, threadJavaFrameAnchorFlagsOffset)).emit(masm);
+        masm.stx(g0, lastJavaPc);
+        masm.stx(g0, new SPARCAddress(thread, threadLastJavaSpOffset));
+        masm.stw(g0, new SPARCAddress(thread, threadJavaFrameAnchorFlagsOffset));
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java	Tue Mar 03 17:13:51 2015 -0800
@@ -22,14 +22,13 @@
  */
 package com.oracle.graal.hotspot.sparc;
 
+import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 import static com.oracle.graal.sparc.SPARC.*;
-import static com.oracle.graal.api.code.ValueUtil.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
@@ -51,6 +50,6 @@
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         Register addrRegister = asLongReg(address);
-        new Sub(addrRegister, Return.PC_RETURN_OFFSET, i7).emit(masm);
+        masm.sub(addrRegister, SPARCAssembler.PC_RETURN_OFFSET, i7);
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPushInterpreterFrameOp.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPushInterpreterFrameOp.java	Tue Mar 03 17:13:51 2015 -0800
@@ -22,17 +22,16 @@
  */
 package com.oracle.graal.hotspot.sparc;
 
-import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
-import static com.oracle.graal.sparc.SPARC.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+import static com.oracle.graal.sparc.SPARC.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
-import com.oracle.graal.lir.asm.*;
 
 /**
  * Pushes an interpreter frame to the stack.
@@ -61,21 +60,21 @@
         final Register senderSpRegister = asRegister(senderSp);
 
         // Save sender SP to O5_savedSP.
-        new Mov(senderSpRegister, o5).emit(masm);
+        masm.mov(senderSpRegister, o5);
 
-        new Neg(frameSizeRegister).emit(masm);
-        new Save(sp, frameSizeRegister, sp).emit(masm);
+        masm.neg(frameSizeRegister);
+        masm.save(sp, frameSizeRegister, sp);
 
-        new Mov(i0, o0).emit(masm);
-        new Mov(i1, o1).emit(masm);
-        new Mov(i2, o2).emit(masm);
-        new Mov(i3, o3).emit(masm);
-        new Mov(i4, o4).emit(masm);
+        masm.mov(i0, o0);
+        masm.mov(i1, o1);
+        masm.mov(i2, o2);
+        masm.mov(i3, o3);
+        masm.mov(i4, o4);
 
         // NOTE: Don't touch I5 as it contains valuable saved SP!
 
         // Move frame's new PC into i7
-        new Mov(framePcRegister, i7).emit(masm);
+        masm.mov(framePcRegister, i7);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotSafepointOp.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotSafepointOp.java	Tue Mar 03 17:13:51 2015 -0800
@@ -27,7 +27,6 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId;
@@ -67,7 +66,7 @@
         new Setx(config.safepointPollingAddress, scratch).emit(masm);
         MarkId.recordMark(crb, atReturn ? MarkId.POLL_RETURN_FAR : MarkId.POLL_FAR);
         final int pos = masm.position();
-        new Ldx(new SPARCAddress(scratch, 0), g0).emit(masm);
+        masm.ldx(new SPARCAddress(scratch, 0), g0);
         if (state != null) {
             crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
         }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java	Tue Mar 03 17:13:51 2015 -0800
@@ -28,9 +28,7 @@
 import static com.oracle.graal.sparc.SPARC.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov;
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
@@ -54,7 +52,7 @@
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         // This Frame is left but the called unwind (which is sibling) method needs the exception as
         // input in i0
-        new Mov(o0, i0).emit(masm);
+        masm.mov(o0, i0);
         leaveFrame(crb);
 
         ForeignCallLinkage linkage = crb.foreignCalls.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER);
@@ -64,7 +62,7 @@
 
         // Get return address (is in o7 after leave).
         Register returnAddress = asRegister(cc.getArgument(1));
-        new Add(o7, Return.PC_RETURN_OFFSET, returnAddress).emit(masm);
+        masm.add(o7, SPARCAssembler.PC_RETURN_OFFSET, returnAddress);
         Register scratch = g5;
         SPARCCall.indirectJmp(crb, masm, scratch, linkage);
     }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCPrefetchOp.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCPrefetchOp.java	Tue Mar 03 17:13:51 2015 -0800
@@ -25,7 +25,6 @@
 
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
-import com.oracle.graal.asm.sparc.SPARCAssembler.Prefetch;
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
@@ -45,7 +44,7 @@
 
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-        assert instr >= 0 && instr < Prefetch.Fcn.values().length : instr;
-        new Prefetch(address.toAddress(), Prefetch.Fcn.values()[instr]).emit(masm);
+        assert instr >= 0 && instr < SPARCAssembler.Fcn.values().length : instr;
+        masm.prefetch(address.toAddress(), SPARCAssembler.Fcn.values()[instr]);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Tue Mar 03 17:13:51 2015 -0800
@@ -172,7 +172,7 @@
         EventProvider eventProvider = Graal.getRequiredCapability(EventProvider.class);
         CompilationEvent compilationEvent = eventProvider.newCompilationEvent();
 
-        try (TimerCloseable a = CompilationTime.start()) {
+        try (DebugCloseable a = CompilationTime.start()) {
             // If there is already compiled code for this method on our level we simply return.
             // Graal compiles are always at the highest compile level, even in non-tiered mode so we
             // only need to check for that value.
@@ -259,7 +259,7 @@
                 }
             }
 
-            try (TimerCloseable b = CodeInstallationTime.start()) {
+            try (DebugCloseable b = CodeInstallationTime.start()) {
                 installedCode = (HotSpotInstalledCode) installMethod(result);
                 if (!isOSR) {
                     ProfilingInfo profile = method.getProfilingInfo();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java	Tue Mar 03 17:13:51 2015 -0800
@@ -26,7 +26,6 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.lir.*;
 import com.oracle.graal.nodes.*;
 
 /**
@@ -46,25 +45,20 @@
     }
 
     @Override
-    protected JavaValue computeLockValue(FrameState state, int lockIndex) {
+    protected Value computeLockValue(FrameState state, int lockIndex) {
         int lockDepth = lockIndex;
         if (state.outerFrameState() != null) {
             lockDepth += state.outerFrameState().nestedLockDepth();
         }
         StackSlotValue slot = lockStack.makeLockSlot(lockDepth);
         ValueNode lock = state.lockAt(lockIndex);
-        JavaValue object = toValue(lock);
+        Value object = toValue(lock);
         boolean eliminated = object instanceof VirtualObject && state.monitorIdAt(lockIndex) != null;
         assert state.monitorIdAt(lockIndex) == null || state.monitorIdAt(lockIndex).getLockDepth() == lockDepth;
         return new StackLockValue(object, slot, eliminated);
     }
 
     @Override
-    protected LIRFrameState newLIRFrameState(LabelRef exceptionEdge, BytecodeFrame frame, VirtualObject[] virtualObjectsArray) {
-        return new HotSpotLIRFrameState(frame, virtualObjectsArray, exceptionEdge);
-    }
-
-    @Override
     protected BytecodeFrame computeFrameForState(FrameState state) {
         assert state.bci >= 0 || state.bci == BytecodeFrame.BEFORE_BCI : state.bci;
         return super.computeFrameForState(state);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java	Tue Mar 03 17:11:46 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot;
-
-import static com.oracle.graal.api.code.ValueUtil.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.OperandMode;
-
-/**
- * Extends {@link LIRFrameState} to handle {@link StackLockValue}s correctly.
- */
-class HotSpotLIRFrameState extends LIRFrameState {
-
-    public HotSpotLIRFrameState(BytecodeFrame topFrame, VirtualObject[] virtualObjects, LabelRef exceptionEdge) {
-        super(topFrame, virtualObjects, exceptionEdge);
-    }
-
-    @Override
-    protected Value processValue(LIRInstruction inst, InstructionValueProcedure proc, Value value) {
-        if (value instanceof StackLockValue) {
-            StackLockValue monitor = (StackLockValue) value;
-            if (monitor.getOwner() instanceof Value) {
-                Value owner = (Value) monitor.getOwner();
-                if (processed(owner)) {
-                    monitor.setOwner((JavaValue) proc.doValue(inst, owner, OperandMode.ALIVE, STATE_FLAGS));
-                }
-            }
-            Value slot = monitor.getSlot();
-            if (isVirtualStackSlot(slot) && processed(slot)) {
-                monitor.setSlot(asStackSlotValue(proc.doValue(inst, slot, OperandMode.ALIVE, STATE_FLAGS)));
-            }
-            return value;
-        } else {
-            return super.processValue(inst, proc, value);
-        }
-    }
-}
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Tue Mar 03 17:13:51 2015 -0800
@@ -24,18 +24,24 @@
 
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+import static com.oracle.graal.sparc.SPARC.*;
+import static com.oracle.graal.sparc.SPARC.CPUFeature.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.gen.*;
-import com.oracle.graal.sparc.SPARC.CPUFeature;
 import com.oracle.graal.sparc.*;
 
 public enum SPARCArithmetic {
@@ -211,24 +217,24 @@
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             Label noOverflow = new Label();
-            new Mulx(asLongReg(x), asLongReg(y), asLongReg(result)).emit(masm);
+            masm.mulx(asLongReg(x), asLongReg(y), asLongReg(result));
 
             // Calculate the upper 64 bit signed := (umulxhi product - (x{63}&y + y{63}&x))
-            new Umulxhi(asLongReg(x), asLongReg(y), asLongReg(scratch1)).emit(masm);
-            new Srax(asLongReg(x), 63, asLongReg(scratch2)).emit(masm);
-            new And(asLongReg(scratch2), asLongReg(y), asLongReg(scratch2)).emit(masm);
-            new Sub(asLongReg(scratch1), asLongReg(scratch2), asLongReg(scratch1)).emit(masm);
+            masm.umulxhi(asLongReg(x), asLongReg(y), asLongReg(scratch1));
+            masm.srax(asLongReg(x), 63, asLongReg(scratch2));
+            masm.and(asLongReg(scratch2), asLongReg(y), asLongReg(scratch2));
+            masm.sub(asLongReg(scratch1), asLongReg(scratch2), asLongReg(scratch1));
 
-            new Srax(asLongReg(y), 63, asLongReg(scratch2)).emit(masm);
-            new And(asLongReg(scratch2), asLongReg(x), asLongReg(scratch2)).emit(masm);
-            new Sub(asLongReg(scratch1), asLongReg(scratch2), asLongReg(scratch1)).emit(masm);
+            masm.srax(asLongReg(y), 63, asLongReg(scratch2));
+            masm.and(asLongReg(scratch2), asLongReg(x), asLongReg(scratch2));
+            masm.sub(asLongReg(scratch1), asLongReg(scratch2), asLongReg(scratch1));
 
             // Now construct the lower half and compare
-            new Srax(asLongReg(result), 63, asLongReg(scratch2)).emit(masm);
-            new Cmp(asLongReg(scratch1), asLongReg(scratch2)).emit(masm);
-            new Bpe(CC.Xcc, false, true, noOverflow).emit(masm);
-            new Nop().emit(masm);
-            new Wrccr(SPARC.g0, 1 << (CCR_XCC_SHIFT + CCR_V_SHIFT)).emit(masm);
+            masm.srax(asLongReg(result), 63, asLongReg(scratch2));
+            masm.cmp(asLongReg(scratch1), asLongReg(scratch2));
+            masm.bpcc(Equal, NOT_ANNUL, noOverflow, Xcc, PREDICT_TAKEN);
+            masm.nop();
+            masm.wrccr(g0, 1 << (CCR_XCC_SHIFT + CCR_V_SHIFT));
             masm.bind(noOverflow);
         }
     }
@@ -241,86 +247,86 @@
         delaySlotLir.emitControlTransfer(crb, masm);
         switch (opcode) {
             case IADD:
-                new Add(asIntReg(src1), constant, asIntReg(dst)).emit(masm);
+                masm.add(asIntReg(src1), constant, asIntReg(dst));
                 break;
             case IADDCC:
-                new Addcc(asIntReg(src1), constant, asIntReg(dst)).emit(masm);
+                masm.addcc(asIntReg(src1), constant, asIntReg(dst));
                 break;
             case ISUB:
-                new Sub(asIntReg(src1), constant, asIntReg(dst)).emit(masm);
+                masm.sub(asIntReg(src1), constant, asIntReg(dst));
                 break;
             case ISUBCC:
-                new Subcc(asIntReg(src1), constant, asIntReg(dst)).emit(masm);
+                masm.subcc(asIntReg(src1), constant, asIntReg(dst));
                 break;
             case IMUL:
-                new Mulx(asIntReg(src1), constant, asIntReg(dst)).emit(masm);
+                masm.mulx(asIntReg(src1), constant, asIntReg(dst));
                 break;
             case IMULCC:
                 throw GraalInternalError.unimplemented();
             case IDIV:
-                new Sdivx(asIntReg(src1), constant, asIntReg(dst)).emit(masm);
+                masm.sdivx(asIntReg(src1), constant, asIntReg(dst));
                 break;
             case IUDIV:
-                new Udivx(asIntReg(src1), constant, asIntReg(dst)).emit(masm);
+                masm.udivx(asIntReg(src1), constant, asIntReg(dst));
                 break;
             case IAND:
-                new And(asIntReg(src1), constant, asIntReg(dst)).emit(masm);
+                masm.and(asIntReg(src1), constant, asIntReg(dst));
                 break;
             case ISHL:
-                new Sll(asIntReg(src1), constant, asIntReg(dst)).emit(masm);
+                masm.sll(asIntReg(src1), constant, asIntReg(dst));
                 break;
             case ISHR:
-                new Sra(asIntReg(src1), constant, asIntReg(dst)).emit(masm);
+                masm.sra(asIntReg(src1), constant, asIntReg(dst));
                 break;
             case IUSHR:
-                new Srl(asIntReg(src1), constant, asIntReg(dst)).emit(masm);
+                masm.srl(asIntReg(src1), constant, asIntReg(dst));
                 break;
             case IOR:
-                new Or(asIntReg(src1), constant, asIntReg(dst)).emit(masm);
+                masm.or(asIntReg(src1), constant, asIntReg(dst));
                 break;
             case IXOR:
-                new Xor(asIntReg(src1), constant, asIntReg(dst)).emit(masm);
+                masm.xor(asIntReg(src1), constant, asIntReg(dst));
                 break;
             case LADD:
-                new Add(asLongReg(src1), constant, asLongReg(dst)).emit(masm);
+                masm.add(asLongReg(src1), constant, asLongReg(dst));
                 break;
             case LADDCC:
-                new Addcc(asLongReg(src1), constant, asLongReg(dst)).emit(masm);
+                masm.addcc(asLongReg(src1), constant, asLongReg(dst));
                 break;
             case LSUB:
-                new Sub(asLongReg(src1), constant, asLongReg(dst)).emit(masm);
+                masm.sub(asLongReg(src1), constant, asLongReg(dst));
                 break;
             case LSUBCC:
-                new Subcc(asLongReg(src1), constant, asLongReg(dst)).emit(masm);
+                masm.subcc(asLongReg(src1), constant, asLongReg(dst));
                 break;
             case LMUL:
-                new Mulx(asLongReg(src1), constant, asLongReg(dst)).emit(masm);
+                masm.mulx(asLongReg(src1), constant, asLongReg(dst));
                 break;
             case LDIV:
                 exceptionOffset = masm.position();
-                new Sdivx(asLongReg(src1), constant, asLongReg(dst)).emit(masm);
+                masm.sdivx(asLongReg(src1), constant, asLongReg(dst));
                 break;
             case LUDIV:
                 exceptionOffset = masm.position();
-                new Udivx(asLongReg(src1), constant, asLongReg(dst)).emit(masm);
+                masm.udivx(asLongReg(src1), constant, asLongReg(dst));
                 break;
             case LAND:
-                new And(asLongReg(src1), constant, asLongReg(dst)).emit(masm);
+                masm.and(asLongReg(src1), constant, asLongReg(dst));
                 break;
             case LOR:
-                new Or(asLongReg(src1), constant, asLongReg(dst)).emit(masm);
+                masm.or(asLongReg(src1), constant, asLongReg(dst));
                 break;
             case LXOR:
-                new Xor(asLongReg(src1), constant, asLongReg(dst)).emit(masm);
+                masm.xor(asLongReg(src1), constant, asLongReg(dst));
                 break;
             case LSHL:
-                new Sllx(asLongReg(src1), constant, asLongReg(dst)).emit(masm);
+                masm.sllx(asLongReg(src1), constant, asLongReg(dst));
                 break;
             case LSHR:
-                new Srax(asLongReg(src1), constant, asLongReg(dst)).emit(masm);
+                masm.srax(asLongReg(src1), constant, asLongReg(dst));
                 break;
             case LUSHR:
-                new Srlx(asLongReg(src1), constant, asLongReg(dst)).emit(masm);
+                masm.srlx(asLongReg(src1), constant, asLongReg(dst));
                 break;
             case DAND: // Has no constant implementation in SPARC
             case FADD:
@@ -346,185 +352,185 @@
         switch (opcode) {
             case IADD:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Add(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
+                masm.add(asIntReg(src1), asIntReg(src2), asIntReg(dst));
                 break;
             case IADDCC:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Addcc(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
+                masm.addcc(asIntReg(src1), asIntReg(src2), asIntReg(dst));
                 break;
             case ISUB:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Sub(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
+                masm.sub(asIntReg(src1), asIntReg(src2), asIntReg(dst));
                 break;
             case ISUBCC:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Subcc(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
+                masm.subcc(asIntReg(src1), asIntReg(src2), asIntReg(dst));
                 break;
             case IMUL:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Mulx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
+                masm.mulx(asIntReg(src1), asIntReg(src2), asIntReg(dst));
                 break;
             case IMULCC:
                 try (SPARCScratchRegister tmpScratch = SPARCScratchRegister.get()) {
                     Register tmp = tmpScratch.getRegister();
-                    new Mulx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
+                    masm.mulx(asIntReg(src1), asIntReg(src2), asIntReg(dst));
                     Label noOverflow = new Label();
-                    new Sra(asIntReg(dst), 0, tmp).emit(masm);
-                    new Xorcc(SPARC.g0, SPARC.g0, SPARC.g0).emit(masm);
-                    if (masm.hasFeature(CPUFeature.CBCOND)) {
-                        new CBcondx(ConditionFlag.Equal, tmp, asIntReg(dst), noOverflow).emit(masm);
+                    masm.sra(asIntReg(dst), 0, tmp);
+                    masm.xorcc(SPARC.g0, SPARC.g0, SPARC.g0);
+                    if (masm.hasFeature(CBCOND)) {
+                        masm.cbcondx(Equal, tmp, asIntReg(dst), noOverflow);
                         // Is necessary, otherwise we will have a penalty of 5 cycles in S3
-                        new Nop().emit(masm);
+                        masm.nop();
                     } else {
-                        new Cmp(tmp, asIntReg(dst)).emit(masm);
-                        new Bpe(CC.Xcc, noOverflow).emit(masm);
-                        new Nop().emit(masm);
+                        masm.cmp(tmp, asIntReg(dst));
+                        masm.bpcc(Equal, NOT_ANNUL, noOverflow, Xcc, PREDICT_TAKEN);
+                        masm.nop();
                     }
-                    new Wrccr(SPARC.g0, 1 << (SPARCAssembler.CCR_ICC_SHIFT + SPARCAssembler.CCR_V_SHIFT)).emit(masm);
+                    masm.wrccr(SPARC.g0, 1 << (SPARCAssembler.CCR_ICC_SHIFT + SPARCAssembler.CCR_V_SHIFT));
                     masm.bind(noOverflow);
                 }
                 break;
             case IDIV:
-                new Signx(asIntReg(src1), asIntReg(src1)).emit(masm);
-                new Signx(asIntReg(src2), asIntReg(src2)).emit(masm);
+                masm.signx(asIntReg(src1), asIntReg(src1));
+                masm.signx(asIntReg(src2), asIntReg(src2));
                 delaySlotLir.emitControlTransfer(crb, masm);
                 exceptionOffset = masm.position();
-                new Sdivx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
+                masm.sdivx(asIntReg(src1), asIntReg(src2), asIntReg(dst));
                 break;
             case IUDIV:
-                new Signx(asIntReg(src1), asIntReg(src1)).emit(masm);
-                new Signx(asIntReg(src2), asIntReg(src2)).emit(masm);
+                masm.signx(asIntReg(src1), asIntReg(src1));
+                masm.signx(asIntReg(src2), asIntReg(src2));
                 delaySlotLir.emitControlTransfer(crb, masm);
                 exceptionOffset = masm.position();
-                new Udivx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
+                masm.udivx(asIntReg(src1), asIntReg(src2), asIntReg(dst));
                 break;
             case IAND:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new And(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
+                masm.and(asIntReg(src1), asIntReg(src2), asIntReg(dst));
                 break;
             case IOR:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Or(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
+                masm.or(asIntReg(src1), asIntReg(src2), asIntReg(dst));
                 break;
             case IXOR:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Xor(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
+                masm.xor(asIntReg(src1), asIntReg(src2), asIntReg(dst));
                 break;
             case ISHL:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Sll(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
+                masm.sll(asIntReg(src1), asIntReg(src2), asIntReg(dst));
                 break;
             case ISHR:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Sra(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
+                masm.sra(asIntReg(src1), asIntReg(src2), asIntReg(dst));
                 break;
             case IUSHR:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Srl(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
+                masm.srl(asIntReg(src1), asIntReg(src2), asIntReg(dst));
                 break;
             case IREM:
                 throw GraalInternalError.unimplemented();
             case LADD:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Add(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
+                masm.add(asLongReg(src1), asLongReg(src2), asLongReg(dst));
                 break;
             case LADDCC:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Addcc(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
+                masm.addcc(asLongReg(src1), asLongReg(src2), asLongReg(dst));
                 break;
             case LSUB:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Sub(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
+                masm.sub(asLongReg(src1), asLongReg(src2), asLongReg(dst));
                 break;
             case LSUBCC:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Subcc(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
+                masm.subcc(asLongReg(src1), asLongReg(src2), asLongReg(dst));
                 break;
             case LMUL:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Mulx(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
+                masm.mulx(asLongReg(src1), asLongReg(src2), asLongReg(dst));
                 break;
             case LMULCC:
                 throw GraalInternalError.unimplemented();
             case LDIV:
                 delaySlotLir.emitControlTransfer(crb, masm);
                 exceptionOffset = masm.position();
-                new Sdivx(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
+                masm.sdivx(asLongReg(src1), asLongReg(src2), asLongReg(dst));
                 break;
             case LUDIV:
                 delaySlotLir.emitControlTransfer(crb, masm);
                 exceptionOffset = masm.position();
-                new Udivx(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
+                masm.udivx(asLongReg(src1), asLongReg(src2), asLongReg(dst));
                 break;
             case LAND:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new And(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
+                masm.and(asLongReg(src1), asLongReg(src2), asLongReg(dst));
                 break;
             case LOR:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Or(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
+                masm.or(asLongReg(src1), asLongReg(src2), asLongReg(dst));
                 break;
             case LXOR:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Xor(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
+                masm.xor(asLongReg(src1), asLongReg(src2), asLongReg(dst));
                 break;
             case LSHL:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Sllx(asLongReg(src1), asIntReg(src2), asLongReg(dst)).emit(masm);
+                masm.sllx(asLongReg(src1), asIntReg(src2), asLongReg(dst));
                 break;
             case LSHR:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Srax(asLongReg(src1), asIntReg(src2), asLongReg(dst)).emit(masm);
+                masm.srax(asLongReg(src1), asIntReg(src2), asLongReg(dst));
                 break;
             case LUSHR:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Srlx(asLongReg(src1), asIntReg(src2), asLongReg(dst)).emit(masm);
+                masm.srlx(asLongReg(src1), asIntReg(src2), asLongReg(dst));
                 break;
             case FADD:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Fadds(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm);
+                masm.fadds(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst));
                 break;
             case FSUB:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Fsubs(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm);
+                masm.fsubs(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst));
                 break;
             case FMUL:
                 delaySlotLir.emitControlTransfer(crb, masm);
                 if (dst.getPlatformKind() == Kind.Double) {
-                    new Fsmuld(asFloatReg(src1), asFloatReg(src2), asDoubleReg(dst)).emit(masm);
+                    masm.fsmuld(asFloatReg(src1), asFloatReg(src2), asDoubleReg(dst));
                 } else if (dst.getPlatformKind() == Kind.Float) {
-                    new Fmuls(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm);
+                    masm.fmuls(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst));
                 }
                 break;
             case FDIV:
                 delaySlotLir.emitControlTransfer(crb, masm);
                 exceptionOffset = masm.position();
-                new Fdivs(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm);
+                masm.fdivs(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst));
                 break;
             case FREM:
                 throw GraalInternalError.unimplemented();
             case DADD:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Faddd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)).emit(masm);
+                masm.faddd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst));
                 break;
             case DSUB:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Fsubd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)).emit(masm);
+                masm.fsubd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst));
                 break;
             case DMUL:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Fmuld(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)).emit(masm);
+                masm.fmuld(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst));
                 break;
             case DDIV:
                 delaySlotLir.emitControlTransfer(crb, masm);
                 exceptionOffset = masm.position();
-                new Fdivd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)).emit(masm);
+                masm.fdivd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst));
                 break;
             case DREM:
                 throw GraalInternalError.unimplemented();
             case DAND:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Fandd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)).emit(masm);
+                masm.fandd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst));
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
@@ -545,26 +551,26 @@
             assert !src2.equals(scratch1);
             switch (opcode) {
                 case IREM:
-                    new Sra(asIntReg(src1), 0, asIntReg(dst)).emit(masm);
+                    masm.sra(asIntReg(src1), 0, asIntReg(dst));
                     exceptionOffset = masm.position();
-                    new Sdivx(asIntReg(dst), crb.asIntConst(src2), asIntReg(scratch1)).emit(masm);
-                    new Mulx(asIntReg(scratch1), crb.asIntConst(src2), asIntReg(scratch2)).emit(masm);
+                    masm.sdivx(asIntReg(dst), crb.asIntConst(src2), asIntReg(scratch1));
+                    masm.mulx(asIntReg(scratch1), crb.asIntConst(src2), asIntReg(scratch2));
                     delaySlotLir.emitControlTransfer(crb, masm);
-                    new Sub(asIntReg(dst), asIntReg(scratch2), asIntReg(dst)).emit(masm);
+                    masm.sub(asIntReg(dst), asIntReg(scratch2), asIntReg(dst));
                     break;
                 case LREM:
                     exceptionOffset = masm.position();
-                    new Sdivx(asLongReg(src1), crb.asIntConst(src2), asLongReg(scratch1)).emit(masm);
-                    new Mulx(asLongReg(scratch1), crb.asIntConst(src2), asLongReg(scratch2)).emit(masm);
+                    masm.sdivx(asLongReg(src1), crb.asIntConst(src2), asLongReg(scratch1));
+                    masm.mulx(asLongReg(scratch1), crb.asIntConst(src2), asLongReg(scratch2));
                     delaySlotLir.emitControlTransfer(crb, masm);
-                    new Sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst)).emit(masm);
+                    masm.sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst));
                     break;
                 case LUREM:
                     exceptionOffset = masm.position();
-                    new Udivx(asLongReg(src1), crb.asIntConst(src2), asLongReg(scratch1)).emit(masm);
-                    new Mulx(asLongReg(scratch1), crb.asIntConst(src2), asLongReg(scratch2)).emit(masm);
+                    masm.udivx(asLongReg(src1), crb.asIntConst(src2), asLongReg(scratch1));
+                    masm.mulx(asLongReg(scratch1), crb.asIntConst(src2), asLongReg(scratch2));
                     delaySlotLir.emitControlTransfer(crb, masm);
-                    new Sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst)).emit(masm);
+                    masm.sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst));
                     break;
                 case IUREM:
                     GraalInternalError.unimplemented();
@@ -584,10 +590,10 @@
                     assert !asLongReg(src2).equals(asLongReg(scratch1));
                     // But src2 can be scratch2
                     exceptionOffset = masm.position();
-                    new Sdivx(asLongReg(srcLeft), asLongReg(src2), asLongReg(scratch1)).emit(masm);
-                    new Mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch1)).emit(masm);
+                    masm.sdivx(asLongReg(srcLeft), asLongReg(src2), asLongReg(scratch1));
+                    masm.mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch1));
                     delaySlotLir.emitControlTransfer(crb, masm);
-                    new Sub(asLongReg(srcLeft), asLongReg(scratch1), asLongReg(dst)).emit(masm);
+                    masm.sub(asLongReg(srcLeft), asLongReg(scratch1), asLongReg(dst));
                     break;
                 case LUREM:
                     if (isConstant(src1)) {
@@ -597,10 +603,10 @@
                     assert !asLongReg(srcLeft).equals(asLongReg(scratch1));
                     assert !asLongReg(src2).equals(asLongReg(scratch1));
                     exceptionOffset = masm.position();
-                    new Udivx(asLongReg(srcLeft), asLongReg(src2), asLongReg(scratch1)).emit(masm);
-                    new Mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch1)).emit(masm);
+                    masm.udivx(asLongReg(srcLeft), asLongReg(src2), asLongReg(scratch1));
+                    masm.mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch1));
                     delaySlotLir.emitControlTransfer(crb, masm);
-                    new Sub(asLongReg(srcLeft), asLongReg(scratch1), asLongReg(dst)).emit(masm);
+                    masm.sub(asLongReg(srcLeft), asLongReg(scratch1), asLongReg(dst));
                     break;
                 case IREM:
                     if (isConstant(src1)) {
@@ -609,24 +615,24 @@
                     }
                     assert !asIntReg(srcLeft).equals(asIntReg(scratch1));
                     assert !asIntReg(src2).equals(asIntReg(scratch1));
-                    new Sra(asIntReg(src1), 0, asIntReg(scratch1)).emit(masm);
-                    new Sra(asIntReg(src2), 0, asIntReg(scratch2)).emit(masm);
+                    masm.sra(asIntReg(src1), 0, asIntReg(scratch1));
+                    masm.sra(asIntReg(src2), 0, asIntReg(scratch2));
                     exceptionOffset = masm.position();
-                    new Sdivx(asIntReg(scratch1), asIntReg(scratch2), asIntReg(dst)).emit(masm);
-                    new Mulx(asIntReg(dst), asIntReg(scratch2), asIntReg(dst)).emit(masm);
+                    masm.sdivx(asIntReg(scratch1), asIntReg(scratch2), asIntReg(dst));
+                    masm.mulx(asIntReg(dst), asIntReg(scratch2), asIntReg(dst));
                     delaySlotLir.emitControlTransfer(crb, masm);
-                    new Sub(asIntReg(scratch1), asIntReg(dst), asIntReg(dst)).emit(masm);
+                    masm.sub(asIntReg(scratch1), asIntReg(dst), asIntReg(dst));
                     break;
                 case IUREM:
                     assert !asIntReg(dst).equals(asIntReg(scratch1));
                     assert !asIntReg(dst).equals(asIntReg(scratch2));
-                    new Srl(asIntReg(src1), 0, asIntReg(scratch1)).emit(masm);
-                    new Srl(asIntReg(src2), 0, asIntReg(dst)).emit(masm);
+                    masm.srl(asIntReg(src1), 0, asIntReg(scratch1));
+                    masm.srl(asIntReg(src2), 0, asIntReg(dst));
                     exceptionOffset = masm.position();
-                    new Udivx(asIntReg(scratch1), asIntReg(dst), asIntReg(scratch2)).emit(masm);
-                    new Mulx(asIntReg(scratch2), asIntReg(dst), asIntReg(dst)).emit(masm);
+                    masm.udivx(asIntReg(scratch1), asIntReg(dst), asIntReg(scratch2));
+                    masm.mulx(asIntReg(scratch2), asIntReg(dst), asIntReg(dst));
                     delaySlotLir.emitControlTransfer(crb, masm);
-                    new Sub(asIntReg(scratch1), asIntReg(dst), asIntReg(dst)).emit(masm);
+                    masm.sub(asIntReg(scratch1), asIntReg(dst), asIntReg(dst));
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
@@ -646,110 +652,110 @@
         switch (opcode) {
             case INEG:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Neg(asIntReg(src), asIntReg(dst)).emit(masm);
+                masm.neg(asIntReg(src), asIntReg(dst));
                 break;
             case LNEG:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Neg(asLongReg(src), asLongReg(dst)).emit(masm);
+                masm.neg(asLongReg(src), asLongReg(dst));
                 break;
             case INOT:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Not(asIntReg(src), asIntReg(dst)).emit(masm);
+                masm.not(asIntReg(src), asIntReg(dst));
                 break;
             case LNOT:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Not(asLongReg(src), asLongReg(dst)).emit(masm);
+                masm.not(asLongReg(src), asLongReg(dst));
                 break;
             case D2F:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Fdtos(asDoubleReg(src), asFloatReg(dst)).emit(masm);
+                masm.fdtos(asDoubleReg(src), asFloatReg(dst));
                 break;
             case L2D:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Fxtod(asDoubleReg(src), asDoubleReg(dst)).emit(masm);
+                masm.fxtod(asDoubleReg(src), asDoubleReg(dst));
                 break;
             case L2F:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Fxtos(asDoubleReg(src), asFloatReg(dst)).emit(masm);
+                masm.fxtos(asDoubleReg(src), asFloatReg(dst));
                 break;
             case I2D:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Fitod(asFloatReg(src), asDoubleReg(dst)).emit(masm);
+                masm.fitod(asFloatReg(src), asDoubleReg(dst));
                 break;
             case I2L:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Signx(asIntReg(src), asLongReg(dst)).emit(masm);
+                masm.signx(asIntReg(src), asLongReg(dst));
                 break;
             case L2I:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Signx(asLongReg(src), asIntReg(dst)).emit(masm);
+                masm.signx(asLongReg(src), asIntReg(dst));
                 break;
             case B2L:
-                new Sll(asIntReg(src), 24, asLongReg(dst)).emit(masm);
+                masm.sll(asIntReg(src), 24, asLongReg(dst));
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Sra(asLongReg(dst), 24, asLongReg(dst)).emit(masm);
+                masm.sra(asLongReg(dst), 24, asLongReg(dst));
                 break;
             case B2I:
-                new Sll(asIntReg(src), 24, asIntReg(dst)).emit(masm);
+                masm.sll(asIntReg(src), 24, asIntReg(dst));
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Sra(asIntReg(dst), 24, asIntReg(dst)).emit(masm);
+                masm.sra(asIntReg(dst), 24, asIntReg(dst));
                 break;
             case S2L:
-                new Sll(asIntReg(src), 16, asLongReg(dst)).emit(masm);
+                masm.sll(asIntReg(src), 16, asLongReg(dst));
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Sra(asLongReg(dst), 16, asLongReg(dst)).emit(masm);
+                masm.sra(asLongReg(dst), 16, asLongReg(dst));
                 break;
             case S2I:
-                new Sll(asIntReg(src), 16, asIntReg(dst)).emit(masm);
+                masm.sll(asIntReg(src), 16, asIntReg(dst));
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Sra(asIntReg(dst), 16, asIntReg(dst)).emit(masm);
+                masm.sra(asIntReg(dst), 16, asIntReg(dst));
                 break;
             case I2F:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Fitos(asFloatReg(src), asFloatReg(dst)).emit(masm);
+                masm.fitos(asFloatReg(src), asFloatReg(dst));
                 break;
             case F2D:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Fstod(asFloatReg(src), asDoubleReg(dst)).emit(masm);
+                masm.fstod(asFloatReg(src), asDoubleReg(dst));
                 break;
             case F2L:
-                new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(src), asFloatReg(src)).emit(masm);
-                new Fbo(true, notOrdered).emit(masm);
-                new Fstox(asFloatReg(src), asDoubleReg(dst)).emit(masm);
-                new Fsubd(asDoubleReg(dst), asDoubleReg(dst), asDoubleReg(dst)).emit(masm);
+                masm.fcmp(Fcc0, Fcmps, asFloatReg(src), asFloatReg(src));
+                masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN);
+                masm.fstox(asFloatReg(src), asDoubleReg(dst));
+                masm.fsubd(asDoubleReg(dst), asDoubleReg(dst), asDoubleReg(dst));
                 masm.bind(notOrdered);
                 break;
             case F2I:
-                new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(src), asFloatReg(src)).emit(masm);
-                new Fbo(true, notOrdered).emit(masm);
-                new Fstoi(asFloatReg(src), asFloatReg(dst)).emit(masm);
-                new Fitos(asFloatReg(dst), asFloatReg(dst)).emit(masm);
-                new Fsubs(asFloatReg(dst), asFloatReg(dst), asFloatReg(dst)).emit(masm);
+                masm.fcmp(Fcc0, Fcmps, asFloatReg(src), asFloatReg(src));
+                masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN);
+                masm.fstoi(asFloatReg(src), asFloatReg(dst));
+                masm.fitos(asFloatReg(dst), asFloatReg(dst));
+                masm.fsubs(asFloatReg(dst), asFloatReg(dst), asFloatReg(dst));
                 masm.bind(notOrdered);
                 break;
             case D2L:
-                new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(src), asDoubleReg(src)).emit(masm);
-                new Fbo(false, notOrdered).emit(masm);
-                new Fdtox(asDoubleReg(src), asDoubleReg(dst)).emit(masm);
-                new Fxtod(asDoubleReg(dst), asDoubleReg(dst)).emit(masm);
-                new Fsubd(asDoubleReg(dst), asDoubleReg(dst), asDoubleReg(dst)).emit(masm);
+                masm.fcmp(Fcc0, Fcmpd, asDoubleReg(src), asDoubleReg(src));
+                masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN);
+                masm.fdtox(asDoubleReg(src), asDoubleReg(dst));
+                masm.fxtod(asDoubleReg(dst), asDoubleReg(dst));
+                masm.fsubd(asDoubleReg(dst), asDoubleReg(dst), asDoubleReg(dst));
                 masm.bind(notOrdered);
                 break;
             case D2I:
-                new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(src), asDoubleReg(src)).emit(masm);
-                new Fbo(true, notOrdered).emit(masm);
-                new Fdtoi(asDoubleReg(src), asFloatReg(dst)).emit(masm);
-                new Fsubs(asFloatReg(dst), asFloatReg(dst), asFloatReg(dst)).emit(masm);
-                new Fstoi(asFloatReg(dst), asFloatReg(dst)).emit(masm);
+                masm.fcmp(Fcc0, Fcmpd, asDoubleReg(src), asDoubleReg(src));
+                masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN);
+                masm.fdtoi(asDoubleReg(src), asFloatReg(dst));
+                masm.fsubs(asFloatReg(dst), asFloatReg(dst), asFloatReg(dst));
+                masm.fstoi(asFloatReg(dst), asFloatReg(dst));
                 masm.bind(notOrdered);
                 break;
             case FNEG:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Fnegs(asFloatReg(src), asFloatReg(dst)).emit(masm);
+                masm.fnegs(asFloatReg(src), asFloatReg(dst));
                 break;
             case DNEG:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Fnegd(asDoubleReg(src), asDoubleReg(dst)).emit(masm);
+                masm.fnegd(asDoubleReg(src), asDoubleReg(dst));
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere("missing: " + opcode);
@@ -868,30 +874,30 @@
             assert isRegister(x) && isRegister(y) && isRegister(result) && isRegister(scratch);
             switch (opcode) {
                 case IMUL:
-                    new Mulx(asIntReg(x), asIntReg(y), asIntReg(result)).emit(masm);
-                    new Srax(asIntReg(result), 32, asIntReg(result)).emit(masm);
+                    masm.mulx(asIntReg(x), asIntReg(y), asIntReg(result));
+                    masm.srax(asIntReg(result), 32, asIntReg(result));
                     break;
                 case IUMUL:
                     assert !asIntReg(scratch).equals(asIntReg(result));
-                    new Srl(asIntReg(x), 0, asIntReg(scratch)).emit(masm);
-                    new Srl(asIntReg(y), 0, asIntReg(result)).emit(masm);
-                    new Mulx(asIntReg(result), asIntReg(scratch), asIntReg(result)).emit(masm);
-                    new Srlx(asIntReg(result), 32, asIntReg(result)).emit(masm);
+                    masm.srl(asIntReg(x), 0, asIntReg(scratch));
+                    masm.srl(asIntReg(y), 0, asIntReg(result));
+                    masm.mulx(asIntReg(result), asIntReg(scratch), asIntReg(result));
+                    masm.srlx(asIntReg(result), 32, asIntReg(result));
                     break;
                 case LMUL:
                     assert !asLongReg(scratch).equals(asLongReg(result));
-                    new Umulxhi(asLongReg(x), asLongReg(y), asLongReg(result)).emit(masm);
+                    masm.umulxhi(asLongReg(x), asLongReg(y), asLongReg(result));
 
-                    new Srlx(asLongReg(x), 63, asLongReg(scratch)).emit(masm);
-                    new Mulx(asLongReg(scratch), asLongReg(y), asLongReg(scratch)).emit(masm);
-                    new Sub(asLongReg(result), asLongReg(scratch), asLongReg(result)).emit(masm);
+                    masm.srlx(asLongReg(x), 63, asLongReg(scratch));
+                    masm.mulx(asLongReg(scratch), asLongReg(y), asLongReg(scratch));
+                    masm.sub(asLongReg(result), asLongReg(scratch), asLongReg(result));
 
-                    new Srlx(asLongReg(y), 63, asLongReg(scratch)).emit(masm);
-                    new Mulx(asLongReg(scratch), asLongReg(x), asLongReg(scratch)).emit(masm);
-                    new Sub(asLongReg(result), asLongReg(scratch), asLongReg(result)).emit(masm);
+                    masm.srlx(asLongReg(y), 63, asLongReg(scratch));
+                    masm.mulx(asLongReg(scratch), asLongReg(x), asLongReg(scratch));
+                    masm.sub(asLongReg(result), asLongReg(scratch), asLongReg(result));
                     break;
                 case LUMUL:
-                    new Umulxhi(asLongReg(x), asLongReg(y), asLongReg(result)).emit(masm);
+                    masm.umulxhi(asLongReg(x), asLongReg(y), asLongReg(result));
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java	Tue Mar 03 17:13:51 2015 -0800
@@ -23,11 +23,15 @@
 package com.oracle.graal.lir.sparc;
 
 import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.RCondition.*;
 import static com.oracle.graal.compiler.common.UnsafeAccess.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 import static com.oracle.graal.sparc.SPARC.*;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.*;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*;
+import static com.oracle.graal.sparc.SPARC.CPUFeature.*;
 
 import java.lang.reflect.*;
 
@@ -35,12 +39,12 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop;
+import com.oracle.graal.asm.sparc.SPARCAssembler.CC;
+import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.gen.*;
+import com.oracle.graal.sparc.SPARC.CPUFeature;
 
 /**
  * Emits code which compares two arrays of the same length.
@@ -96,25 +100,25 @@
         Label done = new Label();
 
         // Load array base addresses.
-        new Add(asObjectReg(array1Value), arrayBaseOffset, array1).emit(masm);
-        new Add(asObjectReg(array2Value), arrayBaseOffset, array2).emit(masm);
+        masm.add(asObjectReg(array1Value), arrayBaseOffset, array1);
+        masm.add(asObjectReg(array2Value), arrayBaseOffset, array2);
 
         // Get array length in bytes.
-        new Mulx(asIntReg(lengthValue), arrayIndexScale, length).emit(masm);
-        new Mov(length, result).emit(masm); // copy
+        masm.mulx(asIntReg(lengthValue), arrayIndexScale, length);
+        masm.mov(length, result); // copy
 
         emit8ByteCompare(masm, result, array1, array2, length, trueLabel, falseLabel);
         emitTailCompares(masm, result, array1, array2, trueLabel, falseLabel);
 
         // Return true
         masm.bind(trueLabel);
-        new Mov(1, result).emit(masm);
-        new Bpa(done).emit(masm);
-        new Nop().emit(masm);
+        masm.mov(1, result);
+        masm.bicc(Always, ANNUL, done);
+        masm.nop();
 
         // Return false
         masm.bind(falseLabel);
-        new Mov(g0, result).emit(masm);
+        masm.mov(g0, result);
 
         // That's it
         masm.bind(done);
@@ -138,54 +142,55 @@
 
         boolean hasCBcond = masm.hasFeature(CPUFeature.CBCOND);
 
-        new And(result, VECTOR_SIZE - 1, result).emit(masm); // tail count (in bytes)
-        new Andcc(length, ~(VECTOR_SIZE - 1), length).emit(masm);  // vector count (in bytes)
-        new Bpe(CC.Xcc, compareTail).emit(masm);
+        masm.and(result, VECTOR_SIZE - 1, result); // tail count (in bytes)
+        masm.andcc(length, ~(VECTOR_SIZE - 1), length);  // vector count (in bytes)
+        masm.bpcc(ConditionFlag.Equal, NOT_ANNUL, compareTail, CC.Xcc, PREDICT_NOT_TAKEN);
 
-        new Sub(length, VECTOR_SIZE, length).emit(masm); // Delay slot
-        new Add(array1, length, array1).emit(masm);
-        new Add(array2, length, array2).emit(masm);
-        new Sub(g0, length, length).emit(masm);
+        masm.sub(length, VECTOR_SIZE, length); // Delay slot
+        masm.add(array1, length, array1);
+        masm.add(array2, length, array2);
+        masm.sub(g0, length, length);
 
         // Compare the last element first
-        new Ldx(new SPARCAddress(array1, 0), tempReg1).emit(masm);
-        new Ldx(new SPARCAddress(array2, 0), tempReg2).emit(masm);
+        masm.ldx(new SPARCAddress(array1, 0), tempReg1);
+        masm.ldx(new SPARCAddress(array2, 0), tempReg2);
         if (hasCBcond) {
-            new CBcondx(ConditionFlag.NotEqual, tempReg1, tempReg2, falseLabel).emit(masm);
-            new Nop().emit(masm); // for optimal performance (see manual)
-            new CBcondx(ConditionFlag.Equal, length, 0, compareTailCorrectVectorEnd).emit(masm);
-            new Nop().emit(masm); // for optimal performance (see manual)
+            masm.cbcondx(NotEqual, tempReg1, tempReg2, falseLabel);
+            masm.nop(); // for optimal performance (see manual)
+            masm.cbcondx(Equal, length, 0, compareTailCorrectVectorEnd);
+            masm.nop(); // for optimal performance (see manual)
         } else {
-            new Cmp(tempReg1, tempReg2).emit(masm);
-            new Bpne(Xcc, true, false, falseLabel).emit(masm);
-            new Nop().emit(masm);
-            new Bpr(RCondition.Rc_z, false, false, length, compareTailCorrectVectorEnd).emit(masm);
-            new Nop().emit(masm);
+            masm.cmp(tempReg1, tempReg2);
+            masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_NOT_TAKEN);
+            masm.nop();
+            masm.bpr(Rc_z, NOT_ANNUL, compareTailCorrectVectorEnd, PREDICT_NOT_TAKEN, length);
+            masm.nop();
         }
 
         // Load the first value from array 1 (Later done in back branch delay-slot)
-        new Ldx(new SPARCAddress(array1, length), tempReg1).emit(masm);
+        masm.ldx(new SPARCAddress(array1, length), tempReg1);
         masm.bind(loop);
-        new Ldx(new SPARCAddress(array2, length), tempReg2).emit(masm);
-        new Cmp(tempReg1, tempReg2).emit(masm);
-        new Bpne(Xcc, false, false, falseLabel).emit(masm);
+        masm.ldx(new SPARCAddress(array2, length), tempReg2);
+        masm.cmp(tempReg1, tempReg2);
+        masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_NOT_TAKEN);
         // Delay slot, not annul, add for next iteration
-        new Addcc(length, VECTOR_SIZE, length).emit(masm);
-        new Bpne(Xcc, true, true, loop).emit(masm); // Annul, to prevent access past the array
-        new Ldx(new SPARCAddress(array1, length), tempReg1).emit(masm); // Load in delay slot
+        masm.addcc(length, VECTOR_SIZE, length);
+        // Annul, to prevent access past the array
+        masm.bpcc(NotEqual, ANNUL, loop, Xcc, PREDICT_TAKEN);
+        masm.ldx(new SPARCAddress(array1, length), tempReg1); // Load in delay slot
 
         // Tail count zero, therefore we can go to the end
         if (hasCBcond) {
-            new CBcondx(ConditionFlag.Equal, result, 0, trueLabel).emit(masm);
+            masm.cbcondx(Equal, result, 0, trueLabel);
         } else {
-            new Bpr(RCondition.Rc_z, true, true, result, trueLabel).emit(masm);
-            new Nop().emit(masm);
+            masm.bpr(Rc_z, NOT_ANNUL, trueLabel, PREDICT_TAKEN, result);
+            masm.nop();
         }
 
         masm.bind(compareTailCorrectVectorEnd);
         // Correct the array pointers
-        new Add(array1, VECTOR_SIZE, array1).emit(masm);
-        new Add(array2, VECTOR_SIZE, array2).emit(masm);
+        masm.add(array1, VECTOR_SIZE, array1);
+        masm.add(array2, VECTOR_SIZE, array2);
 
         masm.bind(compareTail);
     }
@@ -199,82 +204,81 @@
 
         Register tempReg1 = asRegister(temp3);
         Register tempReg2 = asRegister(temp4);
-        boolean hasCBcond = masm.hasFeature(CPUFeature.CBCOND);
+        boolean hasCBcond = masm.hasFeature(CBCOND);
 
         if (kind.getByteCount() <= 4) {
             // Compare trailing 4 bytes, if any.
             if (hasCBcond) {
-                new CBcondx(ConditionFlag.Less, result, 4, compare2Bytes).emit(masm);
+                masm.cbcondx(Less, result, 4, compare2Bytes);
             } else {
-                new Cmp(result, 4).emit(masm);
-                new Bpl(Xcc, false, false, compare2Bytes).emit(masm);
-                new Nop().emit(masm);
+                masm.cmp(result, 4);
+                masm.bpcc(Less, NOT_ANNUL, compare2Bytes, Xcc, PREDICT_NOT_TAKEN);
+                masm.nop();
             }
 
-            new Lduw(new SPARCAddress(array1, 0), tempReg1).emit(masm);
-            new Lduw(new SPARCAddress(array2, 0), tempReg2).emit(masm);
+            masm.lduw(new SPARCAddress(array1, 0), tempReg1);
+            masm.lduw(new SPARCAddress(array2, 0), tempReg2);
 
             if (hasCBcond) {
-                new CBcondx(ConditionFlag.NotEqual, tempReg1, tempReg2, falseLabel).emit(masm);
+                masm.cbcondx(NotEqual, tempReg1, tempReg2, falseLabel);
             } else {
-                new Cmp(tempReg1, tempReg2).emit(masm);
-                new Bpne(Xcc, false, false, falseLabel).emit(masm);
-                new Nop().emit(masm);
+                masm.cmp(tempReg1, tempReg2);
+                masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_NOT_TAKEN);
+                masm.nop();
             }
 
             if (kind.getByteCount() <= 2) {
                 // Move array pointers forward.
-                new Add(array1, 4, array1).emit(masm);
-                new Add(array2, 4, array2).emit(masm);
-                new Sub(result, 4, result).emit(masm);
+                masm.add(array1, 4, array1);
+                masm.add(array2, 4, array2);
+                masm.sub(result, 4, result);
 
                 // Compare trailing 2 bytes, if any.
                 masm.bind(compare2Bytes);
 
                 if (hasCBcond) {
-                    new CBcondx(ConditionFlag.Less, result, 2, compare1Byte).emit(masm);
+                    masm.cbcondx(Less, result, 2, compare1Byte);
                 } else {
-                    new Cmp(result, 2).emit(masm);
-                    new Bpl(Xcc, false, true, compare1Byte).emit(masm);
-                    new Nop().emit(masm);
+                    masm.cmp(result, 2);
+                    masm.bpcc(Less, NOT_ANNUL, compare1Byte, Xcc, PREDICT_TAKEN);
+                    masm.nop();
                 }
 
-                new Lduh(new SPARCAddress(array1, 0), tempReg1).emit(masm);
-                new Lduh(new SPARCAddress(array2, 0), tempReg2).emit(masm);
+                masm.lduh(new SPARCAddress(array1, 0), tempReg1);
+                masm.lduh(new SPARCAddress(array2, 0), tempReg2);
 
                 if (hasCBcond) {
-                    new CBcondx(ConditionFlag.NotEqual, tempReg1, tempReg2, falseLabel).emit(masm);
+                    masm.cbcondx(NotEqual, tempReg1, tempReg2, falseLabel);
                 } else {
-                    new Cmp(tempReg1, tempReg2).emit(masm);
-                    new Bpne(Xcc, false, true, falseLabel).emit(masm);
-                    new Nop().emit(masm);
+                    masm.cmp(tempReg1, tempReg2);
+                    masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_TAKEN);
+                    masm.nop();
                 }
 
                 // The one-byte tail compare is only required for boolean and byte arrays.
                 if (kind.getByteCount() <= 1) {
                     // Move array pointers forward before we compare the last trailing byte.
-                    new Add(array1, 2, array1).emit(masm);
-                    new Add(array2, 2, array2).emit(masm);
-                    new Sub(result, 2, result).emit(masm);
+                    masm.add(array1, 2, array1);
+                    masm.add(array2, 2, array2);
+                    masm.sub(result, 2, result);
 
                     // Compare trailing byte, if any.
                     masm.bind(compare1Byte);
                     if (hasCBcond) {
-                        new CBcondx(ConditionFlag.NotEqual, result, 1, trueLabel).emit(masm);
+                        masm.cbcondx(NotEqual, result, 1, trueLabel);
                     } else {
-                        new Cmp(result, 1).emit(masm);
-                        new Bpne(Xcc, trueLabel).emit(masm);
-                        new Nop().emit(masm);
+                        masm.cmp(result, 1);
+                        masm.bpcc(NotEqual, NOT_ANNUL, trueLabel, Xcc, PREDICT_TAKEN);
+                        masm.nop();
                     }
-                    new Ldub(new SPARCAddress(array1, 0), tempReg1).emit(masm);
-                    new Ldub(new SPARCAddress(array2, 0), tempReg2).emit(masm);
+                    masm.ldub(new SPARCAddress(array1, 0), tempReg1);
+                    masm.ldub(new SPARCAddress(array2, 0), tempReg2);
                     if (hasCBcond) {
-                        // new SPARCAssembler.Ldx(new SPARCAddress(o7, 1), g3).emit(masm);
-                        new CBcondx(ConditionFlag.NotEqual, tempReg1, tempReg2, falseLabel).emit(masm);
+                        masm.cbcondx(NotEqual, tempReg1, tempReg2, falseLabel);
                     } else {
-                        new Cmp(tempReg1, tempReg2).emit(masm);
-                        new Bpne(Xcc, falseLabel).emit(masm);
-                        new Nop().emit(masm);
+                        masm.cmp(tempReg1, tempReg2);
+                        masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_TAKEN);
+                        masm.nop();
                     }
                 } else {
                     masm.bind(compare1Byte);
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Tue Mar 03 17:13:51 2015 -0800
@@ -29,12 +29,6 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Andn;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Or;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Popc;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Srl;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Srlx;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Sub;
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.*;
@@ -73,23 +67,23 @@
             switch (opcode) {
                 case IPOPCNT:
                     // clear upper word for 64 bit POPC
-                    new Srl(src, g0, dst).emit(masm);
-                    new Popc(dst, dst).emit(masm);
+                    masm.srl(src, g0, dst);
+                    masm.popc(dst, dst);
                     break;
                 case LPOPCNT:
-                    new Popc(src, dst).emit(masm);
+                    masm.popc(src, dst);
                     break;
                 case BSF:
                     Kind tkind = input.getKind();
                     if (tkind == Kind.Int) {
-                        new Sub(src, 1, dst).emit(masm);
-                        new Andn(dst, src, dst).emit(masm);
-                        new Srl(dst, g0, dst).emit(masm);
-                        new Popc(dst, dst).emit(masm);
+                        masm.sub(src, 1, dst);
+                        masm.andn(dst, src, dst);
+                        masm.srl(dst, g0, dst);
+                        masm.popc(dst, dst);
                     } else if (tkind == Kind.Long) {
-                        new Sub(src, 1, dst).emit(masm);
-                        new Andn(dst, src, dst).emit(masm);
-                        new Popc(dst, dst).emit(masm);
+                        masm.sub(src, 1, dst);
+                        masm.andn(dst, src, dst);
+                        masm.popc(dst, dst);
                     } else {
                         throw GraalInternalError.shouldNotReachHere("missing: " + tkind);
                     }
@@ -99,19 +93,19 @@
                     assert ikind == Kind.Int;
                     Register tmp = asRegister(scratch);
                     assert !tmp.equals(dst);
-                    new Srl(src, 1, tmp).emit(masm);
-                    new Srl(src, 0, dst).emit(masm);
-                    new Or(dst, tmp, dst).emit(masm);
-                    new Srl(dst, 2, tmp).emit(masm);
-                    new Or(dst, tmp, dst).emit(masm);
-                    new Srl(dst, 4, tmp).emit(masm);
-                    new Or(dst, tmp, dst).emit(masm);
-                    new Srl(dst, 8, tmp).emit(masm);
-                    new Or(dst, tmp, dst).emit(masm);
-                    new Srl(dst, 16, tmp).emit(masm);
-                    new Or(dst, tmp, dst).emit(masm);
-                    new Popc(dst, dst).emit(masm);
-                    new Sub(dst, 1, dst).emit(masm);
+                    masm.srl(src, 1, tmp);
+                    masm.srl(src, 0, dst);
+                    masm.or(dst, tmp, dst);
+                    masm.srl(dst, 2, tmp);
+                    masm.or(dst, tmp, dst);
+                    masm.srl(dst, 4, tmp);
+                    masm.or(dst, tmp, dst);
+                    masm.srl(dst, 8, tmp);
+                    masm.or(dst, tmp, dst);
+                    masm.srl(dst, 16, tmp);
+                    masm.or(dst, tmp, dst);
+                    masm.popc(dst, dst);
+                    masm.sub(dst, 1, dst);
                     break;
                 }
                 case LBSR: {
@@ -119,20 +113,20 @@
                     assert lkind == Kind.Long;
                     Register tmp = asRegister(scratch);
                     assert !tmp.equals(dst);
-                    new Srlx(src, 1, tmp).emit(masm);
-                    new Or(src, tmp, dst).emit(masm);
-                    new Srlx(dst, 2, tmp).emit(masm);
-                    new Or(dst, tmp, dst).emit(masm);
-                    new Srlx(dst, 4, tmp).emit(masm);
-                    new Or(dst, tmp, dst).emit(masm);
-                    new Srlx(dst, 8, tmp).emit(masm);
-                    new Or(dst, tmp, dst).emit(masm);
-                    new Srlx(dst, 16, tmp).emit(masm);
-                    new Or(dst, tmp, dst).emit(masm);
-                    new Srlx(dst, 32, tmp).emit(masm);
-                    new Or(dst, tmp, dst).emit(masm);
-                    new Popc(dst, dst).emit(masm);
-                    new Sub(dst, 1, dst).emit(masm); // This is required to fit the given structure.
+                    masm.srlx(src, 1, tmp);
+                    masm.or(src, tmp, dst);
+                    masm.srlx(dst, 2, tmp);
+                    masm.or(dst, tmp, dst);
+                    masm.srlx(dst, 4, tmp);
+                    masm.or(dst, tmp, dst);
+                    masm.srlx(dst, 8, tmp);
+                    masm.or(dst, tmp, dst);
+                    masm.srlx(dst, 16, tmp);
+                    masm.or(dst, tmp, dst);
+                    masm.srlx(dst, 32, tmp);
+                    masm.or(dst, tmp, dst);
+                    masm.popc(dst, dst);
+                    masm.sub(dst, 1, dst); // This is required to fit the given structure.
                     break;
                 }
                 default:
@@ -142,55 +136,16 @@
         } else if (isConstant(input) && isSimm13(crb.asIntConst(input))) {
             switch (opcode) {
                 case IPOPCNT:
-                    new Popc(crb.asIntConst(input), dst).emit(masm);
+                    masm.popc(crb.asIntConst(input), dst);
                     break;
                 case LPOPCNT:
-                    new Popc(crb.asIntConst(input), dst).emit(masm);
+                    masm.popc(crb.asIntConst(input), dst);
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
             }
         } else {
             throw GraalInternalError.shouldNotReachHere();
-            // SPARCAddress src = (SPARCAddress) crb.asAddress(input);
-            // switch (opcode) {
-            // case IPOPCNT:
-            // new Ldsw(src, tmp).emit(masm);
-            // // clear upper word for 64 bit POPC
-            // new Srl(tmp, g0, dst).emit(masm);
-            // new Popc(tmp, dst).emit(masm);
-            // break;
-            // case LPOPCNT:
-            // new Ldx(src, tmp).emit(masm);
-            // new Popc(tmp, dst).emit(masm);
-            // break;
-            // case BSF:
-            // assert input.getKind() == Kind.Int;
-            // new Ldsw(src, tmp).emit(masm);
-            // new Srl(tmp, 1, tmp).emit(masm);
-            // new Srl(tmp, 0, dst).emit(masm);
-            // new Or(tmp, tmp, dst).emit(masm);
-            // new Srl(dst, 2, tmp).emit(masm);
-            // new Or(dst, tmp, dst).emit(masm);
-            // new Srl(dst, 4, tmp).emit(masm);
-            // new Or(dst, tmp, dst).emit(masm);
-            // new Srl(dst, 8, tmp).emit(masm);
-            // new Or(dst, tmp, dst).emit(masm);
-            // new Srl(dst, 16, tmp).emit(masm);
-            // new Or(dst, tmp, dst).emit(masm);
-            // new Popc(dst, dst).emit(masm);
-            // new Mov(Kind.Int.getBitCount(), tmp).emit(masm);
-            // new Sub(tmp, dst, dst).emit(masm);
-            // break;
-            // case IBSR:
-            // // masm.bsrl(dst, src);
-            // // countLeadingZerosI_bsr masm.bsrq(dst, src);
-            // // masm.bsrl(dst, src);
-            // case LBSR:
-            // // masm.bsrq(dst, src);
-            // default:
-            // throw GraalInternalError.shouldNotReachHere("missing: " + opcode);
-            // }
         }
     }
 
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java	Tue Mar 03 17:13:51 2015 -0800
@@ -25,7 +25,6 @@
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Ta;
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
@@ -54,6 +53,6 @@
 
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-        new Ta(ST_RESERVED_FOR_USER_0).emit(masm);
+        masm.ta(ST_RESERVED_FOR_USER_0);
     }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Tue Mar 03 17:13:51 2015 -0800
@@ -28,7 +28,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.*;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Asi;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
@@ -63,10 +63,10 @@
         delayedControlTransfer.emitControlTransfer(crb, masm);
         switch (input.getKind()) {
             case Int:
-                new SPARCAssembler.Lduwa(addr.getBase(), addr.getIndex(), asIntReg(result), Asi.ASI_PRIMARY_LITTLE).emit(masm);
+                masm.lduwa(addr.getBase(), addr.getIndex(), asIntReg(result), Asi.ASI_PRIMARY_LITTLE);
                 break;
             case Long:
-                new SPARCAssembler.Ldxa(addr.getBase(), addr.getIndex(), asLongReg(result), Asi.ASI_PRIMARY_LITTLE).emit(masm);
+                masm.ldxa(addr.getBase(), addr.getIndex(), asLongReg(result), Asi.ASI_PRIMARY_LITTLE);
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java	Tue Mar 03 17:13:51 2015 -0800
@@ -29,10 +29,6 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Call;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Jmpl;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Jmp;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Sethix;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.*;
@@ -96,7 +92,7 @@
             } else {
                 int after = masm.position();
                 if (after - before == 4) {
-                    new Nop().emit(masm);
+                    masm.nop();
                 } else if (after - before == 8) {
                     // everything is fine;
                 } else {
@@ -118,7 +114,7 @@
             assert !emitted;
             emitCallPrefixCode(crb, masm);
             before = masm.position();
-            new Call(0).emit(masm);
+            masm.call(0);
             emitted = true;
         }
 
@@ -205,11 +201,11 @@
             // offset might not fit a 30-bit displacement, generate an
             // indirect call with a 64-bit immediate
             new Sethix(0L, scratch, true).emit(masm);
-            new Jmpl(scratch, 0, o7).emit(masm);
+            masm.jmpl(scratch, 0, o7);
         } else {
-            new Call(0).emit(masm);
+            masm.call(0);
         }
-        new Nop().emit(masm);  // delay slot
+        masm.nop();  // delay slot
         int after = masm.position();
         crb.recordDirectCall(before, after, callTarget, info);
         crb.recordExceptionHandlers(after, info);
@@ -219,8 +215,8 @@
     public static void indirectJmp(CompilationResultBuilder crb, SPARCMacroAssembler masm, Register dst, InvokeTarget target) {
         int before = masm.position();
         new Sethix(0L, dst, true).emit(masm);
-        new Jmp(new SPARCAddress(dst, 0)).emit(masm);
-        new Nop().emit(masm);  // delay slot
+        masm.jmp(new SPARCAddress(dst, 0));
+        masm.nop();  // delay slot
         int after = masm.position();
         crb.recordIndirectCall(before, after, target, null);
         masm.ensureUniquePC();
@@ -228,8 +224,8 @@
 
     public static void indirectCall(CompilationResultBuilder crb, SPARCMacroAssembler masm, Register dst, InvokeTarget callTarget, LIRFrameState info) {
         int before = masm.position();
-        new Jmpl(dst, 0, o7).emit(masm);
-        new Nop().emit(masm);  // delay slot
+        masm.jmpl(dst, 0, o7);
+        masm.nop();  // delay slot
         int after = masm.position();
         crb.recordIndirectCall(before, after, callTarget, info);
         crb.recordExceptionHandlers(after, info);
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java	Tue Mar 03 17:13:51 2015 -0800
@@ -24,11 +24,12 @@
 
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.*;
 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.SPARCMacroAssembler.Cmp;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
@@ -81,19 +82,19 @@
         if (isRegister(y)) {
             switch (opcode) {
                 case ICMP:
-                    new Cmp(asIntReg(x), asIntReg(y)).emit(masm);
+                    masm.cmp(asIntReg(x), asIntReg(y));
                     break;
                 case LCMP:
-                    new Cmp(asLongReg(x), asLongReg(y)).emit(masm);
+                    masm.cmp(asLongReg(x), asLongReg(y));
                     break;
                 case ACMP:
-                    new Cmp(asObjectReg(x), asObjectReg(y)).emit(masm);
+                    masm.cmp(asObjectReg(x), asObjectReg(y));
                     break;
                 case FCMP:
-                    new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(x), asFloatReg(y)).emit(masm);
+                    masm.fcmp(Fcc0, Fcmps, asFloatReg(x), asFloatReg(y));
                     break;
                 case DCMP:
-                    new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(x), asDoubleReg(y)).emit(masm);
+                    masm.fcmp(Fcc0, Fcmpd, asDoubleReg(x), asDoubleReg(y));
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
@@ -103,24 +104,24 @@
             switch (opcode) {
                 case LCMP:
                     assert isSimm13(crb.asLongConst(y));
-                    new Cmp(asLongReg(x), (int) crb.asLongConst(y)).emit(masm);
+                    masm.cmp(asLongReg(x), (int) crb.asLongConst(y));
                     break;
                 case ICMP:
                     assert isSimm13(crb.asIntConst(y));
-                    new Cmp(asIntReg(x), crb.asIntConst(y)).emit(masm);
+                    masm.cmp(asIntReg(x), crb.asIntConst(y));
                     break;
                 case ACMP:
                     if (((JavaConstant) y).isNull()) {
-                        new Cmp(asObjectReg(x), 0).emit(masm);
+                        masm.cmp(asObjectReg(x), 0);
                         break;
                     } else {
                         throw GraalInternalError.shouldNotReachHere("Only null object constants are allowed in comparisons");
                     }
                 case FCMP:
-                    new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(x), asFloatReg(y)).emit(masm);
+                    masm.fcmp(Fcc0, Fcmps, asFloatReg(x), asFloatReg(y));
                     break;
                 case DCMP:
-                    new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(x), asDoubleReg(y)).emit(masm);
+                    masm.fcmp(Fcc0, Fcmpd, asDoubleReg(x), asDoubleReg(y));
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Tue Mar 03 17:13:51 2015 -0800
@@ -23,21 +23,30 @@
 package com.oracle.graal.lir.sparc;
 
 import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 import static com.oracle.graal.sparc.SPARC.*;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
+import com.oracle.graal.asm.Assembler.LabelHint;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
+import com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict;
+import com.oracle.graal.asm.sparc.SPARCAssembler.CC;
+import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.calc.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.*;
+import com.oracle.graal.lir.StandardOp.BlockEndOp;
 import com.oracle.graal.lir.SwitchStrategy.BaseSwitchClosure;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.sparc.SPARC.CPUFeature;
 import com.oracle.graal.sparc.*;
 
 public class SPARCControlFlow {
@@ -58,7 +67,7 @@
         }
 
         public static void emitCodeHelper(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            new Ret().emit(masm);
+            masm.ret();
             // On SPARC we always leave the frame (in the delay slot).
             crb.frameContext.leave(crb);
         }
@@ -70,7 +79,7 @@
         private final SPARCCompare opcode;
         @Use({REG}) protected Value x;
         @Use({REG, CONST}) protected Value y;
-        protected final Condition condition;
+        private ConditionFlag conditionFlag;
         protected final LabelRef trueDestination;
         protected LabelHint trueDestinationHint;
         protected final LabelRef falseDestination;
@@ -90,12 +99,13 @@
             this.opcode = opcode;
             this.x = x;
             this.y = y;
-            this.condition = condition;
             this.trueDestination = trueDestination;
             this.falseDestination = falseDestination;
             this.kind = kind;
             this.unorderedIsTrue = unorderedIsTrue;
             this.trueDestinationProbability = trueDestinationProbability;
+            CC conditionCodeReg = CC.forKind(kind);
+            conditionFlag = ConditionFlag.fromCondtition(conditionCodeReg, condition, unorderedIsTrue);
         }
 
         @Override
@@ -105,24 +115,32 @@
             }
             if (!emitted) {
                 requestHints(masm);
-                if (canUseShortBranch(crb, masm, masm.position() + maximumSelfOffsetInstructions * masm.target.wordSize)) {
+                int targetPosition = getTargetPosition(masm);
+                if (canUseShortBranch(crb, masm, targetPosition)) {
                     emitted = emitShortCompareBranch(crb, masm);
                 }
-                if (!emitted) {
+                if (!emitted) { // No short compare/branch was used, so we go into fallback
                     SPARCCompare.emit(crb, masm, opcode, x, y);
-                    emitted = emitBranch(crb, masm, true);
+                    emitted = emitBranch(crb, masm, kind, conditionFlag, trueDestination, falseDestination, true, trueDestinationProbability);
                 }
             }
+            assert emitted;
+        }
 
-            assert emitted;
+        private static int getTargetPosition(Assembler asm) {
+            return asm.position() + maximumSelfOffsetInstructions * asm.target.wordSize;
         }
 
         public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             requestHints(masm);
             // When we use short branches, no delay slot is available
-            if (!canUseShortBranch(crb, masm, masm.position() + maximumSelfOffsetInstructions * masm.target.wordSize)) {
+            int targetPosition = getTargetPosition(masm);
+            if (!canUseShortBranch(crb, masm, targetPosition)) {
                 SPARCCompare.emit(crb, masm, opcode, x, y);
-                emitted = emitBranch(crb, masm, false);
+                emitted = emitBranch(crb, masm, kind, conditionFlag, trueDestination, falseDestination, false, trueDestinationProbability);
+                if (emitted) {
+                    delaySlotPosition = masm.position();
+                }
             }
         }
 
@@ -133,7 +151,6 @@
             if (falseDestinationHint == null) {
                 this.falseDestinationHint = masm.requestLabelHint(falseDestination.label());
             }
-
         }
 
         /**
@@ -170,24 +187,25 @@
             Value tmpValue;
             Value actualX = x;
             Value actualY = y;
-            Condition actualCondition = condition;
+            ConditionFlag actualConditionFlag = conditionFlag;
             Label actualTrueTarget = trueDestination.label();
             Label actualFalseTarget = falseDestination.label();
             Label tmpTarget;
             boolean needJump;
             if (crb.isSuccessorEdge(trueDestination)) {
-                actualCondition = actualCondition.negate();
+                actualConditionFlag = conditionFlag.negate();
                 tmpTarget = actualTrueTarget;
                 actualTrueTarget = actualFalseTarget;
                 actualFalseTarget = tmpTarget;
                 needJump = false;
             } else {
                 needJump = !crb.isSuccessorEdge(falseDestination);
-                if (needJump && !isShortBranch(masm, masm.position() + maximumSelfOffsetInstructions * masm.target.wordSize, trueDestinationHint, actualTrueTarget)) {
+                int targetPosition = getTargetPosition(masm);
+                if (needJump && !isShortBranch(masm, targetPosition, trueDestinationHint, actualTrueTarget)) {
                     // we have to jump in either way, so we must put the shorter
                     // branch into the actualTarget as only one of the two jump targets
                     // is guaranteed to be simm10
-                    actualCondition = actualCondition.negate();
+                    actualConditionFlag = actualConditionFlag.negate();
                     tmpTarget = actualTrueTarget;
                     actualTrueTarget = actualFalseTarget;
                     actualFalseTarget = tmpTarget;
@@ -198,9 +216,8 @@
                 tmpValue = actualX;
                 actualX = actualY;
                 actualY = tmpValue;
-                actualCondition = actualCondition.mirror();
+                actualConditionFlag = actualConditionFlag.mirror();
             }
-            ConditionFlag conditionFlag = ConditionFlag.fromCondtition(CC.Icc, actualCondition, false);
             boolean isValidConstant = isConstant(actualY) && isSimm5(asConstant(actualY));
             SPARCScratchRegister scratch = null;
             try {
@@ -210,8 +227,8 @@
                     SPARCMove.move(crb, masm, scratchValue, actualY, SPARCDelayedControlTransfer.DUMMY);
                     actualY = scratchValue;
                 }
-                emitCBCond(masm, actualX, actualY, actualTrueTarget, conditionFlag);
-                new Nop().emit(masm);
+                emitCBCond(masm, actualX, actualY, actualTrueTarget, actualConditionFlag);
+                masm.nop();
             } finally {
                 if (scratch != null) {
                     // release the scratch if used
@@ -220,7 +237,7 @@
             }
             if (needJump) {
                 masm.jmp(actualFalseTarget);
-                new Nop().emit(masm);
+                masm.nop();
             }
             return true;
         }
@@ -233,26 +250,26 @@
                 case Int:
                     if (isConstant(actualY)) {
                         int constantY = asConstant(actualY).asInt();
-                        new CBcondw(conditionFlag, asIntReg(actualX), constantY, actualTrueTarget).emit(masm);
+                        masm.cbcondw(conditionFlag, asIntReg(actualX), constantY, actualTrueTarget);
                     } else {
-                        new CBcondw(conditionFlag, asIntReg(actualX), asIntReg(actualY), actualTrueTarget).emit(masm);
+                        masm.cbcondw(conditionFlag, asIntReg(actualX), asIntReg(actualY), actualTrueTarget);
                     }
                     break;
                 case Long:
                     if (isConstant(actualY)) {
                         int constantY = (int) asConstant(actualY).asLong();
-                        new CBcondx(conditionFlag, asLongReg(actualX), constantY, actualTrueTarget).emit(masm);
+                        masm.cbcondx(conditionFlag, asLongReg(actualX), constantY, actualTrueTarget);
                     } else {
-                        new CBcondx(conditionFlag, asLongReg(actualX), asLongReg(actualY), actualTrueTarget).emit(masm);
+                        masm.cbcondx(conditionFlag, asLongReg(actualX), asLongReg(actualY), actualTrueTarget);
                     }
                     break;
                 case Object:
                     if (isConstant(actualY)) {
                         // Object constant valid can only be null
                         assert asConstant(actualY).isNull();
-                        new CBcondx(conditionFlag, asObjectReg(actualX), 0, actualTrueTarget).emit(masm);
+                        masm.cbcondx(conditionFlag, asObjectReg(actualX), 0, actualTrueTarget);
                     } else { // this is already loaded
-                        new CBcondx(conditionFlag, asObjectReg(actualX), asObjectReg(actualY), actualTrueTarget).emit(masm);
+                        masm.cbcondx(conditionFlag, asObjectReg(actualX), asObjectReg(actualY), actualTrueTarget);
                     }
                     break;
                 default:
@@ -260,46 +277,6 @@
             }
         }
 
-        public boolean emitBranch(CompilationResultBuilder crb, SPARCMacroAssembler masm, boolean withDelayedNop) {
-            Label actualTarget;
-            Condition actualCondition;
-            boolean branchOnUnordered;
-            boolean needJump;
-            boolean predictBranchTaken;
-            if (crb.isSuccessorEdge(trueDestination)) {
-                actualCondition = condition != null ? condition.negate() : null;
-                actualTarget = falseDestination.label();
-                predictBranchTaken = trueDestinationProbability < .5; // false branch needs jump
-                needJump = false;
-                branchOnUnordered = !unorderedIsTrue;
-            } else {
-                actualCondition = condition;
-                actualTarget = trueDestination.label();
-                needJump = !crb.isSuccessorEdge(falseDestination);
-                predictBranchTaken = trueDestinationProbability >= .5;
-                branchOnUnordered = unorderedIsTrue;
-            }
-            if (!withDelayedNop && needJump) {
-                // We cannot make use of the delay slot when we jump in true-case and false-case
-                return false;
-            }
-            if (kind == Kind.Double || kind == Kind.Float) {
-                emitFloatBranch(masm, actualTarget, actualCondition, branchOnUnordered);
-            } else {
-                CC cc = kind == Kind.Int ? CC.Icc : CC.Xcc;
-                assert actualCondition != null;
-                SPARCControlFlow.emitBranch(masm, actualTarget, actualCondition, cc, predictBranchTaken);
-            }
-            delaySlotPosition = masm.position();
-            if (withDelayedNop) {
-                new Nop().emit(masm);  // delay slot
-            }
-            if (needJump) {
-                masm.jmp(falseDestination.label());
-            }
-            return true; // emitted
-        }
-
         private boolean canUseShortBranch(CompilationResultBuilder crb, SPARCAssembler asm, int position) {
             if (!asm.hasFeature(CPUFeature.CBCOND)) {
                 return false;
@@ -354,175 +331,62 @@
 
     public static final class BranchOp extends SPARCLIRInstruction implements StandardOp.BranchOp {
         public static final LIRInstructionClass<BranchOp> TYPE = LIRInstructionClass.create(BranchOp.class);
-        // TODO: Condition code/flag handling needs to be improved;
-        protected final Condition condition;
         protected final ConditionFlag conditionFlag;
         protected final LabelRef trueDestination;
         protected final LabelRef falseDestination;
         protected final Kind kind;
-        protected final boolean unorderedIsTrue;
-
-        public BranchOp(ConditionFlag condition, LabelRef trueDestination, LabelRef falseDestination, Kind kind) {
-            super(TYPE);
-            this.conditionFlag = condition;
-            this.trueDestination = trueDestination;
-            this.falseDestination = falseDestination;
-            this.kind = kind;
-            this.condition = null;
-            this.unorderedIsTrue = true;
-        }
+        protected final double trueDestinationProbability;
 
-        public BranchOp(Condition condition, LabelRef trueDestination, LabelRef falseDestination, Kind kind) {
-            super(TYPE);
-            this.condition = condition;
-            this.trueDestination = trueDestination;
-            this.falseDestination = falseDestination;
-            this.kind = kind;
-            this.conditionFlag = null;
-            this.unorderedIsTrue = true;
-        }
-
-        public BranchOp(Condition finalCondition, LabelRef trueDestination, LabelRef falseDestination, Kind kind, boolean unorderedIsTrue) {
+        public BranchOp(ConditionFlag conditionFlag, LabelRef trueDestination, LabelRef falseDestination, Kind kind, double trueDestinationProbability) {
             super(TYPE);
             this.trueDestination = trueDestination;
             this.falseDestination = falseDestination;
             this.kind = kind;
-            this.conditionFlag = null;
-            this.unorderedIsTrue = unorderedIsTrue;
-            this.condition = finalCondition;
+            this.conditionFlag = conditionFlag;
+            this.trueDestinationProbability = trueDestinationProbability;
         }
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            assert condition == null && conditionFlag != null || condition != null && conditionFlag == null;
-            Label actualTarget;
-            Condition actualCondition;
-            ConditionFlag actualConditionFlag;
-            boolean branchOnUnordered;
-            boolean needJump;
-            if (crb.isSuccessorEdge(trueDestination)) {
-                actualCondition = condition != null ? condition.negate() : null;
-                actualConditionFlag = conditionFlag != null ? conditionFlag.negate() : null;
-                actualTarget = falseDestination.label();
-                needJump = false;
-                branchOnUnordered = !unorderedIsTrue;
-            } else {
-                actualCondition = condition;
-                actualConditionFlag = conditionFlag;
-                actualTarget = trueDestination.label();
-                needJump = !crb.isSuccessorEdge(falseDestination);
-                branchOnUnordered = unorderedIsTrue;
-            }
-            assert kind == Kind.Int || kind == Kind.Long || kind == Kind.Object || kind == Kind.Double || kind == Kind.Float : kind;
-            if (kind == Kind.Double || kind == Kind.Float) {
-                emitFloatBranch(masm, actualTarget, actualCondition, branchOnUnordered);
-            } else {
-                CC cc = kind == Kind.Int ? CC.Icc : CC.Xcc;
-                if (actualCondition != null) {
-                    emitBranch(masm, actualTarget, actualCondition, cc, false);
-                } else if (actualConditionFlag != null) {
-                    emitBranch(masm, actualTarget, actualConditionFlag, cc);
-                } else {
-                    GraalInternalError.shouldNotReachHere();
-                }
-            }
-            new Nop().emit(masm);  // delay slot
-            if (needJump) {
-                masm.jmp(falseDestination.label());
-            }
+            emitBranch(crb, masm, kind, conditionFlag, trueDestination, falseDestination, true, trueDestinationProbability);
         }
     }
 
-    private static void emitFloatBranch(SPARCMacroAssembler masm, Label target, Condition actualCondition, boolean branchOnUnordered) {
-        switch (actualCondition) {
-            case EQ:
-                if (branchOnUnordered) {
-                    new Fbue(false, target).emit(masm);
-                } else {
-                    new Fbe(false, target).emit(masm);
-                }
-                break;
-            case NE:
-                new Fbne(false, target).emit(masm); // Is also unordered
-                break;
-            case LT:
-                if (branchOnUnordered) {
-                    new Fbul(false, target).emit(masm);
-                } else {
-                    new Fbl(false, target).emit(masm);
-                }
-                break;
-            case LE:
-                if (branchOnUnordered) {
-                    new Fbule(false, target).emit(masm);
-                } else {
-                    new Fble(false, target).emit(masm);
-                }
-                break;
-            case GT:
-                if (branchOnUnordered) {
-                    new Fbug(false, target).emit(masm);
-                } else {
-                    new Fbg(false, target).emit(masm);
-                }
-                break;
-            case GE:
-                if (branchOnUnordered) {
-                    new Fbuge(false, target).emit(masm);
-                } else {
-                    new Fbge(false, target).emit(masm);
-                }
-                break;
-            case AE:
-            case AT:
-            case BT:
-            case BE:
-                throw GraalInternalError.unimplemented("Should not be required for float/dobule");
-            default:
-                throw GraalInternalError.shouldNotReachHere();
+    private static boolean emitBranch(CompilationResultBuilder crb, SPARCMacroAssembler masm, Kind kind, ConditionFlag conditionFlag, LabelRef trueDestination, LabelRef falseDestination,
+                    boolean withDelayedNop, double trueDestinationProbability) {
+        Label actualTarget;
+        ConditionFlag actualConditionFlag;
+        boolean needJump;
+        BranchPredict predictTaken;
+        if (falseDestination != null && crb.isSuccessorEdge(trueDestination)) {
+            actualConditionFlag = conditionFlag != null ? conditionFlag.negate() : null;
+            actualTarget = falseDestination.label();
+            needJump = false;
+            predictTaken = trueDestinationProbability < .5d ? PREDICT_TAKEN : PREDICT_NOT_TAKEN;
+        } else {
+            actualConditionFlag = conditionFlag;
+            actualTarget = trueDestination.label();
+            needJump = falseDestination != null && !crb.isSuccessorEdge(falseDestination);
+            predictTaken = trueDestinationProbability > .5d ? PREDICT_TAKEN : PREDICT_NOT_TAKEN;
         }
-    }
-
-    private static void emitBranch(SPARCMacroAssembler masm, Label target, ConditionFlag actualCondition, CC cc) {
-        new Fmt00c(0, actualCondition, Op2s.Bp, cc, 0, target).emit(masm);
-    }
-
-    private static void emitBranch(SPARCMacroAssembler masm, Label target, Condition actualCondition, CC cc, boolean predictTaken) {
+        if (!withDelayedNop && needJump) {
+            // We cannot make use of the delay slot when we jump in true-case and false-case
+            return false;
+        }
 
-        switch (actualCondition) {
-            case EQ:
-                new Bpe(cc, false, predictTaken, target).emit(masm);
-                break;
-            case NE:
-                new Bpne(cc, false, predictTaken, target).emit(masm);
-                break;
-            case BT:
-                new Bplu(cc, false, predictTaken, target).emit(masm);
-                break;
-            case LT:
-                new Bpl(cc, false, predictTaken, target).emit(masm);
-                break;
-            case BE:
-                new Bpleu(cc, false, predictTaken, target).emit(masm);
-                break;
-            case LE:
-                new Bple(cc, false, predictTaken, target).emit(masm);
-                break;
-            case GE:
-                new Bpge(cc, false, predictTaken, target).emit(masm);
-                break;
-            case AE:
-                new Bpgeu(cc, false, predictTaken, target).emit(masm);
-                break;
-            case GT:
-                new Bpg(cc, false, predictTaken, target).emit(masm);
-                break;
-            case AT:
-                new Bpgu(cc, false, predictTaken, target).emit(masm);
-                break;
-            default:
-                throw GraalInternalError.shouldNotReachHere();
+        if (kind == Kind.Double || kind == Kind.Float) {
+            masm.fbpcc(actualConditionFlag, NOT_ANNUL, actualTarget, CC.Fcc0, predictTaken);
+        } else {
+            CC cc = kind == Kind.Int ? CC.Icc : CC.Xcc;
+            masm.bpcc(actualConditionFlag, NOT_ANNUL, actualTarget, cc, predictTaken);
         }
+        if (withDelayedNop) {
+            masm.nop();  // delay slot
+        }
+        if (needJump) {
+            masm.jmp(falseDestination.label());
+        }
+        return true;
     }
 
     public static final class StrategySwitchOp extends SPARCLIRInstruction implements BlockEndOp {
@@ -553,40 +417,34 @@
             BaseSwitchClosure closure = new BaseSwitchClosure(crb, masm, keyTargets, defaultTarget) {
                 @Override
                 protected void conditionalJump(int index, Condition condition, Label target) {
+                    SPARCMove.move(crb, masm, scratch, keyConstants[index], SPARCDelayedControlTransfer.DUMMY);
+                    CC conditionCode;
+                    Register scratchRegister;
                     switch (key.getKind()) {
                         case Char:
                         case Byte:
                         case Short:
                         case Int:
-                            if (crb.codeCache.needsDataPatch(keyConstants[index])) {
-                                crb.recordInlineDataInCode(keyConstants[index]);
-                            }
-                            long lc = keyConstants[index].asLong();
-                            if (SPARCAssembler.isSimm13(lc)) {
-                                assert NumUtil.isInt(lc);
-                                new Cmp(keyRegister, (int) lc).emit(masm);
-                            } else {
-                                new Setx(lc, asIntReg(scratch)).emit(masm);
-                                new Cmp(keyRegister, asIntReg(scratch)).emit(masm);
-                            }
-                            emitBranch(masm, target, condition, CC.Icc, false);
+                            conditionCode = CC.Icc;
+                            scratchRegister = asIntReg(scratch);
                             break;
                         case Long: {
-                            SPARCMove.move(crb, masm, scratch, keyConstants[index], SPARCDelayedControlTransfer.DUMMY);
-                            new Cmp(keyRegister, asLongReg(scratch)).emit(masm);
-                            emitBranch(masm, target, condition, CC.Xcc, false);
+                            conditionCode = CC.Xcc;
+                            scratchRegister = asLongReg(scratch);
                             break;
                         }
                         case Object: {
-                            SPARCMove.move(crb, masm, scratch, keyConstants[index], SPARCDelayedControlTransfer.DUMMY);
-                            new Cmp(keyRegister, asObjectReg(scratch)).emit(masm);
-                            emitBranch(masm, target, condition, CC.Ptrcc, false);
+                            conditionCode = CC.Ptrcc;
+                            scratchRegister = asObjectReg(scratch);
                             break;
                         }
                         default:
                             throw new GraalInternalError("switch only supported for int, long and object");
                     }
-                    new Nop().emit(masm);  // delay slot
+                    ConditionFlag conditionFlag = ConditionFlag.fromCondtition(conditionCode, condition, false);
+                    masm.cmp(keyRegister, scratchRegister);
+                    masm.bpcc(conditionFlag, NOT_ANNUL, target, conditionCode, PREDICT_TAKEN);
+                    masm.nop();  // delay slot
                 }
             };
             strategy.run(closure);
@@ -621,47 +479,46 @@
 
             // subtract the low value from the switch value
             if (isSimm13(lowKey)) {
-                new Sub(value, lowKey, scratchReg).emit(masm);
+                masm.sub(value, lowKey, scratchReg);
             } else {
                 try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
                     Register scratch2 = sc.getRegister();
                     new Setx(lowKey, scratch2).emit(masm);
-                    new Sub(value, scratch2, scratchReg).emit(masm);
+                    masm.sub(value, scratch2, scratchReg);
                 }
             }
             int upperLimit = highKey - lowKey;
             try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
                 Register scratch2 = sc.getRegister();
                 if (isSimm13(upperLimit)) {
-                    new Cmp(scratchReg, upperLimit).emit(masm);
+                    masm.cmp(scratchReg, upperLimit);
                 } else {
                     new Setx(upperLimit, scratch2).emit(masm);
-                    new Cmp(scratchReg, upperLimit).emit(masm);
+                    masm.cmp(scratchReg, upperLimit);
                 }
 
                 // Jump to default target if index is not within the jump table
                 if (defaultTarget != null) {
-                    new Bpgu(CC.Icc, defaultTarget.label()).emit(masm);
-                    new Nop().emit(masm);  // delay slot
+                    masm.bpcc(GreaterUnsigned, NOT_ANNUL, defaultTarget.label(), Icc, PREDICT_TAKEN);
+                    masm.nop();  // delay slot
                 }
 
                 // Load jump table entry into scratch and jump to it
-                new Sll(scratchReg, 3, scratchReg).emit(masm); // Multiply by 8
+                masm.sll(scratchReg, 3, scratchReg); // Multiply by 8
                 // Zero the left bits sll with shcnt>0 does not mask upper 32 bits
-                new Srl(scratchReg, 0, scratchReg).emit(masm);
-                new Rdpc(scratch2).emit(masm);
+                masm.srl(scratchReg, 0, scratchReg);
+                masm.rdpc(scratch2);
 
                 // The jump table follows four instructions after rdpc
-                new Add(scratchReg, 4 * 4, scratchReg).emit(masm);
-                new Jmpl(scratch2, scratchReg, g0).emit(masm);
+                masm.add(scratchReg, 4 * 4, scratchReg);
+                masm.jmpl(scratch2, scratchReg, g0);
             }
-            new Nop().emit(masm);
-            // new Sra(value, 3, value).emit(masm); // delay slot, correct the value (division by 8)
+            masm.nop();
 
             // Emit jump table entries
             for (LabelRef target : targets) {
-                new Bpa(target.label()).emit(masm);
-                new Nop().emit(masm); // delay slot
+                masm.bpcc(Always, NOT_ANNUL, target.label(), Xcc, PREDICT_TAKEN);
+                masm.nop(); // delay slot
             }
         }
     }
@@ -691,8 +548,6 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            // check that we don't overwrite an input operand before it is used.
-            // assert !result.equals(trueValue);
             if (result.equals(trueValue)) { // We have the true value in place, do he opposite
                 cmove(masm, cc, kind, result, condition.negate(), falseValue);
             } else if (result.equals(falseValue)) {
@@ -722,9 +577,9 @@
                     } else {
                         constant = asConstant(other).asInt();
                     }
-                    new Movcc(cond, cc, constant, asRegister(result)).emit(masm);
+                    masm.movcc(cond, cc, constant, asRegister(result));
                 } else {
-                    new Movcc(cond, cc, asRegister(other), asRegister(result)).emit(masm);
+                    masm.movcc(cond, cc, asRegister(other), asRegister(result));
                 }
                 break;
             case Long:
@@ -736,17 +591,16 @@
                     } else {
                         constant = asConstant(other).asLong();
                     }
-                    assert isSimm11(constant);
-                    new Movcc(cond, cc, (int) constant, asRegister(result)).emit(masm);
+                    masm.movcc(cond, cc, (int) constant, asRegister(result));
                 } else {
-                    new Movcc(cond, cc, asRegister(other), asRegister(result)).emit(masm);
+                    masm.movcc(cond, cc, asRegister(other), asRegister(result));
                 }
                 break;
             case Float:
-                new Fmovscc(cond, cc, asFloatReg(other), asFloatReg(result)).emit(masm);
+                masm.fmovscc(cond, cc, asFloatReg(other), asFloatReg(result));
                 break;
             case Double:
-                new Fmovdcc(cond, cc, asDoubleReg(other), asDoubleReg(result)).emit(masm);
+                masm.fmovdcc(cond, cc, asDoubleReg(other), asDoubleReg(result));
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java	Tue Mar 03 17:13:51 2015 -0800
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.lir.sparc;
 
-import com.oracle.graal.asm.sparc.SPARCAssembler.Bpa;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*;
+
+import com.oracle.graal.asm.sparc.SPARCAssembler.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.JumpOp;
 import com.oracle.graal.lir.asm.*;
@@ -41,7 +42,7 @@
     public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         assert !emitDone;
         if (!crb.isSuccessorEdge(destination())) {
-            new Bpa(destination().label()).emit(masm);
+            masm.bicc(ConditionFlag.Always, NOT_ANNUL, destination().label());
             delaySlotPosition = masm.position();
         }
         emitDone = true;
@@ -52,8 +53,8 @@
         if (!crb.isSuccessorEdge(destination())) {
             if (!emitDone) {
                 SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm;
-                new Bpa(destination().label()).emit(masm);
-                new Nop().emit(masm);
+                masm.bicc(ConditionFlag.Always, NOT_ANNUL, destination().label());
+                masm.nop();
             } else {
                 assert crb.asm.position() - delaySlotPosition == 4;
             }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java	Tue Mar 03 17:13:51 2015 -0800
@@ -25,7 +25,6 @@
 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.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.*;
@@ -63,10 +62,10 @@
             case SQRT:
                 switch (inputKind) {
                     case Float:
-                        new Fsqrts(asFloatReg(input), asFloatReg(result)).emit(masm);
+                        masm.fsqrts(asFloatReg(input), asFloatReg(result));
                         break;
                     case Double:
-                        new Fsqrtd(asDoubleReg(input), asDoubleReg(result)).emit(masm);
+                        masm.fsqrtd(asDoubleReg(input), asDoubleReg(result));
                         break;
                     default:
                         GraalInternalError.shouldNotReachHere();
@@ -75,10 +74,10 @@
             case ABS:
                 switch (inputKind) {
                     case Float:
-                        new Fabss(asFloatReg(input), asFloatReg(result)).emit(masm);
+                        masm.fabss(asFloatReg(input), asFloatReg(result));
                         break;
                     case Double:
-                        new Fabsd(asDoubleReg(input), asDoubleReg(result)).emit(masm);
+                        masm.fabsd(asDoubleReg(input), asDoubleReg(result));
                         break;
                     default:
                         GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Tue Mar 03 17:13:51 2015 -0800
@@ -31,35 +31,6 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Add;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fmovd;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fmovs;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fzerod;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fzeros;
-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.Lduh;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Membar;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Movdtox;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Movstosw;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Movstouw;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Movwtos;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Movxtod;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Or;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Stb;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Stdf;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Stf;
-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.SPARCMacroAssembler.Cas;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Casx;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Clr;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.*;
@@ -168,11 +139,11 @@
                 switch (inputKind) {
                     case Float:
                         assert resultKindSize == 4;
-                        new Stf(asFloatReg(input), tempAddress).emit(masm);
+                        masm.stf(asFloatReg(input), tempAddress);
                         break;
                     case Double:
                         assert resultKindSize == 8;
-                        new Stdf(asDoubleReg(input), tempAddress).emit(masm);
+                        masm.stdf(asDoubleReg(input), tempAddress);
                         break;
                     case Long:
                     case Int:
@@ -180,13 +151,13 @@
                     case Char:
                     case Byte:
                         if (resultKindSize == 8) {
-                            new Stx(asLongReg(input), tempAddress).emit(masm);
+                            masm.stx(asLongReg(input), tempAddress);
                         } else if (resultKindSize == 4) {
-                            new Stw(asIntReg(input), tempAddress).emit(masm);
+                            masm.stw(asIntReg(input), tempAddress);
                         } else if (resultKindSize == 2) {
-                            new Sth(asIntReg(input), tempAddress).emit(masm);
+                            masm.sth(asIntReg(input), tempAddress);
                         } else if (resultKindSize == 1) {
-                            new Stb(asIntReg(input), tempAddress).emit(masm);
+                            masm.stb(asIntReg(input), tempAddress);
                         } else {
                             throw GraalInternalError.shouldNotReachHere();
                         }
@@ -197,25 +168,25 @@
                 delayedControlTransfer.emitControlTransfer(crb, masm);
                 switch (resultKind) {
                     case Long:
-                        new Ldx(tempAddress, asLongReg(result)).emit(masm);
+                        masm.ldx(tempAddress, asLongReg(result));
                         break;
                     case Int:
-                        new Ldsw(tempAddress, asIntReg(result)).emit(masm);
+                        masm.ldsw(tempAddress, asIntReg(result));
                         break;
                     case Short:
-                        new Ldsh(tempAddress, asIntReg(input)).emit(masm);
+                        masm.ldsh(tempAddress, asIntReg(input));
                         break;
                     case Char:
-                        new Lduh(tempAddress, asIntReg(input)).emit(masm);
+                        masm.lduh(tempAddress, asIntReg(input));
                         break;
                     case Byte:
-                        new Ldsb(tempAddress, asIntReg(input)).emit(masm);
+                        masm.ldsb(tempAddress, asIntReg(input));
                         break;
                     case Float:
-                        new Ldf(tempAddress, asFloatReg(result)).emit(masm);
+                        masm.ldf(tempAddress, asFloatReg(result));
                         break;
                     case Double:
-                        new Lddf(tempAddress, asDoubleReg(result)).emit(masm);
+                        masm.lddf(tempAddress, asDoubleReg(result));
                         break;
                     default:
                         GraalInternalError.shouldNotReachHere();
@@ -256,25 +227,25 @@
             delayedControlTransfer.emitControlTransfer(crb, masm);
             if (resultKind == Float) {
                 if (inputKind == Int || inputKind == Short || inputKind == Char || inputKind == Byte) {
-                    new Movwtos(asIntReg(input), asFloatReg(result)).emit(masm);
+                    masm.movwtos(asIntReg(input), asFloatReg(result));
                 } else {
                     throw GraalInternalError.shouldNotReachHere();
                 }
             } else if (resultKind == Double) {
                 if (inputKind == Int || inputKind == Short || inputKind == Char || inputKind == Byte) {
-                    new Movxtod(asIntReg(input), asDoubleReg(result)).emit(masm);
+                    masm.movxtod(asIntReg(input), asDoubleReg(result));
                 } else {
-                    new Movxtod(asLongReg(input), asDoubleReg(result)).emit(masm);
+                    masm.movxtod(asLongReg(input), asDoubleReg(result));
                 }
             } else if (inputKind == Float) {
                 if (resultKind == Int || resultKind == Short || resultKind == Byte) {
-                    new Movstosw(asFloatReg(input), asIntReg(result)).emit(masm);
+                    masm.movstosw(asFloatReg(input), asIntReg(result));
                 } else {
-                    new Movstouw(asFloatReg(input), asIntReg(result)).emit(masm);
+                    masm.movstouw(asFloatReg(input), asIntReg(result));
                 }
             } else if (inputKind == Double) {
                 if (resultKind == Long) {
-                    new Movdtox(asDoubleReg(input), asLongReg(result)).emit(masm);
+                    masm.movdtox(asDoubleReg(input), asLongReg(result));
                 } else {
                     throw GraalInternalError.shouldNotReachHere();
                 }
@@ -335,28 +306,28 @@
                 switch (kind) {
                     case Boolean:
                     case Byte:
-                        new Ldsb(addr, dst).emit(masm);
+                        masm.ldsb(addr, dst);
                         break;
                     case Short:
-                        new Ldsh(addr, dst).emit(masm);
+                        masm.ldsh(addr, dst);
                         break;
                     case Char:
-                        new Lduh(addr, dst).emit(masm);
+                        masm.lduh(addr, dst);
                         break;
                     case Int:
-                        new Ldsw(addr, dst).emit(masm);
+                        masm.ldsw(addr, dst);
                         break;
                     case Long:
-                        new Ldx(addr, dst).emit(masm);
+                        masm.ldx(addr, dst);
                         break;
                     case Float:
-                        new Ldf(addr, dst).emit(masm);
+                        masm.ldf(addr, dst);
                         break;
                     case Double:
-                        new Lddf(addr, dst).emit(masm);
+                        masm.lddf(addr, dst);
                         break;
                     case Object:
-                        new Ldx(addr, dst).emit(masm);
+                        masm.ldx(addr, dst);
                         break;
                     default:
                         throw GraalInternalError.shouldNotReachHere();
@@ -418,7 +389,7 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            new Membar(barriers).emit(masm);
+            masm.membar(barriers);
         }
     }
 
@@ -438,7 +409,7 @@
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             delayedControlTransfer.emitControlTransfer(crb, masm);
             crb.recordImplicitException(masm.position(), state);
-            new Ldx(new SPARCAddress(asRegister(input), 0), r0).emit(masm);
+            masm.ldx(new SPARCAddress(asRegister(input), 0), g0);
         }
 
         public Value getCheckedValue() {
@@ -497,17 +468,17 @@
         if (address.getIndex().equals(Register.None)) {
             if (isSimm13(address.getDisplacement())) {
                 delaySlotHolder.emitControlTransfer(crb, masm);
-                new Add(address.getBase(), address.getDisplacement(), result).emit(masm);
+                masm.add(address.getBase(), address.getDisplacement(), result);
             } else {
                 assert result.encoding() != address.getBase().encoding();
                 new Setx(address.getDisplacement(), result).emit(masm);
                 // No relocation, therefore, the add can be delayed as well
                 delaySlotHolder.emitControlTransfer(crb, masm);
-                new Add(address.getBase(), result, result).emit(masm);
+                masm.add(address.getBase(), result, result);
             }
         } else {
             delaySlotHolder.emitControlTransfer(crb, masm);
-            new Add(address.getBase(), address.getIndex(), result).emit(masm);
+            masm.add(address.getBase(), address.getIndex(), result);
         }
     }
 
@@ -534,26 +505,26 @@
                 switch (kind) {
                     case Boolean:
                     case Byte:
-                        new Stb(asRegister(input), addr).emit(masm);
+                        masm.stb(asRegister(input), addr);
                         break;
                     case Short:
                     case Char:
-                        new Sth(asRegister(input), addr).emit(masm);
+                        masm.sth(asRegister(input), addr);
                         break;
                     case Int:
-                        new Stw(asRegister(input), addr).emit(masm);
+                        masm.stw(asRegister(input), addr);
                         break;
                     case Long:
-                        new Stx(asRegister(input), addr).emit(masm);
+                        masm.stx(asRegister(input), addr);
                         break;
                     case Object:
-                        new Stx(asRegister(input), addr).emit(masm);
+                        masm.stx(asRegister(input), addr);
                         break;
                     case Float:
-                        new Stf(asRegister(input), addr).emit(masm);
+                        masm.stf(asRegister(input), addr);
                         break;
                     case Double:
-                        new Stdf(asRegister(input), addr).emit(masm);
+                        masm.stdf(asRegister(input), addr);
                         break;
                     default:
                         throw GraalInternalError.shouldNotReachHere("missing: " + kind);
@@ -587,18 +558,18 @@
                 switch (kind) {
                     case Boolean:
                     case Byte:
-                        new Stb(g0, addr).emit(masm);
+                        masm.stb(g0, addr);
                         break;
                     case Short:
                     case Char:
-                        new Sth(g0, addr).emit(masm);
+                        masm.sth(g0, addr);
                         break;
                     case Int:
-                        new Stw(g0, addr).emit(masm);
+                        masm.stw(g0, addr);
                         break;
                     case Long:
                     case Object:
-                        new Stx(g0, addr).emit(masm);
+                        masm.stx(g0, addr);
                         break;
                     case Float:
                     case Double:
@@ -637,7 +608,7 @@
                         Register scratch = sc.getRegister();
                         long value = constant.asLong();
                         if (isSimm13(value)) {
-                            new Or(g0, (int) value, scratch).emit(masm);
+                            masm.or(g0, (int) value, scratch);
                         } else {
                             new Setx(value, scratch).emit(masm);
                         }
@@ -667,18 +638,18 @@
             case Long:
             case Object:
                 delaySlotLir.emitControlTransfer(crb, masm);
-                new Mov(src, dst).emit(masm);
+                masm.mov(src, dst);
                 break;
             case Float:
                 if (result.getPlatformKind() == Kind.Float) {
-                    new Fmovs(src, dst).emit(masm);
+                    masm.fmovs(src, dst);
                 } else {
                     throw GraalInternalError.shouldNotReachHere();
                 }
                 break;
             case Double:
                 if (result.getPlatformKind() == Kind.Double) {
-                    new Fmovd(src, dst).emit(masm);
+                    masm.fmovd(src, dst);
                 } else {
                     throw GraalInternalError.shouldNotReachHere();
                 }
@@ -718,24 +689,24 @@
             switch (input.getKind()) {
                 case Byte:
                 case Boolean:
-                    new Stb(src, dst).emit(masm);
+                    masm.stb(src, dst);
                     break;
                 case Char:
                 case Short:
-                    new Sth(src, dst).emit(masm);
+                    masm.sth(src, dst);
                     break;
                 case Int:
-                    new Stw(src, dst).emit(masm);
+                    masm.stw(src, dst);
                     break;
                 case Long:
                 case Object:
-                    new Stx(src, dst).emit(masm);
+                    masm.stx(src, dst);
                     break;
                 case Float:
-                    new Stf(src, dst).emit(masm);
+                    masm.stf(src, dst);
                     break;
                 case Double:
-                    new Stdf(src, dst).emit(masm);
+                    masm.stdf(src, dst);
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere("Input is a: " + input.getKind() + "(" + input + ")");
@@ -753,26 +724,26 @@
             switch (input.getKind()) {
                 case Boolean:
                 case Byte:
-                    new Ldsb(src, dst).emit(masm);
+                    masm.ldsb(src, dst);
                     break;
                 case Short:
-                    new Ldsh(src, dst).emit(masm);
+                    masm.ldsh(src, dst);
                     break;
                 case Char:
-                    new Lduh(src, dst).emit(masm);
+                    masm.lduh(src, dst);
                     break;
                 case Int:
-                    new Ldsw(src, dst).emit(masm);
+                    masm.ldsw(src, dst);
                     break;
                 case Long:
                 case Object:
-                    new Ldx(src, dst).emit(masm);
+                    masm.ldx(src, dst);
                     break;
                 case Float:
-                    new Ldf(src, dst).emit(masm);
+                    masm.ldf(src, dst);
                     break;
                 case Double:
-                    new Lddf(src, dst).emit(masm);
+                    masm.lddf(src, dst);
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere("Input is a: " + input.getKind());
@@ -788,10 +759,10 @@
                 case Int:
                     if (input.isDefaultForKind()) {
                         delaySlotLir.emitControlTransfer(crb, masm);
-                        new Clr(asIntReg(result)).emit(masm);
+                        masm.clr(asIntReg(result));
                     } else if (isSimm13(input.asLong())) {
                         delaySlotLir.emitControlTransfer(crb, masm);
-                        new Or(g0, input.asInt(), asIntReg(result)).emit(masm);
+                        masm.or(g0, input.asInt(), asIntReg(result));
                     } else {
                         Setx set = new Setx(input.asLong(), asIntReg(result), false, true);
                         set.emitFirstPartOfDelayed(masm);
@@ -802,10 +773,10 @@
                 case Long:
                     if (input.isDefaultForKind()) {
                         delaySlotLir.emitControlTransfer(crb, masm);
-                        new Clr(asLongReg(result)).emit(masm);
+                        masm.clr(asLongReg(result));
                     } else if (isSimm13(input.asLong())) {
                         delaySlotLir.emitControlTransfer(crb, masm);
-                        new Or(g0, (int) input.asLong(), asLongReg(result)).emit(masm);
+                        masm.or(g0, (int) input.asLong(), asLongReg(result));
                     } else {
                         Setx setx = new Setx(input.asLong(), asLongReg(result), false, true);
                         setx.emitFirstPartOfDelayed(masm);
@@ -818,24 +789,24 @@
                     int constantBits = java.lang.Float.floatToIntBits(constant);
                     if (constantBits == 0) {
                         delaySlotLir.emitControlTransfer(crb, masm);
-                        new Fzeros(asFloatReg(result)).emit(masm);
+                        masm.fzeros(asFloatReg(result));
                     } else {
                         if (hasVIS3) {
                             if (isSimm13(constantBits)) {
-                                new Or(g0, constantBits, scratch).emit(masm);
+                                masm.or(g0, constantBits, scratch);
                             } else {
                                 new Setx(constantBits, scratch, false).emit(masm);
                             }
                             delaySlotLir.emitControlTransfer(crb, masm);
                             // Now load the float value
-                            new Movwtos(scratch, asFloatReg(result)).emit(masm);
+                            masm.movwtos(scratch, asFloatReg(result));
                         } else {
                             crb.asFloatConstRef(input);
                             // First load the address into the scratch register
                             new Setx(0, scratch, true).emit(masm);
                             // Now load the float value
                             delaySlotLir.emitControlTransfer(crb, masm);
-                            new Ldf(scratch, asFloatReg(result)).emit(masm);
+                            masm.ldf(new SPARCAddress(scratch, 0), asFloatReg(result));
                         }
                     }
                     break;
@@ -845,24 +816,24 @@
                     long constantBits = java.lang.Double.doubleToLongBits(constant);
                     if (constantBits == 0) {
                         delaySlotLir.emitControlTransfer(crb, masm);
-                        new Fzerod(asDoubleReg(result)).emit(masm);
+                        masm.fzerod(asDoubleReg(result));
                     } else {
                         if (hasVIS3) {
                             if (isSimm13(constantBits)) {
-                                new Or(g0, (int) constantBits, scratch).emit(masm);
+                                masm.or(g0, (int) constantBits, scratch);
                             } else {
                                 new Setx(constantBits, scratch, false).emit(masm);
                             }
                             delaySlotLir.emitControlTransfer(crb, masm);
                             // Now load the float value
-                            new Movxtod(scratch, asDoubleReg(result)).emit(masm);
+                            masm.movxtod(scratch, asDoubleReg(result));
                         } else {
                             crb.asDoubleConstRef(input);
                             // First load the address into the scratch register
                             new Setx(0, scratch, true).emit(masm);
                             delaySlotLir.emitControlTransfer(crb, masm);
                             // Now load the float value
-                            new Lddf(scratch, asDoubleReg(result)).emit(masm);
+                            masm.lddf(new SPARCAddress(scratch, 0), asDoubleReg(result));
                         }
                     }
                     break;
@@ -870,7 +841,7 @@
                 case Object:
                     if (input.isNull()) {
                         delaySlotLir.emitControlTransfer(crb, masm);
-                        new Clr(asRegister(result)).emit(masm);
+                        masm.clr(asRegister(result));
                     } else if (crb.target.inlineObjects) {
                         crb.recordInlineDataInCode(input); // relocatable cannot be delayed
                         new Setx(0xDEADDEADDEADDEADL, asRegister(result), true).emit(masm);
@@ -887,11 +858,11 @@
     protected static void compareAndSwap(SPARCMacroAssembler masm, AllocatableValue address, AllocatableValue cmpValue, AllocatableValue newValue) {
         switch (cmpValue.getKind()) {
             case Int:
-                new Cas(asRegister(address), asRegister(cmpValue), asRegister(newValue)).emit(masm);
+                masm.cas(asRegister(address), asRegister(cmpValue), asRegister(newValue));
                 break;
             case Long:
             case Object:
-                new Casx(asRegister(address), asRegister(cmpValue), asRegister(newValue)).emit(masm);
+                masm.casx(asRegister(address), asRegister(cmpValue), asRegister(newValue));
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java	Tue Mar 03 17:13:51 2015 -0800
@@ -29,8 +29,6 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Lddf;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Stx;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.SaveRegistersOp;
 import com.oracle.graal.lir.asm.*;
@@ -86,8 +84,8 @@
         // We abuse the first stackslot for transferring i0 to return_register_storage
         // assert slots.length >= 1;
         SPARCAddress slot0Address = (SPARCAddress) crb.asAddress(slots[0]);
-        new Stx(SPARC.i0, slot0Address).emit(masm);
-        new Lddf(slot0Address, RETURN_REGISTER_STORAGE).emit(masm);
+        masm.stx(SPARC.i0, slot0Address);
+        masm.lddf(slot0Address, RETURN_REGISTER_STORAGE);
 
         // Now save the registers
         for (int i = 0; i < savedRegisters.length; i++) {
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java	Tue Mar 03 17:13:51 2015 -0800
@@ -24,7 +24,6 @@
 
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.*;
 import static com.oracle.graal.sparc.SPARC.*;
 
 import com.oracle.graal.api.meta.*;
@@ -54,10 +53,10 @@
                 case Char:
                 case Boolean:
                 case Int:
-                    new Andcc(asIntReg(x), asIntReg(y), g0).emit(masm);
+                    masm.andcc(asIntReg(x), asIntReg(y), g0);
                     break;
                 case Long:
-                    new Andcc(asLongReg(x), asLongReg(y), g0).emit(masm);
+                    masm.andcc(asLongReg(x), asLongReg(y), g0);
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
@@ -69,10 +68,10 @@
                 case Char:
                 case Boolean:
                 case Int:
-                    new Andcc(asIntReg(x), crb.asIntConst(y), g0).emit(masm);
+                    masm.andcc(asIntReg(x), crb.asIntConst(y), g0);
                     break;
                 case Long:
-                    new Andcc(asLongReg(x), crb.asIntConst(y), g0).emit(masm);
+                    masm.andcc(asLongReg(x), crb.asIntConst(y), g0);
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java	Tue Mar 03 17:13:51 2015 -0800
@@ -80,39 +80,51 @@
      */
     protected static final EnumSet<OperandFlag> STATE_FLAGS = EnumSet.of(OperandFlag.REG, OperandFlag.STACK);
 
-    protected void processValues(LIRInstruction inst, JavaValue[] values, InstructionValueProcedure proc) {
+    protected void processValues(LIRInstruction inst, Value[] values, InstructionValueProcedure proc) {
         for (int i = 0; i < values.length; i++) {
-            if (values[i] instanceof Value) {
-                Value value = (Value) values[i];
-                values[i] = (JavaValue) processValue(inst, proc, value);
-            }
+            Value value = values[i];
+            values[i] = processValue(inst, proc, value);
         }
     }
 
     protected Value processValue(LIRInstruction inst, InstructionValueProcedure proc, Value value) {
-        if (processed(value)) {
-            return proc.doValue(inst, value, OperandMode.ALIVE, STATE_FLAGS);
+        if (value instanceof StackLockValue) {
+            StackLockValue monitor = (StackLockValue) value;
+            Value owner = monitor.getOwner();
+            if (owner instanceof AllocatableValue) {
+                monitor.setOwner(proc.doValue(inst, owner, OperandMode.ALIVE, STATE_FLAGS));
+            }
+            Value slot = monitor.getSlot();
+            if (isVirtualStackSlot(slot)) {
+                monitor.setSlot(asStackSlotValue(proc.doValue(inst, slot, OperandMode.ALIVE, STATE_FLAGS)));
+            }
+        } else {
+            if (!isIllegal(value) && value instanceof AllocatableValue) {
+                return proc.doValue(inst, value, OperandMode.ALIVE, STATE_FLAGS);
+            } else {
+                assert unprocessed(value);
+            }
         }
         return value;
     }
 
-    protected boolean processed(Value value) {
+    private boolean unprocessed(Value value) {
         if (isIllegal(value)) {
             // Ignore dead local variables.
-            return false;
+            return true;
         } else if (isConstant(value)) {
             // Ignore constants, the register allocator does not need to see them.
-            return false;
+            return true;
         } else if (isVirtualObject(value)) {
             assert Arrays.asList(virtualObjects).contains(value);
-            return false;
+            return true;
         } else {
-            return true;
+            return false;
         }
     }
 
     /**
-     * Called by the register allocator before {@link #markLocation} to initialize the frame state.
+     * Called by the register allocator before {@link #updateUnion} to initialize the frame state.
      *
      * @param frameMap The frame map.
      * @param canHaveRegisters True if there can be any register map entries.
@@ -122,33 +134,12 @@
     }
 
     /**
-     * Called by the register allocator to mark the specified location as a reference in the
-     * reference map of the debug information. The tracked location can be a {@link RegisterValue}
-     * or a {@link StackSlot}. Note that a {@link JavaConstant} is automatically tracked.
-     *
-     * @param location The location to be added to the reference map.
-     * @param frameMap The frame map.
-     */
-    public void markLocation(Value location, FrameMap frameMap) {
-        frameMap.setReference(location, debugInfo.getReferenceMap());
-    }
-
-    /**
      * Updates this reference map with all references that are marked in {@code refMap}.
      */
     public void updateUnion(ReferenceMap refMap) {
         debugInfo.getReferenceMap().updateUnion(refMap);
     }
 
-    /**
-     * Called by the register allocator after all locations are marked.
-     *
-     * @param op The instruction to which this frame state belongs.
-     * @param frameMap The frame map.
-     */
-    public void finish(LIRInstruction op, FrameMap frameMap) {
-    }
-
     @Override
     public String toString() {
         return debugInfo != null ? debugInfo.toString() : topFrame != null ? topFrame.toString() : "<empty>";
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java	Tue Mar 03 17:13:51 2015 -0800
@@ -84,15 +84,6 @@
                 AbstractBlockBase<?> block = worklist.poll();
                 processBlock(block, worklist);
             }
-            // finish states
-            for (AbstractBlockBase<?> block : lir.getControlFlowGraph().getBlocks()) {
-                List<LIRInstruction> instructions = lir.getLIRforBlock(block);
-                for (int i = instructions.size() - 1; i >= 0; i--) {
-                    LIRInstruction inst = instructions.get(i);
-                    inst.forEachState((op, info) -> info.finish(op, frameMap));
-                }
-
-            }
         }
 
         /**
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantLoadOptimization.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantLoadOptimization.java	Tue Mar 03 17:13:51 2015 -0800
@@ -24,6 +24,7 @@
 
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRValueUtil.*;
+import static com.oracle.graal.lir.phases.LIRPhase.Options.*;
 
 import java.util.*;
 
@@ -52,7 +53,7 @@
     public static class Options {
         // @formatter:off
         @Option(help = "Enable constant load optimization.", type = OptionType.Debug)
-        public static final OptionValue<Boolean> LIROptConstantLoadOptimization = new OptionValue<>(true);
+        public static final NestedBooleanOptionValue LIROptConstantLoadOptimization = new NestedBooleanOptionValue(LIROptimization, true);
         // @formatter:on
     }
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/LIRPhase.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/LIRPhase.java	Tue Mar 03 17:13:51 2015 -0800
@@ -29,10 +29,9 @@
 import com.oracle.graal.compiler.common.cfg.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
-import com.oracle.graal.debug.DebugMemUseTracker.Closeable;
-import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.gen.*;
+import com.oracle.graal.options.*;
 
 /**
  * Base class for all {@link LIR low-level} phases. Subclasses should be stateless. There will be
@@ -40,6 +39,13 @@
  */
 public abstract class LIRPhase<C> {
 
+    public static class Options {
+        // @formatter:off
+        @Option(help = "Enable LIR level optimiztations.", type = OptionType.Debug)
+        public static final OptionValue<Boolean> LIROptimization = new OptionValue<>(true);
+        // @formatter:on
+    }
+
     private static final int PHASE_DUMP_LEVEL = 2;
 
     private CharSequence name;
@@ -79,7 +85,7 @@
 
     public final <B extends AbstractBlockBase<B>> void apply(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, C context, boolean dumpLIR) {
         try (Scope s = Debug.scope(getName(), this)) {
-            try (TimerCloseable a = timer.start(); Closeable c = memUseTracker.start()) {
+            try (DebugCloseable a = timer.start(); DebugCloseable c = memUseTracker.start()) {
                 run(target, lirGenRes, codeEmittingOrder, linearScanOrder, context);
                 if (dumpLIR && Debug.isDumpEnabled(PHASE_DUMP_LEVEL)) {
                     Debug.dump(PHASE_DUMP_LEVEL, lirGenRes.getLIR(), "After phase %s", getName());
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/PostAllocationOptimizationStage.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/PostAllocationOptimizationStage.java	Tue Mar 03 17:13:51 2015 -0800
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.lir.phases;
 
+import static com.oracle.graal.lir.phases.LIRPhase.Options.*;
+
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.phases.PostAllocationOptimizationPhase.*;
 import com.oracle.graal.options.*;
@@ -30,13 +32,13 @@
     public static class Options {
         // @formatter:off
         @Option(help = "", type = OptionType.Debug)
-        public static final OptionValue<Boolean> LIROptEdgeMoveOptimizer = new OptionValue<>(true);
+        public static final NestedBooleanOptionValue LIROptEdgeMoveOptimizer = new NestedBooleanOptionValue(LIROptimization, true);
         @Option(help = "", type = OptionType.Debug)
-        public static final OptionValue<Boolean> LIROptControlFlowOptmizer = new OptionValue<>(true);
+        public static final NestedBooleanOptionValue LIROptControlFlowOptmizer = new NestedBooleanOptionValue(LIROptimization, true);
         @Option(help = "", type = OptionType.Debug)
-        public static final OptionValue<Boolean> LIROptRedundantMoveElimination = new OptionValue<>(true);
+        public static final NestedBooleanOptionValue LIROptRedundantMoveElimination = new NestedBooleanOptionValue(LIROptimization, true);
         @Option(help = "", type = OptionType.Debug)
-        public static final OptionValue<Boolean> LIROptNullCheckOptimizer = new OptionValue<>(true);
+        public static final NestedBooleanOptionValue LIROptNullCheckOptimizer = new NestedBooleanOptionValue(LIROptimization, true);
         // @formatter:on
     }
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/LSStackSlotAllocator.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/LSStackSlotAllocator.java	Tue Mar 03 17:13:51 2015 -0800
@@ -23,6 +23,7 @@
 package com.oracle.graal.lir.stackslotalloc;
 
 import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.lir.phases.LIRPhase.Options.*;
 
 import java.util.*;
 import java.util.function.*;
@@ -32,7 +33,6 @@
 import com.oracle.graal.compiler.common.cfg.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
-import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.LIRInstruction.OperandFlag;
 import com.oracle.graal.lir.LIRInstruction.OperandMode;
@@ -57,7 +57,7 @@
     public static class Options {
         // @formatter:off
         @Option(help = "Use linear scan stack slot allocation.", type = OptionType.Debug)
-        public static final OptionValue<Boolean> LIROptLSStackSlotAllocator = new OptionValue<>(true);
+        public static final NestedBooleanOptionValue LIROptLSStackSlotAllocator = new NestedBooleanOptionValue(LIROptimization, true);
         // @formatter:on
     }
 
@@ -74,7 +74,7 @@
     }
 
     public void allocateStackSlots(FrameMapBuilderTool builder, LIRGenerationResult res) {
-        try (TimerCloseable t = MainTimer.start()) {
+        try (DebugCloseable t = MainTimer.start()) {
             new Allocator(res.getLIR(), builder).allocate();
         }
     }
@@ -99,7 +99,7 @@
             // insert by to
             this.active = new PriorityQueue<>((a, b) -> a.to() - b.to());
 
-            try (TimerCloseable t = NumInstTimer.start()) {
+            try (DebugCloseable t = NumInstTimer.start()) {
                 // step 1: number instructions
                 this.maxOpId = numberInstructions(lir, sortedBlocks);
             }
@@ -111,12 +111,12 @@
             long currentFrameSize = Debug.isMeterEnabled() ? frameMapBuilder.getFrameMap().currentFrameSize() : 0;
             Set<LIRInstruction> usePos;
             // step 2: build intervals
-            try (Scope s = Debug.scope("StackSlotAllocationBuildIntervals"); Indent indent = Debug.logAndIndent("BuildIntervals"); TimerCloseable t = BuildIntervalsTimer.start()) {
+            try (Scope s = Debug.scope("StackSlotAllocationBuildIntervals"); Indent indent = Debug.logAndIndent("BuildIntervals"); DebugCloseable t = BuildIntervalsTimer.start()) {
                 usePos = buildIntervals();
             }
             // step 3: verify intervals
             if (Debug.isEnabled()) {
-                try (TimerCloseable t = VerifyIntervalsTimer.start()) {
+                try (DebugCloseable t = VerifyIntervalsTimer.start()) {
                     verifyIntervals();
                 }
             }
@@ -124,7 +124,7 @@
                 dumpIntervals("Before stack slot allocation");
             }
             // step 4: allocate stack slots
-            try (TimerCloseable t = AllocateSlotsTimer.start()) {
+            try (DebugCloseable t = AllocateSlotsTimer.start()) {
                 allocateStackSlots();
             }
             if (Debug.isDumpEnabled()) {
@@ -132,7 +132,7 @@
             }
 
             // step 5: assign stack slots
-            try (TimerCloseable t = AssignSlotsTimer.start()) {
+            try (DebugCloseable t = AssignSlotsTimer.start()) {
                 assignStackSlots(usePos);
             }
             Debug.dump(lir, "After StackSlot assignment");
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java	Tue Mar 03 17:13:51 2015 -0800
@@ -39,4 +39,12 @@
     }
 
     public abstract double probability(AbstractBeginNode successor);
+
+    /**
+     * Primary successor of the control split. Data dependencies on the node have to be scheduled in
+     * the primary successor.
+     *
+     * @return the primary successor
+     */
+    public abstract AbstractBeginNode getPrimarySuccessor();
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java	Tue Mar 03 17:13:51 2015 -0800
@@ -23,12 +23,14 @@
 package com.oracle.graal.nodes;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.spi.*;
 
 @NodeInfo(shortName = "Deopt", nameTemplate = "Deopt {p#reason/s}")
 public final class DeoptimizeNode extends AbstractDeoptimizeNode implements Lowerable, LIRLowerable {
+    public static final int DEFAULT_DEBUG_ID = 0;
 
     public static final NodeClass<DeoptimizeNode> TYPE = NodeClass.create(DeoptimizeNode.class);
     protected final DeoptimizationAction action;
@@ -37,7 +39,7 @@
     protected final JavaConstant speculation;
 
     public DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason) {
-        this(action, reason, 0, JavaConstant.NULL_POINTER, null);
+        this(action, reason, DEFAULT_DEBUG_ID, JavaConstant.NULL_POINTER, null);
     }
 
     public DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason, int debugId, JavaConstant speculation, FrameState stateBefore) {
@@ -64,14 +66,23 @@
         tool.getLowerer().lower(this, tool);
     }
 
+    @SuppressWarnings("deprecation")
+    public int getDebugId() {
+        int deoptDebugId = debugId;
+        if (deoptDebugId == DEFAULT_DEBUG_ID && (Debug.isDumpEnabledForMethod() || Debug.isLogEnabledForMethod())) {
+            deoptDebugId = this.getId();
+        }
+        return deoptDebugId;
+    }
+
     @Override
     public void generate(NodeLIRBuilderTool gen) {
-        gen.getLIRGeneratorTool().emitDeoptimize(gen.getLIRGeneratorTool().getMetaAccess().encodeDeoptActionAndReason(action, reason, debugId), speculation, gen.state(this));
+        gen.getLIRGeneratorTool().emitDeoptimize(gen.getLIRGeneratorTool().getMetaAccess().encodeDeoptActionAndReason(action, reason, getDebugId()), speculation, gen.state(this));
     }
 
     @Override
     public ValueNode getActionAndReason(MetaAccessProvider metaAccess) {
-        return ConstantNode.forConstant(metaAccess.encodeDeoptActionAndReason(action, reason, debugId), metaAccess, graph());
+        return ConstantNode.forConstant(metaAccess.encodeDeoptActionAndReason(action, reason, getDebugId()), metaAccess, graph());
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Tue Mar 03 17:13:51 2015 -0800
@@ -1128,4 +1128,9 @@
 
         return null;
     }
+
+    @Override
+    public AbstractBeginNode getPrimarySuccessor() {
+        return this.trueSuccessor();
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Tue Mar 03 17:13:51 2015 -0800
@@ -232,4 +232,9 @@
         updateUsagesInterface(this.guard, guard);
         this.guard = guard;
     }
+
+    @Override
+    public AbstractBeginNode getPrimarySuccessor() {
+        return this.next();
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java	Tue Mar 03 17:13:51 2015 -0800
@@ -30,7 +30,6 @@
 
 public final class Block extends AbstractBlockBase<Block> {
 
-    public static final int DISTANCED_DOMINATOR_CACHE = 5;
     protected final AbstractBeginNode beginNode;
 
     protected FixedNode endNode;
@@ -177,28 +176,10 @@
         this.probability = probability;
     }
 
-    public Block getDistancedDominatorCache() {
-        Block result = this.distancedDominatorCache;
-        if (result == null) {
-            Block current = this;
-            for (int i = 0; i < DISTANCED_DOMINATOR_CACHE; ++i) {
-                current = current.getDominator();
-            }
-            distancedDominatorCache = current;
-            return current;
-        } else {
-            return result;
-        }
-    }
-
     @Override
     public Block getDominator(int distance) {
         Block result = this;
-        int i = 0;
-        for (; i < distance - (DISTANCED_DOMINATOR_CACHE - 1); i += DISTANCED_DOMINATOR_CACHE) {
-            result = result.getDistancedDominatorCache();
-        }
-        for (; i < distance; ++i) {
+        for (int i = 0; i < distance; ++i) {
             result = result.getDominator();
         }
         return result;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java	Tue Mar 03 17:13:51 2015 -0800
@@ -78,6 +78,10 @@
         return reversePostOrder.get(0);
     }
 
+    public Iterable<Block> reversePostOrder() {
+        return reversePostOrder;
+    }
+
     public Iterable<Block> postOrder() {
         return new Iterable<Block>() {
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/OpaqueNode.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/OpaqueNode.java	Tue Mar 03 17:13:51 2015 -0800
@@ -32,13 +32,17 @@
 public final class OpaqueNode extends FloatingNode implements LIRLowerable {
 
     public static final NodeClass<OpaqueNode> TYPE = NodeClass.create(OpaqueNode.class);
-    @Input ValueNode value;
+    @Input protected ValueNode value;
 
     public OpaqueNode(ValueNode value) {
         super(TYPE, value.stamp().unrestricted());
         this.value = value;
     }
 
+    public ValueNode getValue() {
+        return value;
+    }
+
     @Override
     public void generate(NodeLIRBuilderTool gen) {
         gen.setResult(this, gen.operand(value));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java	Tue Mar 03 17:13:51 2015 -0800
@@ -159,4 +159,9 @@
         }
         return successors.get(defaultSuccessorIndex());
     }
+
+    @Override
+    public AbstractBeginNode getPrimarySuccessor() {
+        return this.defaultSuccessor();
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.options.test/src/com/oracle/graal/options/test/NestedBooleanOptionValueTest.java	Tue Mar 03 17:13:51 2015 -0800
@@ -0,0 +1,128 @@
+/*
+ * 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.test;
+
+import static com.oracle.graal.options.test.NestedBooleanOptionValueTest.Options.*;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+
+import com.oracle.graal.options.*;
+import com.oracle.graal.options.OptionValue.OverrideScope;
+
+public class NestedBooleanOptionValueTest {
+
+    public static class Options {
+        public static final OptionValue<Boolean> Master0 = new OptionValue<>(true);
+        public static final OptionValue<Boolean> NestedOption0 = new NestedBooleanOptionValue(Master0, true);
+        public static final OptionValue<Boolean> Master1 = new OptionValue<>(true);
+        public static final OptionValue<Boolean> NestedOption1 = new NestedBooleanOptionValue(Master1, true);
+        public static final OptionValue<Boolean> Master2 = new OptionValue<>(true);
+        public static final OptionValue<Boolean> NestedOption2 = new NestedBooleanOptionValue(Master2, false);
+    }
+
+    static final OptionDescriptor master0 = new OptionDescriptor("Master0", Boolean.class, "", Options.class, "Master0", Master0);
+    static final OptionDescriptor nestedOption0 = new OptionDescriptor("NestedOption0", Boolean.class, "", Options.class, "NestedOption0", NestedOption0);
+    static final OptionDescriptor master1 = new OptionDescriptor("Master1", Boolean.class, "", Options.class, "Master1", Master1);
+    static final OptionDescriptor nestedOption1 = new OptionDescriptor("NestedOption1", Boolean.class, "", Options.class, "NestedOption1", NestedOption1);
+    static final OptionDescriptor master2 = new OptionDescriptor("Master2", Boolean.class, "", Options.class, "Master2", Master2);
+    static final OptionDescriptor nestedOption2 = new OptionDescriptor("NestedOption2", Boolean.class, "", Options.class, "NestedOption2", NestedOption2);
+
+    @Test
+    public void runOverrides() {
+        assertTrue(Master0.getValue());
+        assertTrue(NestedOption0.getValue());
+        try (OverrideScope s1 = OptionValue.override(Master0, false)) {
+            assertFalse(Master0.getValue());
+            assertFalse(NestedOption0.getValue());
+            try (OverrideScope s2 = OptionValue.override(NestedOption0, false)) {
+                assertFalse(NestedOption0.getValue());
+            }
+            try (OverrideScope s2 = OptionValue.override(NestedOption0, true)) {
+                assertTrue(NestedOption0.getValue());
+            }
+        }
+        assertTrue(Master0.getValue());
+        try (OverrideScope s1 = OptionValue.override(NestedOption0, false)) {
+            assertFalse(NestedOption0.getValue());
+        }
+        try (OverrideScope s1 = OptionValue.override(NestedOption0, true)) {
+            assertTrue(NestedOption0.getValue());
+        }
+    }
+
+    @Test
+    public void runDefaultTrue() {
+        Master1.setValue(true);
+        assertTrue(Master1.getValue());
+        assertTrue(NestedOption1.getValue());
+        // nested value unset
+        Master1.setValue(false);
+        assertFalse(Master1.getValue());
+        assertFalse(NestedOption1.getValue());
+        // set false
+        Master1.setValue(false);
+        NestedOption1.setValue(false);
+        assertFalse(Master1.getValue());
+        assertFalse(NestedOption1.getValue());
+        Master1.setValue(true);
+        assertTrue(Master1.getValue());
+        assertFalse(NestedOption1.getValue());
+        // set true
+        Master1.setValue(false);
+        NestedOption1.setValue(true);
+        assertFalse(Master1.getValue());
+        assertTrue(NestedOption1.getValue());
+        Master1.setValue(true);
+        assertTrue(Master1.getValue());
+        assertTrue(NestedOption1.getValue());
+    }
+
+    @Test
+    public void runDefaultFalse() {
+        Master2.setValue(true);
+        assertTrue(Master2.getValue());
+        assertFalse(NestedOption2.getValue());
+        // nested value unset
+        Master2.setValue(false);
+        assertFalse(Master2.getValue());
+        assertFalse(NestedOption2.getValue());
+        // set false
+        Master2.setValue(false);
+        NestedOption2.setValue(false);
+        assertFalse(Master2.getValue());
+        assertFalse(NestedOption2.getValue());
+        Master2.setValue(true);
+        assertTrue(Master2.getValue());
+        assertFalse(NestedOption2.getValue());
+        // set true
+        Master2.setValue(false);
+        NestedOption2.setValue(true);
+        assertFalse(Master2.getValue());
+        assertTrue(NestedOption2.getValue());
+        Master2.setValue(true);
+        assertTrue(Master2.getValue());
+        assertTrue(NestedOption2.getValue());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/NestedBooleanOptionValue.java	Tue Mar 03 17:13:51 2015 -0800
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.options;
+
+/**
+ * A nested Boolean {@link OptionValue} that can be overridden by a {@link #masterOption master
+ * option}.
+ * <p>
+ * <li>If the option is present on the command line the specified value is used.
+ * <li>Otherwise {@link #getValue()} depends on the {@link #masterOption} and evaluates as follows:
+ * <ul>
+ * <li>If {@link #masterOption} is set, this value equals to {@link #initialValue}.
+ * <li>Otherwise, if {@link #masterOption} is {@code false}, this option is {@code false}.
+ */
+public class NestedBooleanOptionValue extends OptionValue<Boolean> {
+    private final OptionValue<Boolean> masterOption;
+    private final Boolean initialValue;
+
+    public NestedBooleanOptionValue(OptionValue<Boolean> masterOption, Boolean initialValue) {
+        super(null);
+        this.masterOption = masterOption;
+        this.initialValue = initialValue;
+    }
+
+    public OptionValue<Boolean> getMasterOption() {
+        return masterOption;
+    }
+
+    @Override
+    public Boolean getValue() {
+        Boolean v = super.getValue();
+        if (v == null) {
+            return initialValue && masterOption.getValue();
+        }
+        return v;
+    }
+
+}
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Tue Mar 03 17:13:51 2015 -0800
@@ -163,7 +163,8 @@
             StructuredGraph graph = guard.graph();
             AbstractBeginNode fastPath = graph.add(new BeginNode());
             @SuppressWarnings("deprecation")
-            DeoptimizeNode deopt = graph.add(new DeoptimizeNode(guard.action(), guard.reason(), useGuardIdAsDebugId ? guard.getId() : 0, guard.getSpeculation(), null));
+            int debugId = useGuardIdAsDebugId ? guard.getId() : DeoptimizeNode.DEFAULT_DEBUG_ID;
+            DeoptimizeNode deopt = graph.add(new DeoptimizeNode(guard.action(), guard.reason(), debugId, guard.getSpeculation(), null));
             AbstractBeginNode deoptBranch = BeginNode.begin(deopt);
             AbstractBeginNode trueSuccessor;
             AbstractBeginNode falseSuccessor;
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java	Tue Mar 03 17:13:51 2015 -0800
@@ -26,8 +26,6 @@
 
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
-import com.oracle.graal.debug.DebugMemUseTracker.Closeable;
-import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 
@@ -96,7 +94,7 @@
     }
 
     public final void apply(final StructuredGraph graph, final C context, final boolean dumpGraph) {
-        try (TimerCloseable a = timer.start(); Scope s = Debug.scope(getClass(), this); Closeable c = memUseTracker.start()) {
+        try (DebugCloseable a = timer.start(); Scope s = Debug.scope(getClass(), this); DebugCloseable c = memUseTracker.start()) {
             if (dumpGraph && Debug.isDumpEnabled(BEFORE_PHASE_DUMP_LEVEL)) {
                 Debug.dump(BEFORE_PHASE_DUMP_LEVEL, graph, "Before phase %s", getName());
             }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Tue Mar 03 17:13:51 2015 -0800
@@ -42,7 +42,6 @@
 import com.oracle.graal.phases.graph.*;
 import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure;
 import com.oracle.graal.phases.graph.ReentrantBlockIterator.LoopInfo;
-import com.oracle.graal.phases.util.*;
 
 public final class SchedulePhase extends Phase {
 
@@ -321,7 +320,7 @@
 
     @Override
     protected void run(StructuredGraph graph) {
-        assert GraphOrder.assertNonCyclicGraph(graph);
+        // assert GraphOrder.assertNonCyclicGraph(graph);
         cfg = ControlFlowGraph.compute(graph, true, true, true, false);
         earliestCache = graph.createNodeMap();
         blockToNodesMap = new BlockMap<>(cfg);
@@ -330,6 +329,11 @@
             blockToKillSet = new BlockMap<>(cfg);
         }
 
+        if (selectedStrategy == SchedulingStrategy.EARLIEST) {
+            scheduleEarliestIterative(blockToNodesMap, graph);
+            return;
+        }
+
         assignBlockToNodes(graph, selectedStrategy);
         printSchedule("after assign nodes to blocks");
 
@@ -337,6 +341,146 @@
         printSchedule("after sorting nodes within blocks");
     }
 
+    private void scheduleEarliestIterative(BlockMap<List<ValueNode>> blockToNodes, StructuredGraph graph) {
+        NodeMap<Block> nodeToBlock = graph.createNodeMap();
+        NodeBitMap visited = graph.createNodeBitMap();
+
+        // Add begin nodes as the first entry and set the block for phi nodes.
+        for (Block b : cfg.getBlocks()) {
+            AbstractBeginNode beginNode = b.getBeginNode();
+            ArrayList<ValueNode> nodes = new ArrayList<>();
+            nodeToBlock.set(beginNode, b);
+            nodes.add(beginNode);
+            blockToNodes.put(b, nodes);
+
+            if (beginNode instanceof AbstractMergeNode) {
+                AbstractMergeNode mergeNode = (AbstractMergeNode) beginNode;
+                for (PhiNode phi : mergeNode.phis()) {
+                    nodeToBlock.set(phi, b);
+                }
+            }
+        }
+
+        Stack<Node> stack = new Stack<>();
+
+        // Start analysis with control flow ends.
+        for (Block b : cfg.postOrder()) {
+            FixedNode endNode = b.getEndNode();
+            stack.push(endNode);
+            nodeToBlock.set(endNode, b);
+        }
+
+        processStack(blockToNodes, nodeToBlock, visited, stack);
+
+        // Visit back input edges of loop phis.
+        for (LoopBeginNode loopBegin : graph.getNodes(LoopBeginNode.TYPE)) {
+            for (PhiNode phi : loopBegin.phis()) {
+                if (visited.isMarked(phi)) {
+                    for (int i = 0; i < loopBegin.getLoopEndCount(); ++i) {
+                        Node node = phi.valueAt(i + loopBegin.forwardEndCount());
+                        if (!visited.isMarked(node)) {
+                            stack.push(node);
+                            processStack(blockToNodes, nodeToBlock, visited, stack);
+                        }
+                    }
+                }
+            }
+        }
+
+        // Check for dead nodes.
+        if (visited.getCounter() < graph.getNodeCount()) {
+            for (Node n : graph.getNodes()) {
+                if (!visited.isMarked(n)) {
+                    n.clearInputs();
+                    n.markDeleted();
+                }
+            }
+        }
+
+        // Add end nodes as the last nodes in each block.
+        for (Block b : cfg.getBlocks()) {
+            FixedNode endNode = b.getEndNode();
+            if (endNode != b.getBeginNode()) {
+                addNode(blockToNodes, b, endNode);
+            }
+        }
+
+        this.blockToNodesMap = blockToNodes;
+    }
+
+    private static void addNode(BlockMap<List<ValueNode>> blockToNodes, Block b, ValueNode endNode) {
+        assert !blockToNodes.get(b).contains(endNode) : endNode;
+        blockToNodes.get(b).add(endNode);
+    }
+
+    private void processStack(BlockMap<List<ValueNode>> blockToNodes, NodeMap<Block> nodeToBlock, NodeBitMap visited, Stack<Node> stack) {
+        Block startBlock = cfg.getStartBlock();
+        while (!stack.isEmpty()) {
+            Node current = stack.peek();
+            if (visited.checkAndMarkInc(current)) {
+
+                // Push inputs and predecessor.
+                Node predecessor = current.predecessor();
+                if (predecessor != null) {
+                    stack.push(predecessor);
+                }
+
+                if (current instanceof PhiNode) {
+                    PhiNode phiNode = (PhiNode) current;
+                    AbstractMergeNode merge = phiNode.merge();
+                    for (int i = 0; i < merge.forwardEndCount(); ++i) {
+                        Node input = phiNode.valueAt(i);
+                        stack.push(input);
+                    }
+                } else {
+                    for (Node input : current.inputs()) {
+                        if (current instanceof FrameState && input instanceof StateSplit && ((StateSplit) input).stateAfter() == current) {
+                            // Ignore the cycle.
+                        } else {
+                            stack.push(input);
+                        }
+                    }
+                }
+            } else {
+
+                stack.pop();
+
+                if (nodeToBlock.get(current) == null) {
+                    Node predecessor = current.predecessor();
+                    Block curBlock;
+                    if (predecessor != null) {
+                        // Predecessor determines block.
+                        curBlock = nodeToBlock.get(predecessor);
+                    } else {
+                        Block earliest = startBlock;
+                        for (Node input : current.inputs()) {
+                            if (current instanceof FrameState && input instanceof StateSplit && ((StateSplit) input).stateAfter() == current) {
+                                // ignore
+                            } else {
+                                Block inputEarliest;
+                                if (input instanceof ControlSplitNode) {
+                                    inputEarliest = nodeToBlock.get(((ControlSplitNode) input).getPrimarySuccessor());
+                                } else {
+                                    inputEarliest = nodeToBlock.get(input);
+                                }
+                                assert inputEarliest != null : current + " / " + input;
+                                if (earliest.getDominatorDepth() < inputEarliest.getDominatorDepth()) {
+                                    earliest = inputEarliest;
+                                }
+                            }
+                        }
+                        curBlock = earliest;
+                    }
+                    assert curBlock != null;
+                    if (current instanceof ValueNode) {
+                        addNode(blockToNodes, curBlock, (ValueNode) current);
+                    }
+                    nodeToBlock.set(current, curBlock);
+                }
+            }
+        }
+    }
+
     private Block blockForMemoryNode(MemoryNode memory) {
         MemoryNode current = memory;
         while (current instanceof MemoryProxy) {
@@ -982,25 +1126,8 @@
         List<ValueNode> sortedInstructions = state.getSortedInstructions();
         Node lastSorted = sortedInstructions.get(sortedInstructions.size() - 1);
         if (lastSorted != b.getEndNode()) {
-            int idx = sortedInstructions.indexOf(b.getEndNode());
-            boolean canNotMove = false;
-            for (int i = idx + 1; i < sortedInstructions.size(); i++) {
-                if (sortedInstructions.get(i).inputs().contains(b.getEndNode())) {
-                    canNotMove = true;
-                    break;
-                }
-            }
-            if (canNotMove) {
-                if (b.getEndNode() instanceof ControlSplitNode) {
-                    throw new GraalGraphInternalError("Schedule is not possible : needs to move a node after the last node of the block which can not be move").addContext(lastSorted).addContext(
-                                    b.getEndNode());
-                }
-
-                // b.setLastNode(lastSorted);
-            } else {
-                sortedInstructions.remove(b.getEndNode());
-                sortedInstructions.add(b.getEndNode());
-            }
+            sortedInstructions.remove(b.getEndNode());
+            sortedInstructions.add(b.getEndNode());
         }
         return sortedInstructions;
     }
@@ -1082,8 +1209,9 @@
         addUnscheduledToLatestSorting(stateAfter, state);
 
         // Now predecessors and inputs are scheduled => we can add this node.
-        assert !state.containsInstruction(i);
-        state.addInstruction(i);
+        if (!state.containsInstruction(i)) {
+            state.addInstruction(i);
+        }
 
         if (state.readsSize() != 0 && i instanceof FloatingReadNode) {
             state.removeRead(i);
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java	Tue Mar 03 17:13:51 2015 -0800
@@ -182,7 +182,7 @@
         return sb.toString();
     }
 
-    protected String valueToString(JavaValue value, List<VirtualObject> virtualObjects) {
+    protected String valueToString(Value value, List<VirtualObject> virtualObjects) {
         if (value == null) {
             return "-";
         }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/DeoptimizeOnExceptionTest.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/DeoptimizeOnExceptionTest.java	Tue Mar 03 17:13:51 2015 -0800
@@ -26,6 +26,7 @@
 
 import org.junit.*;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.phases.common.*;
 
@@ -67,9 +68,13 @@
             Class<Runnable> c = (Class<Runnable>) testCl.loadClass(name);
             Runnable r = c.newInstance();
             ct = Long.MAX_VALUE;
-            for (int i = 0; i < 100000000; i++) {
+            // warmup
+            for (int i = 0; i < 100; i++) {
                 r.run();
             }
+            // compile
+            ResolvedJavaMethod method = getResolvedJavaMethod(c, "run");
+            getCode(method);
             ct = 0;
             r.run();
         } catch (Throwable e) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java	Tue Mar 03 17:13:51 2015 -0800
@@ -259,6 +259,7 @@
         memoryRead.setStateAfter(n.stateAfter());
 
         ValueNode readValue = implicitLoadConvert(graph, valueKind, memoryRead);
+        n.stateAfter().replaceFirstInput(n, memoryRead);
         n.replaceAtUsages(readValue);
         graph.replaceFixedWithFixed(n, memoryRead);
     }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Tue Mar 03 17:13:51 2015 -0800
@@ -41,7 +41,6 @@
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
-import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.Graph.Mark;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.java.*;
@@ -262,7 +261,7 @@
 
         StructuredGraph graph = UseSnippetGraphCache ? graphs.get(method) : null;
         if (graph == null) {
-            try (TimerCloseable a = SnippetPreparationTime.start()) {
+            try (DebugCloseable a = SnippetPreparationTime.start()) {
                 FrameStateProcessing frameStateProcessing = method.getAnnotation(Snippet.class).removeAllFrameStates() ? FrameStateProcessing.Removal
                                 : FrameStateProcessing.CollapseFrameForSingleSideEffect;
                 StructuredGraph newGraph = makeGraph(method, recursiveEntry, inliningPolicy(method), frameStateProcessing);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Tue Mar 03 17:13:51 2015 -0800
@@ -43,7 +43,6 @@
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
-import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.Graph.Mark;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node;
@@ -520,7 +519,7 @@
             SnippetTemplate template = UseSnippetTemplateCache ? templates.get(args.cacheKey) : null;
             if (template == null) {
                 SnippetTemplates.increment();
-                try (TimerCloseable a = SnippetTemplateCreationTime.start(); Scope s = Debug.scope("SnippetSpecialization", args.info.method)) {
+                try (DebugCloseable a = SnippetTemplateCreationTime.start(); Scope s = Debug.scope("SnippetSpecialization", args.info.method)) {
                     template = new SnippetTemplate(providers, snippetReflection, args);
                     if (UseSnippetTemplateCache) {
                         templates.put(args.cacheKey, template);
@@ -1099,7 +1098,7 @@
      */
     public Map<Node, Node> instantiate(MetaAccessProvider metaAccess, FixedNode replacee, UsageReplacer replacer, Arguments args) {
         assert assertSnippetKills(replacee);
-        try (TimerCloseable a = args.info.instantiationTimer.start(); TimerCloseable b = instantiationTimer.start()) {
+        try (DebugCloseable a = args.info.instantiationTimer.start(); DebugCloseable b = instantiationTimer.start()) {
             args.info.instantiationCounter.increment();
             instantiationCounter.increment();
             // Inline the snippet nodes, replacing parameters with the given args in the process
@@ -1246,7 +1245,7 @@
      */
     public void instantiate(MetaAccessProvider metaAccess, FloatingNode replacee, UsageReplacer replacer, LoweringTool tool, Arguments args) {
         assert assertSnippetKills(replacee);
-        try (TimerCloseable a = args.info.instantiationTimer.start()) {
+        try (DebugCloseable a = args.info.instantiationTimer.start()) {
             args.info.instantiationCounter.increment();
             instantiationCounter.increment();
 
--- a/graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java	Tue Mar 03 17:13:51 2015 -0800
@@ -22,25 +22,23 @@
  */
 package com.oracle.graal.truffle.hotspot.sparc;
 
-import com.oracle.graal.api.code.CallingConvention.Type;
+import static com.oracle.graal.api.code.CallingConvention.Type.*;
+import static com.oracle.graal.api.meta.Kind.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*;
+import static com.oracle.graal.sparc.SPARC.CPUFeature.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Bpe;
-import com.oracle.graal.asm.sparc.SPARCAssembler.CBcondx;
-import com.oracle.graal.asm.sparc.SPARCAssembler.CC;
-import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Jmp;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.framemap.*;
-import com.oracle.graal.sparc.SPARC.CPUFeature;
 import com.oracle.graal.sparc.*;
 import com.oracle.graal.truffle.*;
 import com.oracle.graal.truffle.hotspot.*;
@@ -56,23 +54,23 @@
                 @SuppressWarnings("hiding")
                 SPARCMacroAssembler asm = (SPARCMacroAssembler) this.asm;
                 try (SPARCScratchRegister scratch = SPARCScratchRegister.get()) {
-                    Register thisRegister = codeCache.getRegisterConfig().getCallingConventionRegisters(Type.JavaCall, Kind.Object)[0];
+                    Register thisRegister = codeCache.getRegisterConfig().getCallingConventionRegisters(JavaCall, Object)[0];
                     Register spillRegister = scratch.getRegister();
                     Label doProlog = new Label();
                     SPARCAddress codeBlobAddress = new SPARCAddress(thisRegister, getFieldOffset("address", InstalledCode.class));
                     SPARCAddress verifiedEntryPointAddress = new SPARCAddress(spillRegister, config.nmethodEntryOffset);
 
-                    new Ldx(codeBlobAddress, spillRegister).emit(asm);
-                    if (asm.hasFeature(CPUFeature.CBCOND)) {
-                        new CBcondx(ConditionFlag.Equal, spillRegister, 0, doProlog).emit(asm);
+                    asm.ldx(codeBlobAddress, spillRegister);
+                    if (asm.hasFeature(CBCOND)) {
+                        asm.cbcondx(Equal, spillRegister, 0, doProlog);
                     } else {
-                        new Cmp(spillRegister, 0).emit(asm);
-                        new Bpe(CC.Xcc, doProlog).emit(asm);
-                        new Nop().emit(asm);
+                        asm.cmp(spillRegister, 0);
+                        asm.bpcc(Equal, NOT_ANNUL, doProlog, Xcc, PREDICT_NOT_TAKEN);
+                        asm.nop();
                     }
-                    new Ldx(verifiedEntryPointAddress, spillRegister).emit(asm); // in delay slot
-                    new Jmp(spillRegister).emit(asm);
-                    new Nop().emit(asm);
+                    asm.ldx(verifiedEntryPointAddress, spillRegister); // in delay slot
+                    asm.jmp(spillRegister);
+                    asm.nop();
                     asm.bind(doProlog);
                 }
             }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Tue Mar 03 17:13:51 2015 -0800
@@ -36,8 +36,6 @@
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
-import com.oracle.graal.debug.DebugMemUseTracker.Closeable;
-import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.phases.*;
@@ -131,7 +129,7 @@
         try {
             PhaseSuite<HighTierContext> graphBuilderSuite = createGraphBuilderSuite();
 
-            try (TimerCloseable a = PartialEvaluationTime.start(); Closeable c = PartialEvaluationMemUse.start()) {
+            try (DebugCloseable a = PartialEvaluationTime.start(); DebugCloseable c = PartialEvaluationMemUse.start()) {
                 graph = partialEvaluator.createGraph(compilable, AllowAssumptions.YES);
             }
 
@@ -157,7 +155,7 @@
         }
 
         CompilationResult result = null;
-        try (TimerCloseable a = CompilationTime.start(); Scope s = Debug.scope("TruffleGraal.GraalCompiler", graph, providers.getCodeCache()); Closeable c = CompilationMemUse.start()) {
+        try (DebugCloseable a = CompilationTime.start(); Scope s = Debug.scope("TruffleGraal.GraalCompiler", graph, providers.getCodeCache()); DebugCloseable c = CompilationMemUse.start()) {
             CodeCacheProvider codeCache = providers.getCodeCache();
             CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false);
             CompilationResult compilationResult = new CompilationResult(name);
@@ -190,7 +188,7 @@
         result.setAssumptions(newAssumptions.toArray(new Assumption[newAssumptions.size()]));
 
         InstalledCode installedCode;
-        try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache()); TimerCloseable a = CodeInstallationTime.start(); Closeable c = CodeInstallationMemUse.start()) {
+        try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache()); DebugCloseable a = CodeInstallationTime.start(); DebugCloseable c = CodeInstallationMemUse.start()) {
             installedCode = providers.getCodeCache().addMethod(graph.method(), result, speculationLog, predefinedInstalledCode);
         } catch (Throwable e) {
             throw Debug.handle(e);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java	Tue Mar 03 17:11:46 2015 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java	Tue Mar 03 17:13:51 2015 -0800
@@ -34,8 +34,8 @@
 public abstract class IntegerExactArithmeticSplitNode extends ControlSplitNode implements LIRLowerable {
     public static final NodeClass<IntegerExactArithmeticSplitNode> TYPE = NodeClass.create(IntegerExactArithmeticSplitNode.class);
 
+    @Successor AbstractBeginNode next;
     @Successor AbstractBeginNode overflowSuccessor;
-    @Successor AbstractBeginNode next;
     @Input ValueNode x;
     @Input ValueNode y;
 
@@ -48,6 +48,11 @@
     }
 
     @Override
+    public AbstractBeginNode getPrimarySuccessor() {
+        return next;
+    }
+
+    @Override
     public double probability(AbstractBeginNode successor) {
         return successor == next ? 1 : 0;
     }
--- a/mx/mx_graal.py	Tue Mar 03 17:11:46 2015 -0800
+++ b/mx/mx_graal.py	Tue Mar 03 17:13:51 2015 -0800
@@ -2107,6 +2107,8 @@
     flavor = 'intel'
     if 'att' in args:
         flavor = 'att'
+    if mx.get_arch() == "sparcv9":
+        flavor = "sparcv9"
     lib = mx.add_lib_suffix('hsdis-' + mx.get_arch())
     path = join(_graal_home, 'lib', lib)
 
@@ -2116,6 +2118,7 @@
         'intel/hsdis-amd64.dll' : '6a388372cdd5fe905c1a26ced614334e405d1f30',
         'intel/hsdis-amd64.so' : '844ed9ffed64fe9599638f29a8450c50140e3192',
         'intel/hsdis-amd64.dylib' : 'fdb13ef0d7d23d93dacaae9c98837bea0d4fc5a2',
+        'sparcv9/hsdis-sparcv9.so': '5f79c312b3dcc55bad551dbb710b11f0048a4ce7',
     }
 
     flavoredLib = flavor + "/" + lib
--- a/src/share/vm/graal/graalJavaAccess.hpp	Tue Mar 03 17:11:46 2015 -0800
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Tue Mar 03 17:13:51 2015 -0800
@@ -169,7 +169,7 @@
     typeArrayOop_field(BitSet, words, "[J")                                                                                                                    \
   end_class                                                                                                                                                    \
   start_class(BytecodeFrame)                                                                                                                                   \
-    objArrayOop_field(BytecodeFrame, values, "[Lcom/oracle/graal/api/meta/JavaValue;")                                                                         \
+    objArrayOop_field(BytecodeFrame, values, "[Lcom/oracle/graal/api/meta/Value;")                                                                             \
     int_field(BytecodeFrame, numLocals)                                                                                                                        \
     int_field(BytecodeFrame, numStack)                                                                                                                         \
     int_field(BytecodeFrame, numLocks)                                                                                                                         \
@@ -241,10 +241,10 @@
   start_class(VirtualObject)                                                                                                                                   \
     int_field(VirtualObject, id)                                                                                                                               \
     oop_field(VirtualObject, type, "Lcom/oracle/graal/api/meta/ResolvedJavaType;")                                                                             \
-    objArrayOop_field(VirtualObject, values, "[Lcom/oracle/graal/api/meta/JavaValue;")                                                                         \
+    objArrayOop_field(VirtualObject, values, "[Lcom/oracle/graal/api/meta/Value;")                                                                             \
   end_class                                                                                                                                                    \
-  start_class(StackLockValue)                                                                                                                                 \
-    oop_field(StackLockValue, owner, "Lcom/oracle/graal/api/meta/JavaValue;")                                                                                  \
+  start_class(StackLockValue)                                                                                                                                  \
+    oop_field(StackLockValue, owner, "Lcom/oracle/graal/api/meta/Value;")                                                                                      \
     oop_field(StackLockValue, slot, "Lcom/oracle/graal/api/code/StackSlotValue;")                                                                              \
     boolean_field(StackLockValue, eliminated)                                                                                                                  \
   end_class                                                                                                                                                    \
--- a/src/share/vm/graal/vmStructs_graal.hpp	Tue Mar 03 17:11:46 2015 -0800
+++ b/src/share/vm/graal/vmStructs_graal.hpp	Tue Mar 03 17:13:51 2015 -0800
@@ -39,6 +39,7 @@
   nonstatic_field(GraalEnv,      _jvmti_can_hotswap_or_post_breakpoint, bool) \
 
 #define VM_TYPES_GRAAL(declare_type, declare_toplevel_type)                   \
+  declare_toplevel_type(GraalEnv)                                             \
 
 #define VM_INT_CONSTANTS_GRAAL(declare_constant, declare_preprocessor_constant)                   \
   declare_constant(Deoptimization::Reason_unreached0)                                             \
--- a/src/share/vm/runtime/deoptimization.cpp	Tue Mar 03 17:11:46 2015 -0800
+++ b/src/share/vm/runtime/deoptimization.cpp	Tue Mar 03 17:13:51 2015 -0800
@@ -1405,6 +1405,7 @@
     ScopeDesc*      trap_scope  = cvf->scope();
     
     if (TraceDeoptimization) {
+      ttyLocker ttyl;
       tty->print_cr("  bci=%d pc=" INTPTR_FORMAT ", relative_pc=%d, method=%s" GRAAL_ONLY(", debug_id=%d"), trap_scope->bci(), fr.pc(), fr.pc() - nm->code_begin(), trap_scope->method()->name_and_sig_as_C_string()
 #ifdef GRAAL
           , debug_id