changeset 19668:413ac504d74e

[SPARC] Simplify branch instructions (No more object allocations), Tidy up SPARCControlFlow and SPARCAssembler
author Stefan Anzinger <stefan.anzinger@oracle.com>
date Fri, 27 Feb 2015 09:18:23 +0100
parents afe80ca4b0f0
children f6a01e64a87a
files graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java
diffstat 9 files changed, 446 insertions(+), 1209 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Fri Feb 13 17:42:58 2015 +0100
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Fri Feb 27 09:18:23 2015 +0100
@@ -60,6 +60,17 @@
     public static final int CCR_Z_SHIFT = 2;
     public static final int CCR_N_SHIFT = 3;
 
+    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
     /**
      * Instruction format for Fmt00 instructions. This abstraction is needed as it
@@ -72,48 +83,12 @@
     // @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);
@@ -131,11 +106,13 @@
             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)
+         * @param imm Displacement/imediate value. Can either be a 22 or 19 bit immediate (dependent
+         *            on the instruction)
          */
         public abstract void setImm(int imm);
 
@@ -148,6 +125,7 @@
         public int getA() {
             throw GraalInternalError.shouldNotReachHere();
         }
+
         public void setA(@SuppressWarnings("unused") int a) {
             throw GraalInternalError.shouldNotReachHere();
         }
@@ -234,415 +212,16 @@
         }
     }
 
-    // @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();
-        }
-
-        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;
-        }
-    }
+    protected static final int DISP22_SHIFT = 0;
+    protected static final int DISP22_MASK = 0b00000000001111111111111111111111;
+
+    protected static final int DISP19_SHIFT = 0;
+    protected static final int DISP19_MASK = 0b00000000000001111111111111111111;
+
+    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
     /**
@@ -654,24 +233,24 @@
      */
     // @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;
+        protected static final int CHI_SHIFT = 29;
+        protected static final int CLO_SHIFT = 25;
+        protected static final int CC2_SHIFT = 21;
+        protected static final int D10HI_SHIFT = 19;
+        protected static final int RS1_SHIFT = 14;
+        protected static final int I_SHIFT = 13;
+        protected static final int D10LO_SHIFT = 5;
+        protected 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;
+        protected static final int CHI_MASK      = 0b0010_0000_0000_0000_0000_0000_0000_0000;
+        protected static final int CLO_MASK      = 0b0000_1110_0000_0000_0000_0000_0000_0000;
+        protected static final int CC2_MASK      = 0b0000_0000_0010_0000_0000_0000_0000_0000;
+        protected static final int D10HI_MASK    = 0b0000_0000_0001_1000_0000_0000_0000_0000;
+        protected static final int RS1_MASK      = 0b0000_0000_0000_0111_1100_0000_0000_0000;
+        protected static final int I_MASK        = 0b0000_0000_0000_0000_0010_0000_0000_0000;
+        protected static final int D10LO_MASK    = 0b0000_0000_0000_0000_0001_1111_1110_0000;
+        protected static final int RS2_MASK      = 0b0000_0000_0000_0000_0000_0000_0001_1111;
         // @formatter:on
 
         private int c;
@@ -809,11 +388,9 @@
     // @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
 
@@ -995,7 +572,6 @@
     // @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;
@@ -1006,7 +582,6 @@
         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;
@@ -1147,7 +722,6 @@
     // @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;
@@ -1157,7 +731,6 @@
         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;
@@ -1292,7 +865,6 @@
     // @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;
@@ -1304,7 +876,6 @@
         private static final int SIMM11_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 CC2_MASK    = 0b00000000000001000000000000000000;
@@ -1417,7 +988,6 @@
     // @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;
@@ -1895,6 +1465,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
 
@@ -1961,40 +1551,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 +1686,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 +1744,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);
             }
@@ -2256,6 +1852,11 @@
         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.
      */
@@ -2317,6 +1918,149 @@
         return x & ((1 << 10) - 1);
     }
 
+    // @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);
+    }
+
+    // @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);
+    }
+
+    // @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);
+    }
+
+    // @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);
+    }
+
+    // @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);
+    }
+
+    // @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);
+    }
+
+    // @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);
+    }
+
+    // @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);
+    }
+
+    // @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);
+    }
+
+    private int patchUnbound(Label label) {
+        label.addPatchAt(position());
+        return 0;
+    }
+
     public static class Add extends Fmt10 {
 
         public Add(Register src1, int simm13, Register dst) {
@@ -2592,232 +2336,6 @@
         }
     }
 
-    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);
-        }
-    }
-
-    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);
-        }
-    }
-
-    public static class Bpe extends Fmt00c {
-
-        public Bpe(CC cc, int simm19) {
-            super(0, ConditionFlag.Equal, Op2s.Bp, cc, 1, simm19);
-        }
-
-        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 static class Bpg extends Fmt00c {
-
-        public Bpg(CC cc, int simm19) {
-            super(0, ConditionFlag.Greater, Op2s.Bp, cc, 1, simm19);
-        }
-
-        public Bpg(CC cc, Label label) {
-            super(0, ConditionFlag.Greater, Op2s.Bp, cc, 1, label);
-        }
-
-        public Bpg(CC cc, boolean annul, boolean predictTaken, Label label) {
-            super(annul ? 1 : 0, ConditionFlag.Greater, Op2s.Bp, cc, predictTaken ? 1 : 0, label);
-        }
-    }
-
-    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);
-        }
-    }
-
-    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);
-        }
-    }
-
-    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 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);
-        }
-    }
-
-    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 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 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 static class Bpvs extends Fmt00c {
-
-        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 static class Bshuffle extends Fmt3p {
 
         public Bshuffle(Register src1, Register src2, Register dst) {
@@ -3664,166 +3182,6 @@
         }
     }
 
-    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);
-        }
-    }
-
-    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);
-        }
-    }
-
-    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 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) {
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Fri Feb 13 17:42:58 2015 +0100
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Fri Feb 27 09:18:23 2015 +0100
@@ -22,10 +22,13 @@
  */
 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 com.oracle.graal.api.code.*;
 import com.oracle.graal.asm.*;
+import com.oracle.graal.compiler.common.*;
 
 public class SPARCMacroAssembler extends SPARCAssembler {
 
@@ -48,16 +51,58 @@
 
     @Override
     public void jmp(Label l) {
-        new Bpa(l).emit(this);
+        bicc(Always, NOT_ANNUL, l);
         new Nop().emit(this);  // 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) << Fmt00e.D10HI_SHIFT - 8;
+                    d10Split |= (disp & 0b00_1111_1111) << Fmt00e.D10LO_SHIFT;
+                    setBits = d10Split;
+                    maskBits = Fmt00e.D10LO_MASK | Fmt00e.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
@@ -86,36 +131,6 @@
         }
     }
 
-    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 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 static class Bset extends Or {
 
         public Bset(Register src, Register dst) {
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Fri Feb 13 17:42:58 2015 +0100
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Fri Feb 27 09:18:23 2015 +0100
@@ -215,7 +215,7 @@
                     double trueDestinationProbability) {
         Variable left;
         Value right;
-        Condition actualCondition = null;
+        Condition actualCondition;
         if (isConstant(x)) {
             left = load(y);
             right = loadNonConst(x);
@@ -225,7 +225,7 @@
             right = loadNonConst(y);
             actualCondition = cond;
         }
-        SPARCCompare opcode = null;
+        SPARCCompare opcode;
         Kind kind = left.getKind().getStackKind();
         switch (kind) {
             case Object:
@@ -247,7 +247,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));
     }
@@ -255,13 +255,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.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Fri Feb 13 17:42:58 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Fri Feb 27 09:18:23 2015 +0100
@@ -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,11 +38,7 @@
 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.SPARCAssembler.*;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.RestoreWindow;
@@ -239,7 +239,7 @@
                     new Ldx(src, scratch).emit(masm);
                     new Cmp(scratch, inlineCacheKlass).emit(masm);
                 }
-                new Bpne(CC.Xcc, unverifiedStub).emit(masm);
+                masm.bpcc(NotEqual, NOT_ANNUL, unverifiedStub, Xcc, PREDICT_NOT_TAKEN);
                 new Nop().emit(masm);  // delay slot
             }
 
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Fri Feb 13 17:42:58 2015 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Fri Feb 27 09:18:23 2015 +0100
@@ -24,7 +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.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 com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
@@ -216,9 +221,9 @@
             // 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);
+            masm.bpcc(Equal, NOT_ANNUL, noOverflow, Xcc, PREDICT_TAKEN);
             new Nop().emit(masm);
-            new Wrccr(SPARC.g0, 1 << (CCR_XCC_SHIFT + CCR_V_SHIFT)).emit(masm);
+            new Wrccr(g0, 1 << (CCR_XCC_SHIFT + CCR_V_SHIFT)).emit(masm);
             masm.bind(noOverflow);
         }
     }
@@ -367,7 +372,7 @@
                         new Nop().emit(masm);
                     } else {
                         new Cmp(tmp, asIntReg(dst)).emit(masm);
-                        new Bpe(CC.Xcc, noOverflow).emit(masm);
+                        masm.bpcc(Equal, NOT_ANNUL, noOverflow, Xcc, PREDICT_TAKEN);
                         new Nop().emit(masm);
                     }
                     new Wrccr(SPARC.g0, 1 << (SPARCAssembler.CCR_ICC_SHIFT + SPARCAssembler.CCR_V_SHIFT)).emit(masm);
@@ -704,14 +709,14 @@
                 break;
             case F2L:
                 new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(src), asFloatReg(src)).emit(masm);
-                new Fbo(true, notOrdered).emit(masm);
+                masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN);
                 new Fstox(asFloatReg(src), asDoubleReg(dst)).emit(masm);
                 new Fsubd(asDoubleReg(dst), asDoubleReg(dst), asDoubleReg(dst)).emit(masm);
                 masm.bind(notOrdered);
                 break;
             case F2I:
                 new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(src), asFloatReg(src)).emit(masm);
-                new Fbo(true, notOrdered).emit(masm);
+                masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN);
                 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);
@@ -719,7 +724,7 @@
                 break;
             case D2L:
                 new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(src), asDoubleReg(src)).emit(masm);
-                new Fbo(false, notOrdered).emit(masm);
+                masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN);
                 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);
@@ -727,7 +732,7 @@
                 break;
             case D2I:
                 new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(src), asDoubleReg(src)).emit(masm);
-                new Fbo(true, notOrdered).emit(masm);
+                masm.fbpcc(F_Ordered, ANNUL, notOrdered, Fcc0, PREDICT_TAKEN);
                 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);
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java	Fri Feb 13 17:42:58 2015 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java	Fri Feb 27 09:18:23 2015 +0100
@@ -27,7 +27,11 @@
 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.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 java.lang.reflect.*;
 
@@ -107,7 +111,7 @@
         // Return true
         masm.bind(trueLabel);
         new Mov(1, result).emit(masm);
-        new Bpa(done).emit(masm);
+        masm.bicc(Always, ANNUL, done);
         new Nop().emit(masm);
 
         // Return false
@@ -138,7 +142,7 @@
 
         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.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);
@@ -155,9 +159,9 @@
             new Nop().emit(masm); // for optimal performance (see manual)
         } else {
             new Cmp(tempReg1, tempReg2).emit(masm);
-            new Bpne(Xcc, true, false, falseLabel).emit(masm);
+            masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_NOT_TAKEN);
             new Nop().emit(masm);
-            new Bpr(RCondition.Rc_z, false, false, length, compareTailCorrectVectorEnd).emit(masm);
+            masm.bpr(Rc_z, NOT_ANNUL, compareTailCorrectVectorEnd, PREDICT_NOT_TAKEN, length);
             new Nop().emit(masm);
         }
 
@@ -166,17 +170,18 @@
         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.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
+        // Annul, to prevent access past the array
+        masm.bpcc(NotEqual, ANNUL, loop, Xcc, PREDICT_TAKEN);
         new Ldx(new SPARCAddress(array1, length), tempReg1).emit(masm); // 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);
         } else {
-            new Bpr(RCondition.Rc_z, true, true, result, trueLabel).emit(masm);
+            masm.bpr(Rc_z, NOT_ANNUL, trueLabel, PREDICT_TAKEN, result);
             new Nop().emit(masm);
         }
 
@@ -205,7 +210,7 @@
                 new CBcondx(ConditionFlag.Less, result, 4, compare2Bytes).emit(masm);
             } else {
                 new Cmp(result, 4).emit(masm);
-                new Bpl(Xcc, false, false, compare2Bytes).emit(masm);
+                masm.bpcc(Less, NOT_ANNUL, compare2Bytes, Xcc, PREDICT_NOT_TAKEN);
                 new Nop().emit(masm);
             }
 
@@ -216,7 +221,7 @@
                 new CBcondx(ConditionFlag.NotEqual, tempReg1, tempReg2, falseLabel).emit(masm);
             } else {
                 new Cmp(tempReg1, tempReg2).emit(masm);
-                new Bpne(Xcc, false, false, falseLabel).emit(masm);
+                masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_NOT_TAKEN);
                 new Nop().emit(masm);
             }
 
@@ -233,7 +238,7 @@
                     new CBcondx(ConditionFlag.Less, result, 2, compare1Byte).emit(masm);
                 } else {
                     new Cmp(result, 2).emit(masm);
-                    new Bpl(Xcc, false, true, compare1Byte).emit(masm);
+                    masm.bpcc(Less, NOT_ANNUL, compare1Byte, Xcc, PREDICT_TAKEN);
                     new Nop().emit(masm);
                 }
 
@@ -244,7 +249,7 @@
                     new CBcondx(ConditionFlag.NotEqual, tempReg1, tempReg2, falseLabel).emit(masm);
                 } else {
                     new Cmp(tempReg1, tempReg2).emit(masm);
-                    new Bpne(Xcc, false, true, falseLabel).emit(masm);
+                    masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_TAKEN);
                     new Nop().emit(masm);
                 }
 
@@ -261,17 +266,16 @@
                         new CBcondx(ConditionFlag.NotEqual, result, 1, trueLabel).emit(masm);
                     } else {
                         new Cmp(result, 1).emit(masm);
-                        new Bpne(Xcc, trueLabel).emit(masm);
+                        masm.bpcc(NotEqual, NOT_ANNUL, trueLabel, Xcc, PREDICT_TAKEN);
                         new Nop().emit(masm);
                     }
                     new Ldub(new SPARCAddress(array1, 0), tempReg1).emit(masm);
                     new Ldub(new SPARCAddress(array2, 0), tempReg2).emit(masm);
                     if (hasCBcond) {
-                        // new SPARCAssembler.Ldx(new SPARCAddress(o7, 1), g3).emit(masm);
                         new CBcondx(ConditionFlag.NotEqual, tempReg1, tempReg2, falseLabel).emit(masm);
                     } else {
                         new Cmp(tempReg1, tempReg2).emit(masm);
-                        new Bpne(Xcc, falseLabel).emit(masm);
+                        masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_TAKEN);
                         new Nop().emit(masm);
                     }
                 } else {
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Fri Feb 13 17:42:58 2015 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Fri Feb 27 09:18:23 2015 +0100
@@ -26,6 +26,10 @@
 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.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 com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
@@ -67,7 +71,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;
@@ -86,12 +90,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
@@ -101,24 +106,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();
+                }
             }
         }
 
@@ -129,7 +142,6 @@
             if (falseDestinationHint == null) {
                 this.falseDestinationHint = masm.requestLabelHint(falseDestination.label());
             }
-
         }
 
         /**
@@ -166,24 +178,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;
@@ -194,9 +207,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 {
@@ -206,7 +218,7 @@
                     SPARCMove.move(crb, masm, scratchValue, actualY, SPARCDelayedControlTransfer.DUMMY);
                     actualY = scratchValue;
                 }
-                emitCBCond(masm, actualX, actualY, actualTrueTarget, conditionFlag);
+                emitCBCond(masm, actualX, actualY, actualTrueTarget, actualConditionFlag);
                 new Nop().emit(masm);
             } finally {
                 if (scratch != null) {
@@ -256,46 +268,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;
@@ -349,172 +321,61 @@
     }
 
     public static class BranchOp extends SPARCLIRInstruction implements StandardOp.BranchOp {
-        // 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;
+        protected final double trueDestinationProbability;
 
-        public BranchOp(ConditionFlag condition, LabelRef trueDestination, LabelRef falseDestination, Kind kind) {
-            this.conditionFlag = condition;
+        public BranchOp(ConditionFlag conditionFlag, LabelRef trueDestination, LabelRef falseDestination, Kind kind, double trueDestinationProbability) {
             this.trueDestination = trueDestination;
             this.falseDestination = falseDestination;
             this.kind = kind;
-            this.condition = null;
-            this.unorderedIsTrue = true;
-        }
-
-        public BranchOp(Condition condition, LabelRef trueDestination, LabelRef falseDestination, Kind kind) {
-            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) {
-            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 class StrategySwitchOp extends SPARCLIRInstruction implements BlockEndOp {
@@ -543,39 +404,33 @@
             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");
                     }
+                    ConditionFlag conditionFlag = ConditionFlag.fromCondtition(conditionCode, condition, false);
+                    new Cmp(keyRegister, scratchRegister).emit(masm);
+                    masm.bpcc(conditionFlag, NOT_ANNUL, target, conditionCode, PREDICT_TAKEN);
                     new Nop().emit(masm);  // delay slot
                 }
             };
@@ -629,7 +484,7 @@
 
                 // Jump to default target if index is not within the jump table
                 if (defaultTarget != null) {
-                    new Bpgu(CC.Icc, defaultTarget.label()).emit(masm);
+                    masm.bpcc(GreaterUnsigned, NOT_ANNUL, defaultTarget.label(), Icc, PREDICT_TAKEN);
                     new Nop().emit(masm);  // delay slot
                 }
 
@@ -644,11 +499,10 @@
                 new Jmpl(scratch2, scratchReg, g0).emit(masm);
             }
             new Nop().emit(masm);
-            // new Sra(value, 3, value).emit(masm); // delay slot, correct the value (division by 8)
 
             // Emit jump table entries
             for (LabelRef target : targets) {
-                new Bpa(target.label()).emit(masm);
+                masm.bpcc(Always, NOT_ANNUL, target.label(), Xcc, PREDICT_TAKEN);
                 new Nop().emit(masm); // delay slot
             }
         }
@@ -677,8 +531,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)) {
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java	Fri Feb 13 17:42:58 2015 +0100
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java	Fri Feb 27 09:18:23 2015 +0100
@@ -22,7 +22,9 @@
  */
 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.*;
@@ -40,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;
@@ -51,7 +53,7 @@
         if (!crb.isSuccessorEdge(destination())) {
             if (!emitDone) {
                 SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm;
-                new Bpa(destination().label()).emit(masm);
+                masm.bicc(ConditionFlag.Always, NOT_ANNUL, destination().label());
                 new Nop().emit(masm);
             } else {
                 assert crb.asm.position() - delaySlotPosition == 4;
--- a/graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java	Fri Feb 13 17:42:58 2015 +0100
+++ b/graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java	Fri Feb 27 09:18:23 2015 +0100
@@ -22,17 +22,18 @@
  */
 package com.oracle.graal.truffle.hotspot.sparc;
 
+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 com.oracle.graal.api.code.CallingConvention.Type;
 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.SPARCAssembler.*;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Jmp;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop;
@@ -67,7 +68,7 @@
                         new CBcondx(ConditionFlag.Equal, spillRegister, 0, doProlog).emit(asm);
                     } else {
                         new Cmp(spillRegister, 0).emit(asm);
-                        new Bpe(CC.Xcc, doProlog).emit(asm);
+                        asm.bpcc(Equal, NOT_ANNUL, doProlog, Xcc, PREDICT_NOT_TAKEN);
                         new Nop().emit(asm);
                     }
                     new Ldx(verifiedEntryPointAddress, spillRegister).emit(asm); // in delay slot