changeset 22421:440c505123b4

Merge of update to most recent version of Truffle
author Jaroslav Tulach <jaroslav.tulach@oracle.com>
date Mon, 10 Aug 2015 16:33:57 +0200
parents 0074919ff69c (diff) 13ea85f171d3 (current diff)
children c952e97b4316
files mx.graal/suite.py
diffstat 26 files changed, 659 insertions(+), 640 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Mon Aug 10 16:33:57 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -60,25 +60,6 @@
     public static final int CCR_XCC_SHIFT = 4;
     public static final int CCR_V_SHIFT = 1;
 
-    protected static final int OP2_SHIFT = 22;
-    protected static final int OP2_MASK = 0b0000_0001_1100_0000_0000_0000_0000_0000;
-
-    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;
-
-    protected static final int D10LO_MASK = 0b0000_0000_0000_0000_0001_1111_1110_0000;
-    protected static final int D10HI_MASK = 0b0000_0000_0001_1000_0000_0000_0000_0000;
-    protected static final int D10LO_SHIFT = 5;
-    protected static final int D10HI_SHIFT = 19;
-
     private static final Ops[] OPS;
     private static final Op2s[] OP2S;
     private static final Op3s[][] OP3S;
@@ -107,12 +88,10 @@
 
     public enum Ops {
         // @formatter:off
-
         BranchOp(0b00),
         CallOp(0b01),
         ArithOp(0b10),
         LdstOp(0b11);
-
         // @formatter:on
 
         private final int value;
@@ -133,7 +112,6 @@
 
     public enum Op2s {
         // @formatter:off
-
         Illtrap(0b000),
         Bpr    (0b011),
         Fb     (0b110),
@@ -142,8 +120,6 @@
         Bp     (0b001),
         Cb     (0b111),
         Sethi  (0b100);
-
-
         // @formatter:on
 
         private final int value;
@@ -956,7 +932,7 @@
         }
 
         private int leftBits(int value) {
-            return SPARCAssembler.getBits(value, rightWidth + leftWidth, rightWidth);
+            return SPARCAssembler.getBits(value, rightWidth + leftWidth - 1, rightWidth);
         }
 
         private int rightBits(int value) {
@@ -1304,12 +1280,14 @@
         public void emit(SPARCMacroAssembler masm, ConditionFlag cf, boolean cc2, Register rs1, Register rs2, Label lab) {
             int inst = setBits(0, cf, cc2, rs1);
             inst = BitSpec.rs2.setBits(inst, rs2.encoding);
+            inst = BitSpec.i.setBits(inst, 0);
             emit(masm, lab, inst);
         }
 
         public void emit(SPARCMacroAssembler masm, ConditionFlag cf, boolean cc2, Register rs1, int simm5, Label lab) {
             int inst = setBits(0, cf, cc2, rs1);
             inst = BitSpec.simm5.setBits(inst, simm5);
+            inst = BitSpec.i.setBits(inst, 1);
             emit(masm, lab, inst);
         }
 
@@ -1513,7 +1491,7 @@
     }
 
     protected void op3(Op3s op3, Register rs1, int simm13, Register rd) {
-        assert isSimm13(simm13);
+        assert isSimm13(simm13) : simm13;
         int i = 1 << 13;
         int simm13WithX = simm13 | getXBit(op3);
         fmt(op3.op.value, rd.encoding, op3.value, rs1.encoding, i | simm13WithX & ((1 << 13) - 1));
@@ -1670,38 +1648,6 @@
         return 0;
     }
 
-    public void cbcondw(ConditionFlag cf, Register rs1, Register rs2, Label lab) {
-        cbcond(0, 0, cf, rs1, rs2.encoding, lab);
-    }
-
-    public void cbcondw(ConditionFlag cf, Register rs1, int rs2, Label lab) {
-        assert isSimm(rs2, 5);
-        cbcond(0, 1, cf, rs1, rs2 & ((1 << 5) - 1), lab);
-    }
-
-    public void cbcondx(ConditionFlag cf, Register rs1, Register rs2, Label lab) {
-        cbcond(1, 0, cf, rs1, rs2.encoding, lab);
-    }
-
-    public void cbcondx(ConditionFlag cf, Register rs1, int rs2, Label lab) {
-        assert isSimm(rs2, 5);
-        cbcond(1, 1, cf, rs1, rs2 & ((1 << 5) - 1), lab);
-    }
-
-    private void cbcond(int cc2, int i, ConditionFlag cf, Register rs1, int rs2, Label l) {
-        insertNopAfterCBCond();
-        int disp10 = !l.isBound() ? patchUnbound(l) : (l.position() - position()) / 4;
-        assert isSimm(disp10, 10) && isImm(rs2, 5);
-        disp10 &= (1 << 10) - 1;
-        final int cLo = cf.value & 0b111;
-        final int cHi = cf.value >> 3;
-        final int d10Lo = disp10 & ((1 << 8) - 1);
-        final int d10Hi = disp10 >> 8;
-        int a = cHi << 4 | 0b1000 | cLo;
-        int b = cc2 << 21 | d10Hi << D10HI_SHIFT | rs1.encoding << 14 | i << 13 | d10Lo << D10LO_SHIFT | rs2;
-        fmt00(a, Op2s.Bpr.value, b);
-    }
-
     // @formatter:off
     /**
      * NOP.
@@ -2300,41 +2246,78 @@
         ld(Ldsh, src, dst);
     }
 
-    public void ld(SPARCAddress src, Register dst, int bytes, boolean signed) {
-        if (signed) {
+    public void ld(SPARCAddress src, Register dst, int bytes, boolean signExtend) {
+        if (SPARC.isCPURegister(dst)) {
+            if (signExtend) {
+                switch (bytes) {
+                    case 1:
+                        ld(Ldsb, src, dst);
+                        break;
+                    case 2:
+                        ld(Ldsh, src, dst);
+                        break;
+                    case 4:
+                        ld(Ldsw, src, dst);
+                        break;
+                    case 8:
+                        ld(Ldx, src, dst);
+                        break;
+                    default:
+                        throw new InternalError();
+                }
+            } else {
+                switch (bytes) {
+                    case 1:
+                        ld(Ldub, src, dst);
+                        break;
+                    case 2:
+                        ld(Lduh, src, dst);
+                        break;
+                    case 4:
+                        ld(Lduw, src, dst);
+                        break;
+                    case 8:
+                        ld(Ldx, src, dst);
+                        break;
+                    default:
+                        throw new InternalError();
+                }
+            }
+        } else if (SPARC.isDoubleFloatRegister(dst) && bytes == 8) {
+            assert !signExtend;
+            ld(Lddf, src, dst);
+        } else if (SPARC.isSingleFloatRegister(dst) && bytes == 4) {
+            assert !signExtend;
+            ld(Ldf, src, dst);
+        } else {
+            throw new InternalError(String.format("src: %s dst: %s bytes: %d signExtend: %b", src, dst, bytes, signExtend));
+        }
+    }
+
+    public void st(Register src, SPARCAddress dst, int bytes) {
+        if (SPARC.isCPURegister(src)) {
             switch (bytes) {
                 case 1:
-                    ldub(src, dst);
+                    st(Stb, src, dst);
                     break;
                 case 2:
-                    lduh(src, dst);
+                    st(Sth, src, dst);
                     break;
                 case 4:
-                    lduw(src, dst);
+                    st(Stw, src, dst);
                     break;
                 case 8:
-                    ldx(src, dst);
+                    st(Stx, src, dst);
                     break;
                 default:
-                    throw new InternalError();
+                    throw new InternalError(Integer.toString(bytes));
             }
+        } else if (SPARC.isDoubleFloatRegister(src) && bytes == 8) {
+            st(Stdf, src, dst);
+        } else if (SPARC.isSingleFloatRegister(src) && bytes == 4) {
+            st(Stf, src, dst);
         } else {
-            switch (bytes) {
-                case 1:
-                    ldsb(src, dst);
-                    break;
-                case 2:
-                    ldsh(src, dst);
-                    break;
-                case 4:
-                    ldsw(src, dst);
-                    break;
-                case 8:
-                    ldx(src, dst);
-                    break;
-                default:
-                    throw new InternalError();
-            }
+            throw new InternalError(String.format("src: %s dst: %s bytes: %d", src, dst, bytes));
         }
     }
 
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Mon Aug 10 16:33:57 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,12 +23,17 @@
 package com.oracle.graal.asm.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 static com.oracle.graal.asm.sparc.SPARCAssembler.RCondition.*;
 import static jdk.internal.jvmci.sparc.SPARC.*;
 
 import java.util.function.*;
 
 import jdk.internal.jvmci.code.*;
+import jdk.internal.jvmci.sparc.*;
+import jdk.internal.jvmci.sparc.SPARC.CPUFeature;
 
 import com.oracle.graal.asm.*;
 
@@ -389,4 +394,56 @@
             nextFreeScratchRegister--;
         }
     }
+
+    public void compareBranch(Register rs1, Register rs2, ConditionFlag cond, CC ccRegister, Label label, BranchPredict predict, Runnable delaySlotInstruction) {
+        assert isCPURegister(rs1, rs2);
+        assert ccRegister == Icc || ccRegister == Xcc;
+        if (hasFeature(CPUFeature.CBCOND)) {
+            if (delaySlotInstruction != null) {
+                delaySlotInstruction.run();
+            }
+            CBCOND.emit(this, cond, ccRegister == Xcc, rs1, rs2, label);
+        } else {
+            if (cond == Equal && rs1.equals(g0)) {
+                bpr(Rc_z, NOT_ANNUL, label, PREDICT_NOT_TAKEN, rs1);
+            } else {
+                cmp(rs1, rs2);
+                bpcc(cond, NOT_ANNUL, label, ccRegister, predict);
+            }
+            if (delaySlotInstruction != null) {
+                int positionBefore = position();
+                delaySlotInstruction.run();
+                int positionAfter = position();
+                assert positionBefore - positionAfter > SPARC.INSTRUCTION_SIZE : "Emitted more than one instruction into delay slot";
+            } else {
+                nop();
+            }
+        }
+    }
+
+    public void compareBranch(Register rs1, int simm, ConditionFlag cond, CC ccRegister, Label label, BranchPredict predict, Runnable delaySlotInstruction) {
+        assert isCPURegister(rs1);
+        assert ccRegister == Icc || ccRegister == Xcc;
+        if (hasFeature(CPUFeature.CBCOND)) {
+            if (delaySlotInstruction != null) {
+                delaySlotInstruction.run();
+            }
+            CBCOND.emit(this, cond, ccRegister == Xcc, rs1, simm, label);
+        } else {
+            if (cond == Equal && simm == 0) {
+                bpr(Rc_z, NOT_ANNUL, label, PREDICT_NOT_TAKEN, rs1);
+            } else {
+                cmp(rs1, simm);
+                bpcc(cond, NOT_ANNUL, label, ccRegister, predict);
+            }
+            if (delaySlotInstruction != null) {
+                int positionBefore = position();
+                delaySlotInstruction.run();
+                int positionAfter = position();
+                assert positionBefore - positionAfter > SPARC.INSTRUCTION_SIZE : "Emitted more than one instruction into delay slot";
+            } else {
+                nop();
+            }
+        }
+    }
 }
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCImmediateAddressNode.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCImmediateAddressNode.java	Mon Aug 10 16:33:57 2015 +0200
@@ -64,21 +64,4 @@
 
         gen.setResult(this, new SPARCImmediateAddressValue(kind, baseValue, displacement));
     }
-
-    public ValueNode getBase() {
-        return base;
-    }
-
-    public void setBase(ValueNode base) {
-        updateUsages(this.base, base);
-        this.base = base;
-    }
-
-    public int getDisplacement() {
-        return displacement;
-    }
-
-    public void setDisplacement(int displacement) {
-        this.displacement = displacement;
-    }
 }
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Mon Aug 10 16:33:57 2015 +0200
@@ -117,7 +117,7 @@
         }
     }
 
-    protected SPARCLIRInstruction createMove(AllocatableValue dst, Value src) {
+    protected LIRInstruction createMove(AllocatableValue dst, Value src) {
         boolean srcIsSlot = isStackSlotValue(src);
         boolean dstIsSlot = isStackSlotValue(dst);
         if (src instanceof SPARCAddressValue) {
@@ -910,7 +910,7 @@
         append(new MoveFpGp(dst, src, tempSlot));
     }
 
-    private StackSlotValue getTempSlot(LIRKind kind) {
+    protected StackSlotValue getTempSlot(LIRKind kind) {
         if (tmpStackSlot == null) {
             tmpStackSlot = getResult().getFrameMapBuilder().allocateSpillSlot(kind);
         }
@@ -1061,7 +1061,7 @@
     public Value emitSignExtendLoad(LIRKind kind, Value address, LIRFrameState state) {
         SPARCAddressValue loadAddress = asAddressValue(address);
         Variable result = newVariable(kind);
-        append(new LoadOp((Kind) kind.getPlatformKind(), result, loadAddress, state, true));
+        append(new LoadOp(kind.getPlatformKind(), result, loadAddress, state, true));
         return result;
     }
 
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Mon Aug 10 16:33:57 2015 +0200
@@ -37,7 +37,6 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.code.DataSection.Data;
-import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 
@@ -47,6 +46,7 @@
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
 import com.oracle.graal.compiler.common.alloc.*;
 import com.oracle.graal.compiler.common.cfg.*;
+import com.oracle.graal.debug.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.stubs.*;
@@ -56,7 +56,7 @@
 import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.lir.sparc.*;
-import com.oracle.graal.lir.sparc.SPARCLIRInstruction.SizeEstimate;
+import com.oracle.graal.lir.sparc.SPARCLIRInstructionMixin.SizeEstimate;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 
@@ -252,8 +252,8 @@
                 assert after.equals(op) : "Instructions before/after don't match " + op + "/" + after;
                 int constantSizeAfter = calculateDataSectionSize(crb.compilationResult.getDataSection());
                 int actual = constantSizeAfter - constantSizeBefore;
-                if (op instanceof SPARCLIRInstruction) {
-                    SizeEstimate size = ((SPARCLIRInstruction) op).estimateSize();
+                if (op instanceof SPARCLIRInstructionMixin) {
+                    com.oracle.graal.lir.sparc.SPARCLIRInstructionMixin.SizeEstimate size = ((SPARCLIRInstructionMixin) op).estimateSize();
                     assert size != null : "No size prediction available for op: " + op;
                     Class<?> c = op.getClass();
                     CONSTANT_ESTIMATED_STATS.add(c, size.constantSize);
@@ -356,8 +356,8 @@
         int size = 0;
         for (AbstractBlockBase<?> block : lir.codeEmittingOrder()) {
             for (LIRInstruction inst : lir.getLIRforBlock(block)) {
-                if (inst instanceof SPARCLIRInstruction) {
-                    SizeEstimate pred = ((SPARCLIRInstruction) inst).estimateSize();
+                if (inst instanceof SPARCLIRInstructionMixin) {
+                    SizeEstimate pred = ((SPARCLIRInstructionMixin) inst).estimateSize();
                     if (pred != null) {
                         size += pred.constantSize;
                     }
@@ -414,7 +414,7 @@
                     boolean overlap = acc.add(inst);
                     if (!overlap && inst instanceof SPARCTailDelayedLIRInstruction) {
                         // We have found a non overlapping LIR instruction which can be delayed
-                        ((SPARCTailDelayedLIRInstruction) inst).setDelayedControlTransfer(delayedTransfer);
+                        ((SPARCLIRInstructionMixin) inst).setDelayedControlTransfer(delayedTransfer);
                         delayedTransfer = null;
                     }
                 }
@@ -423,7 +423,7 @@
     }
 
     private static boolean leavesRegisterWindow(LIRInstruction inst) {
-        return inst instanceof SPARCLIRInstruction && ((SPARCLIRInstruction) inst).leavesRegisterWindow();
+        return inst instanceof SPARCLIRInstructionMixin && ((SPARCLIRInstructionMixin) inst).leavesRegisterWindow();
     }
 
     /**
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java	Mon Aug 10 16:33:57 2015 +0200
@@ -61,6 +61,6 @@
         masm.stx(scratchRegister, new SPARCAddress(thread, threadLastJavaSpOffset));
 
         // Save the thread register when calling out to the runtime.
-        SPARCMove.move(crb, masm, threadTemp, thread.asValue(LIRKind.value(Kind.Long)), delayedControlTransfer);
+        SPARCMove.move(crb, masm, threadTemp, thread.asValue(LIRKind.value(Kind.Long)), getDelayedControlTransfer());
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Mon Aug 10 16:33:57 2015 +0200
@@ -206,21 +206,10 @@
     public Variable emitLoad(LIRKind kind, Value address, LIRFrameState state) {
         SPARCAddressValue loadAddress = asAddressValue(address);
         Variable result = newVariable(kind);
-        append(new LoadOp((Kind) kind.getPlatformKind(), result, loadAddress, state));
+        append(new LoadOp(kind.getPlatformKind(), result, loadAddress, state));
         return result;
     }
 
-    private static boolean canStoreConstant(JavaConstant c) {
-        // SPARC can only store integer null constants (via g0)
-        switch (c.getKind()) {
-            case Float:
-            case Double:
-                return false;
-            default:
-                return c.isDefaultForKind();
-        }
-    }
-
     @Override
     public boolean canInlineConstant(JavaConstant c) {
         if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(c)) {
@@ -237,17 +226,16 @@
         SPARCAddressValue storeAddress = asAddressValue(address);
         if (isConstant(inputVal)) {
             JavaConstant c = asConstant(inputVal);
-            if (canStoreConstant(c)) {
-                append(new StoreConstantOp((Kind) kind.getPlatformKind(), storeAddress, c, state));
+            if (c.isDefaultForKind()) {
+                append(new StoreConstantOp(kind.getPlatformKind(), storeAddress, c, state));
                 return;
             }
         }
         Variable input = load(inputVal);
-        append(new StoreOp((Kind) kind.getPlatformKind(), storeAddress, input, state));
+        append(new StoreOp(kind.getPlatformKind(), storeAddress, input, state));
     }
 
     public Variable emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) {
-
         LIRKind kind = newValue.getLIRKind();
         assert kind.equals(expectedValue.getLIRKind());
         Kind memKind = (Kind) kind.getPlatformKind();
@@ -266,7 +254,7 @@
     }
 
     @Override
-    protected SPARCLIRInstruction createMove(AllocatableValue dst, Value src) {
+    protected LIRInstruction createMove(AllocatableValue dst, Value src) {
         Value usedSource;
         if (COMPRESSED_NULL.equals(src)) {
             usedSource = INT_0;
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Mon Aug 10 16:33:57 2015 +0200
@@ -80,7 +80,7 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            emitUnary(crb, masm, opcode, result, x, null, delayedControlTransfer);
+            emitUnary(crb, masm, opcode, result, x, null, getDelayedControlTransfer());
         }
 
         @Override
@@ -128,7 +128,7 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            emitRegReg(crb, masm, opcode, result, x, y, state, delayedControlTransfer);
+            emitRegReg(crb, masm, opcode, result, x, y, state, getDelayedControlTransfer());
         }
 
         @Override
@@ -179,7 +179,7 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            emitRegConstant(crb, masm, opcode, result, x, y, null, delayedControlTransfer);
+            emitRegConstant(crb, masm, opcode, result, x, y, null, getDelayedControlTransfer());
         }
 
         @Override
@@ -217,7 +217,7 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            emitRem(crb, masm, opcode, result, x, y, scratch1, scratch2, state, delayedControlTransfer);
+            emitRem(crb, masm, opcode, result, x, y, scratch1, scratch2, state, getDelayedControlTransfer());
         }
 
         @Override
@@ -414,15 +414,7 @@
                     Label noOverflow = new Label();
                     masm.sra(asIntReg(dst), 0, tmp);
                     masm.xorcc(SPARC.g0, SPARC.g0, SPARC.g0);
-                    if (masm.hasFeature(SPARC.CPUFeature.CBCOND)) {
-                        masm.cbcondx(Equal, tmp, asIntReg(dst), noOverflow);
-                        // Is necessary, otherwise we will have a penalty of 5 cycles in S3
-                        masm.nop();
-                    } else {
-                        masm.cmp(tmp, asIntReg(dst));
-                        masm.bpcc(Equal, NOT_ANNUL, noOverflow, Xcc, PREDICT_TAKEN);
-                        masm.nop();
-                    }
+                    masm.compareBranch(tmp, asRegister(dst), Equal, Xcc, noOverflow, PREDICT_TAKEN, null);
                     masm.wrccr(SPARC.g0, 1 << (SPARCAssembler.CCR_ICC_SHIFT + SPARCAssembler.CCR_V_SHIFT));
                     masm.bind(noOverflow);
                 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java	Mon Aug 10 16:33:57 2015 +0200
@@ -26,18 +26,15 @@
 import static com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict.*;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.RCondition.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 import static jdk.internal.jvmci.code.ValueUtil.*;
 import static jdk.internal.jvmci.common.UnsafeAccess.*;
 import static jdk.internal.jvmci.sparc.SPARC.*;
-import static jdk.internal.jvmci.sparc.SPARC.CPUFeature.*;
 
 import java.lang.reflect.*;
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.meta.*;
-import jdk.internal.jvmci.sparc.SPARC.CPUFeature;
 
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.sparc.*;
@@ -143,8 +140,6 @@
         Register tempReg1 = asRegister(temp4);
         Register tempReg2 = asRegister(temp5);
 
-        boolean hasCBcond = masm.hasFeature(CPUFeature.CBCOND);
-
         masm.sra(length, 0, length);
         masm.and(result, VECTOR_SIZE - 1, result); // tail count (in bytes)
         masm.andcc(length, ~(VECTOR_SIZE - 1), length);  // vector count (in bytes)
@@ -158,16 +153,8 @@
         // Compare the last element first
         masm.ldx(new SPARCAddress(array1, 0), tempReg1);
         masm.ldx(new SPARCAddress(array2, 0), tempReg2);
-        if (hasCBcond) {
-            masm.cbcondx(NotEqual, tempReg1, tempReg2, falseLabel);
-            masm.cbcondx(Equal, length, 0, compareTailCorrectVectorEnd);
-        } else {
-            masm.cmp(tempReg1, tempReg2);
-            masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_NOT_TAKEN);
-            masm.nop();
-            masm.bpr(Rc_z, NOT_ANNUL, compareTailCorrectVectorEnd, PREDICT_NOT_TAKEN, length);
-            masm.nop();
-        }
+        masm.compareBranch(tempReg1, tempReg2, NotEqual, Xcc, falseLabel, PREDICT_NOT_TAKEN, null);
+        masm.compareBranch(length, 0, Equal, Xcc, compareTailCorrectVectorEnd, PREDICT_NOT_TAKEN, null);
 
         // Load the first value from array 1 (Later done in back branch delay-slot)
         masm.ldx(new SPARCAddress(array1, length), tempReg1);
@@ -182,12 +169,7 @@
         masm.ldx(new SPARCAddress(array1, length), tempReg1); // Load in delay slot
 
         // Tail count zero, therefore we can go to the end
-        if (hasCBcond) {
-            masm.cbcondx(Equal, result, 0, trueLabel);
-        } else {
-            masm.bpr(Rc_z, NOT_ANNUL, trueLabel, PREDICT_TAKEN, result);
-            masm.nop();
-        }
+        masm.compareBranch(result, 0, Equal, Xcc, trueLabel, PREDICT_TAKEN, null);
 
         masm.bind(compareTailCorrectVectorEnd);
         // Correct the array pointers
@@ -206,28 +188,14 @@
 
         Register tempReg1 = asRegister(temp3);
         Register tempReg2 = asRegister(temp4);
-        boolean hasCBcond = masm.hasFeature(CBCOND);
 
         if (kind.getByteCount() <= 4) {
             // Compare trailing 4 bytes, if any.
-            if (hasCBcond) {
-                masm.cbcondx(Less, result, 4, compare2Bytes);
-            } else {
-                masm.cmp(result, 4);
-                masm.bpcc(Less, NOT_ANNUL, compare2Bytes, Xcc, PREDICT_NOT_TAKEN);
-                masm.nop();
-            }
+            masm.compareBranch(result, 4, Less, Xcc, compare2Bytes, PREDICT_NOT_TAKEN, null);
 
             masm.lduw(new SPARCAddress(array1, 0), tempReg1);
             masm.lduw(new SPARCAddress(array2, 0), tempReg2);
-
-            if (hasCBcond) {
-                masm.cbcondx(NotEqual, tempReg1, tempReg2, falseLabel);
-            } else {
-                masm.cmp(tempReg1, tempReg2);
-                masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_NOT_TAKEN);
-                masm.nop();
-            }
+            masm.compareBranch(tempReg1, tempReg2, NotEqual, Xcc, falseLabel, PREDICT_NOT_TAKEN, null);
 
             if (kind.getByteCount() <= 2) {
                 // Move array pointers forward.
@@ -238,24 +206,12 @@
                 // Compare trailing 2 bytes, if any.
                 masm.bind(compare2Bytes);
 
-                if (hasCBcond) {
-                    masm.cbcondx(Less, result, 2, compare1Byte);
-                } else {
-                    masm.cmp(result, 2);
-                    masm.bpcc(Less, NOT_ANNUL, compare1Byte, Xcc, PREDICT_TAKEN);
-                    masm.nop();
-                }
+                masm.compareBranch(result, 2, Less, Xcc, compare1Byte, PREDICT_TAKEN, null);
 
                 masm.lduh(new SPARCAddress(array1, 0), tempReg1);
                 masm.lduh(new SPARCAddress(array2, 0), tempReg2);
 
-                if (hasCBcond) {
-                    masm.cbcondx(NotEqual, tempReg1, tempReg2, falseLabel);
-                } else {
-                    masm.cmp(tempReg1, tempReg2);
-                    masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_TAKEN);
-                    masm.nop();
-                }
+                masm.compareBranch(tempReg1, tempReg2, NotEqual, Xcc, falseLabel, PREDICT_TAKEN, null);
 
                 // The one-byte tail compare is only required for boolean and byte arrays.
                 if (kind.getByteCount() <= 1) {
@@ -266,22 +222,11 @@
 
                     // Compare trailing byte, if any.
                     masm.bind(compare1Byte);
-                    if (hasCBcond) {
-                        masm.cbcondx(NotEqual, result, 1, trueLabel);
-                    } else {
-                        masm.cmp(result, 1);
-                        masm.bpcc(NotEqual, NOT_ANNUL, trueLabel, Xcc, PREDICT_TAKEN);
-                        masm.nop();
-                    }
+                    masm.compareBranch(result, 1, NotEqual, Xcc, trueLabel, PREDICT_TAKEN, null);
+
                     masm.ldub(new SPARCAddress(array1, 0), tempReg1);
                     masm.ldub(new SPARCAddress(array2, 0), tempReg2);
-                    if (hasCBcond) {
-                        masm.cbcondx(NotEqual, tempReg1, tempReg2, falseLabel);
-                    } else {
-                        masm.cmp(tempReg1, tempReg2);
-                        masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_TAKEN);
-                        masm.nop();
-                    }
+                    masm.compareBranch(tempReg1, tempReg2, NotEqual, Xcc, falseLabel, PREDICT_TAKEN, null);
                 } else {
                     masm.bind(compare1Byte);
                 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBlockEndOp.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBlockEndOp.java	Mon Aug 10 16:33:57 2015 +0200
@@ -22,65 +22,32 @@
  */
 package com.oracle.graal.lir.sparc;
 
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-
+import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.*;
+import com.oracle.graal.lir.StandardOp.AbstractBlockEndOp;
+import com.oracle.graal.lir.asm.*;
 
-import jdk.internal.jvmci.meta.*;
-
-public abstract class SPARCBlockEndOp extends SPARCLIRInstruction implements BlockEndOp {
+public abstract class SPARCBlockEndOp extends AbstractBlockEndOp implements SPARCLIRInstructionMixin {
     public static final LIRInstructionClass<SPARCBlockEndOp> TYPE = LIRInstructionClass.create(SPARCBlockEndOp.class);
-
-    @Alive({REG, STACK, CONST}) private Value[] outgoingValues;
-    private int size;
+    private final SPARCLIRInstructionMixinStore store;
 
     protected SPARCBlockEndOp(LIRInstructionClass<? extends SPARCBlockEndOp> c) {
         this(c, null);
     }
 
     protected SPARCBlockEndOp(LIRInstructionClass<? extends SPARCBlockEndOp> c, SizeEstimate sizeEstimate) {
-        super(c, sizeEstimate);
-        this.outgoingValues = Value.NO_VALUES;
-        this.size = 0;
+        super(c);
+        store = new SPARCLIRInstructionMixinStore(sizeEstimate);
     }
 
-    public void setOutgoingValues(Value[] values) {
-        assert outgoingValues.length == 0;
-        assert values != null;
-        outgoingValues = values;
-        size = values.length;
-    }
-
-    public int getOutgoingSize() {
-        return size;
-    }
-
-    public Value getOutgoingValue(int idx) {
-        assert checkRange(idx);
-        return outgoingValues[idx];
+    public SPARCLIRInstructionMixinStore getSPARCLIRInstructionStore() {
+        return store;
     }
 
-    private boolean checkRange(int idx) {
-        return idx < size;
-    }
-
-    public void clearOutgoingValues() {
-        outgoingValues = Value.NO_VALUES;
-        size = 0;
+    @Override
+    public void emitCode(CompilationResultBuilder crb) {
+        emitCode(crb, (SPARCMacroAssembler) crb.asm);
     }
 
-    public int addOutgoingValues(Value[] v) {
-
-        int t = size + v.length;
-        if (t >= outgoingValues.length) {
-            Value[] newArray = new Value[t];
-            System.arraycopy(outgoingValues, 0, newArray, 0, size);
-            outgoingValues = newArray;
-        }
-        System.arraycopy(v, 0, outgoingValues, size, v.length);
-        size = t;
-        return t;
-
-    }
+    protected abstract void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm);
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Mon Aug 10 16:33:57 2015 +0200
@@ -60,7 +60,7 @@
             new SPARCMacroAssembler.Setx(addr.getDisplacement(), tempReg, false).emit(masm);
             addr = new SPARCAddress(addr.getBase(), tempReg);
         }
-        delayedControlTransfer.emitControlTransfer(crb, masm);
+        getDelayedControlTransfer().emitControlTransfer(crb, masm);
         switch (input.getKind()) {
             case Int:
                 masm.lduwa(addr.getBase(), addr.getIndex(), asIntReg(result), Asi.ASI_PRIMARY_LITTLE);
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Mon Aug 10 16:33:57 2015 +0200
@@ -240,26 +240,26 @@
                 case Int:
                     if (isConstant(actualY)) {
                         int constantY = asConstant(actualY).asInt();
-                        masm.cbcondw(conditionFlag, asIntReg(actualX), constantY, actualTrueTarget);
+                        CBCOND.emit(masm, conditionFlag, false, asIntReg(actualX), constantY, actualTrueTarget);
                     } else {
-                        masm.cbcondw(conditionFlag, asIntReg(actualX), asIntReg(actualY), actualTrueTarget);
+                        CBCOND.emit(masm, conditionFlag, false, asIntReg(actualX), asIntReg(actualY), actualTrueTarget);
                     }
                     break;
                 case Long:
                     if (isConstant(actualY)) {
                         int constantY = (int) asConstant(actualY).asLong();
-                        masm.cbcondx(conditionFlag, asLongReg(actualX), constantY, actualTrueTarget);
+                        CBCOND.emit(masm, conditionFlag, true, asLongReg(actualX), constantY, actualTrueTarget);
                     } else {
-                        masm.cbcondx(conditionFlag, asLongReg(actualX), asLongReg(actualY), actualTrueTarget);
+                        CBCOND.emit(masm, conditionFlag, true, asLongReg(actualX), asLongReg(actualY), actualTrueTarget);
                     }
                     break;
                 case Object:
                     if (isConstant(actualY)) {
                         // Object constant valid can only be null
                         assert asConstant(actualY).isNull();
-                        masm.cbcondx(conditionFlag, asObjectReg(actualX), 0, actualTrueTarget);
+                        CBCOND.emit(masm, conditionFlag, true, asObjectReg(actualX), 0, actualTrueTarget);
                     } else { // this is already loaded
-                        masm.cbcondx(conditionFlag, asObjectReg(actualX), asObjectReg(actualY), actualTrueTarget);
+                        CBCOND.emit(masm, conditionFlag, true, asObjectReg(actualX), asObjectReg(actualY), actualTrueTarget);
                     }
                     break;
                 default:
@@ -486,19 +486,11 @@
                     boolean canUseShortBranch = masm.hasFeature(CPUFeature.CBCOND) && isShortBranch(masm, cbCondPosition, hint, target);
                     if (bits != null && canUseShortBranch) {
                         if (isShortConstant) {
-                            if (conditionCode == Icc) {
-                                masm.cbcondw(conditionFlag, keyRegister, (int) (long) bits, target);
-                            } else {
-                                masm.cbcondx(conditionFlag, keyRegister, (int) (long) bits, target);
-                            }
+                            CBCOND.emit(masm, conditionFlag, conditionCode == Icc, keyRegister, (int) (long) bits, target);
                         } else {
                             Register scratchRegister = asRegister(scratch);
                             const2reg(crb, masm, scratch, constantBaseRegister, keyConstants[index], SPARCDelayedControlTransfer.DUMMY);
-                            if (conditionCode == Icc) {
-                                masm.cbcondw(conditionFlag, keyRegister, scratchRegister, target);
-                            } else {
-                                masm.cbcondx(conditionFlag, keyRegister, scratchRegister, target);
-                            }
+                            CBCOND.emit(masm, conditionFlag, conditionCode == Icc, keyRegister, scratchRegister, target);
                         }
                     } else {
                         if (bits != null && isSimm13(constant)) {
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java	Mon Aug 10 16:33:57 2015 +0200
@@ -24,22 +24,23 @@
 
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*;
 
+import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.JumpOp;
 import com.oracle.graal.lir.asm.*;
-import com.oracle.graal.lir.sparc.SPARCLIRInstruction.*;
 
-public final class SPARCJumpOp extends JumpOp implements SPARCDelayedControlTransfer {
+public final class SPARCJumpOp extends JumpOp implements SPARCDelayedControlTransfer, SPARCLIRInstructionMixin {
     public static final LIRInstructionClass<SPARCJumpOp> TYPE = LIRInstructionClass.create(SPARCJumpOp.class);
     public static final SizeEstimate SIZE = SizeEstimate.create(2);
 
     private boolean emitDone = false;
     private int delaySlotPosition = -1;
+    private final SPARCLIRInstructionMixinStore store;
 
     public SPARCJumpOp(LabelRef destination) {
         super(TYPE, destination);
+        this.store = new SPARCLIRInstructionMixinStore(SIZE);
     }
 
     public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
@@ -65,12 +66,12 @@
         }
     }
 
-    public static SizeEstimate getSize() {
-        return SIZE;
-    }
-
     public void resetState() {
         delaySlotPosition = -1;
         emitDone = false;
     }
+
+    public SPARCLIRInstructionMixinStore getSPARCLIRInstructionStore() {
+        return store;
+    }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java	Mon Aug 10 16:33:57 2015 +0200
@@ -29,9 +29,9 @@
 /**
  * Convenience class to provide SPARCMacroAssembler for the {@link #emitCode} method.
  */
-public abstract class SPARCLIRInstruction extends LIRInstruction {
+public abstract class SPARCLIRInstruction extends LIRInstruction implements SPARCLIRInstructionMixin {
     public static final LIRInstructionClass<SPARCLIRInstruction> TYPE = LIRInstructionClass.create(SPARCLIRInstruction.class);
-    private final SizeEstimate size;
+    private final SPARCLIRInstructionMixinStore store;
 
     protected SPARCLIRInstruction(LIRInstructionClass<? extends LIRInstruction> c) {
         this(c, null);
@@ -39,72 +39,17 @@
 
     protected SPARCLIRInstruction(LIRInstructionClass<? extends LIRInstruction> c, SizeEstimate size) {
         super(c);
-        this.size = size;
+        store = new SPARCLIRInstructionMixinStore(size);
     }
 
-    protected SPARCDelayedControlTransfer delayedControlTransfer = SPARCDelayedControlTransfer.DUMMY;
-
     @Override
-    public final void emitCode(CompilationResultBuilder crb) {
+    public void emitCode(CompilationResultBuilder crb) {
         emitCode(crb, (SPARCMacroAssembler) crb.asm);
     }
 
-    public abstract void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm);
-
-    public boolean leavesRegisterWindow() {
-        return false;
-    }
-
-    public void setDelayedControlTransfer(SPARCDelayedControlTransfer holder) {
-        this.delayedControlTransfer = holder;
-    }
-
-    public SizeEstimate estimateSize() {
-        return size;
-    }
+    protected abstract void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm);
 
-    /**
-     * This class represents a size estimation of a particular LIR instruction. It contains a
-     * pessimistic estimate of emitted SPARC instructions and emitted bytes into the constant
-     * section.
-     */
-    public static class SizeEstimate {
-        /**
-         * Cache the first size definition (with just 0 as constant size).
-         */
-        private static final SizeEstimate[] cache = new SizeEstimate[5];
-        static {
-            for (int i = 0; i < cache.length; i++) {
-                cache[i] = new SizeEstimate(i, 0);
-            }
-        }
-        public final int instructionSize;
-        public final int constantSize;
-
-        public SizeEstimate(int instructionSize, int constantSize) {
-            this.instructionSize = instructionSize;
-            this.constantSize = constantSize;
-        }
-
-        public static SizeEstimate create(int instructionSize, int constantSize) {
-            if (constantSize == 0 && instructionSize < cache.length) {
-                return cache[instructionSize];
-            } else {
-                return new SizeEstimate(instructionSize, constantSize);
-            }
-        }
-
-        public static SizeEstimate create(int instructionSize) {
-            if (instructionSize < cache.length) {
-                return cache[instructionSize];
-            } else {
-                return new SizeEstimate(instructionSize, 0);
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "SE[i=" + instructionSize + ", c=" + constantSize + "]";
-        }
+    public SPARCLIRInstructionMixinStore getSPARCLIRInstructionStore() {
+        return store;
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstructionMixin.java	Mon Aug 10 16:33:57 2015 +0200
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.lir.sparc;
+
+public interface SPARCLIRInstructionMixin {
+
+    default boolean leavesRegisterWindow() {
+        return false;
+    }
+
+    default void setDelayedControlTransfer(SPARCDelayedControlTransfer holder) {
+        assert this instanceof SPARCTailDelayedLIRInstruction : this;
+        getSPARCLIRInstructionStore().delayedControlTransfer = holder;
+    }
+
+    default SPARCDelayedControlTransfer getDelayedControlTransfer() {
+        return getSPARCLIRInstructionStore().delayedControlTransfer;
+    }
+
+    default SizeEstimate estimateSize() {
+        return getSPARCLIRInstructionStore().estimate;
+    }
+
+    SPARCLIRInstructionMixinStore getSPARCLIRInstructionStore();
+
+    /**
+     * This class represents a size estimation of a particular LIR instruction. It contains a
+     * pessimistic estimate of emitted SPARC instructions and emitted bytes into the constant
+     * section.
+     */
+    public static class SizeEstimate {
+        /**
+         * Cache the first size definition (with just 0 as constant size).
+         */
+        private static final SizeEstimate[] cache = new SizeEstimate[5];
+        static {
+            for (int i = 0; i < cache.length; i++) {
+                cache[i] = new SizeEstimate(i, 0);
+            }
+        }
+        public final int instructionSize;
+        public final int constantSize;
+
+        public SizeEstimate(int instructionSize, int constantSize) {
+            this.instructionSize = instructionSize;
+            this.constantSize = constantSize;
+        }
+
+        public static SizeEstimate create(int instructionSize, int constantSize) {
+            if (constantSize == 0 && instructionSize < cache.length) {
+                return cache[instructionSize];
+            } else {
+                return new SizeEstimate(instructionSize, constantSize);
+            }
+        }
+
+        public static SizeEstimate create(int instructionSize) {
+            if (instructionSize < cache.length) {
+                return cache[instructionSize];
+            } else {
+                return new SizeEstimate(instructionSize, 0);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "SE[i=" + instructionSize + ", c=" + constantSize + "]";
+        }
+    }
+
+    public static class SPARCLIRInstructionMixinStore {
+        public SizeEstimate estimate;
+        public SPARCDelayedControlTransfer delayedControlTransfer = SPARCDelayedControlTransfer.DUMMY;
+
+        public SPARCLIRInstructionMixinStore(SizeEstimate estimate) {
+            this.estimate = estimate;
+        }
+    }
+}
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLoadConstantTableBaseOp.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLoadConstantTableBaseOp.java	Mon Aug 10 16:33:57 2015 +0200
@@ -51,7 +51,7 @@
  * this case absolute addressing (without using the base pointer is used). See also:
  * CodeInstaller::pd_patch_DataSectionReference
  *
- * @see SPARCMove#loadFromConstantTable(CompilationResultBuilder, SPARCMacroAssembler, Kind,
+ * @see SPARCMove#loadFromConstantTable(CompilationResultBuilder, SPARCMacroAssembler, PlatformKind,
  *      Register, Register, SPARCDelayedControlTransfer, Runnable)
  */
 public class SPARCLoadConstantTableBaseOp extends SPARCLIRInstruction {
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java	Mon Aug 10 16:33:57 2015 +0200
@@ -53,7 +53,7 @@
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         Kind inputKind = (Kind) input.getLIRKind().getPlatformKind();
-        delayedControlTransfer.emitControlTransfer(crb, masm);
+        getDelayedControlTransfer().emitControlTransfer(crb, masm);
         switch (opcode) {
             case SQRT:
                 switch (inputKind) {
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Mon Aug 10 16:33:57 2015 +0200
@@ -63,10 +63,10 @@
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             if (isRegister(result)) {
-                const2reg(crb, masm, result, g0, constant, delayedControlTransfer);
+                const2reg(crb, masm, result, g0, constant, getDelayedControlTransfer());
             } else if (isStackSlot(result)) {
                 StackSlot slot = asStackSlot(result);
-                const2stack(crb, masm, slot, g0, constant, delayedControlTransfer, constant);
+                const2stack(crb, masm, slot, g0, constant, getDelayedControlTransfer(), constant);
             }
         }
 
@@ -96,35 +96,20 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            final Runnable recordReference;
-            final Kind constantKind = constant.getKind().equals(Object) ? Kind.Long : constant.getKind();
-            switch (constantKind) {
-                case Object:
-                case Float:
-                case Double:
-                case Char:
-                case Short:
-                case Int:
-                case Long:
-                    recordReference = () -> crb.recordDataReferenceInCode(constant, constantKind.getByteCount());
-                    break;
-                case Byte:
-                case Boolean: // Byte and Boolean always fits into simm13
-                    throw JVMCIError.shouldNotReachHere("Byte/Boolean must not be loaded via constant table");
-                default:
-                    throw JVMCIError.shouldNotReachHere("Unimplemented constant type: " + constant);
-            }
+            final int byteCount = crb.target.getSizeInBytes(constant.getKind());
+            assert byteCount >= 1 : "Byte values must not be loaded via constant table";
+            final Kind constantKind = constant.getKind();
+            final Runnable recordReference = () -> crb.recordDataReferenceInCode(constant, byteCount);
             Register baseRegister = asRegister(constantTableBase);
             if (isRegister(result)) {
                 Register resultRegister = asRegister(result);
-                loadFromConstantTable(crb, masm, constantKind, baseRegister, resultRegister, delayedControlTransfer, recordReference);
+                loadFromConstantTable(crb, masm, constantKind, baseRegister, resultRegister, getDelayedControlTransfer(), recordReference);
             } else if (isStackSlot(result)) {
                 try (ScratchRegister scratch = masm.getScratchRegister()) {
                     Register scratchRegister = scratch.getRegister();
-                    loadFromConstantTable(crb, masm, constantKind, baseRegister, scratchRegister, delayedControlTransfer, recordReference);
+                    loadFromConstantTable(crb, masm, constantKind, baseRegister, scratchRegister, getDelayedControlTransfer(), recordReference);
                     StackSlot slot = asStackSlot(result);
-                    delayedControlTransfer.emitControlTransfer(crb, masm);
-                    masm.stx(scratchRegister, (SPARCAddress) crb.asAddress(slot));
+                    reg2stack(crb, masm, slot, scratchRegister.asValue(), getDelayedControlTransfer());
                 }
             }
         }
@@ -146,12 +131,7 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            assert !isConstant(input);
-            if (isStackSlot(input) && isStackSlot(result)) {
-                stack2stack(crb, masm, reInterpret(asStackSlot(result)), reInterpret(asStackSlot(input)), delayedControlTransfer);
-            } else {
-                move(crb, masm, getResult(), getInput(), delayedControlTransfer);
-            }
+            move(crb, masm, getResult(), getInput(), getDelayedControlTransfer());
         }
 
         @Override
@@ -163,25 +143,6 @@
         public AllocatableValue getResult() {
             return result;
         }
-
-        private static StackSlot reInterpret(StackSlot slot) {
-            switch ((Kind) slot.getPlatformKind()) {
-                case Boolean:
-                case Byte:
-                case Short:
-                case Char:
-                case Int:
-                case Long:
-                case Object:
-                    return slot;
-                case Float:
-                    return StackSlot.get(LIRKind.value(Kind.Int), slot.getRawOffset(), slot.getRawAddFrameSize());
-                case Double:
-                    return StackSlot.get(LIRKind.value(Kind.Long), slot.getRawOffset(), slot.getRawAddFrameSize());
-                default:
-                    throw JVMCIError.shouldNotReachHere();
-            }
-        }
     }
 
     /**
@@ -223,7 +184,7 @@
         }
 
         private void moveDirect(CompilationResultBuilder crb, SPARCMacroAssembler masm, Kind inputKind, Kind resultKind) {
-            delayedControlTransfer.emitControlTransfer(crb, masm);
+            getDelayedControlTransfer().emitControlTransfer(crb, masm);
             if (resultKind == Float) {
                 if (inputKind == Int || inputKind == Short || inputKind == Char || inputKind == Byte) {
                     masm.movwtos(asIntReg(input), asFloatReg(result));
@@ -252,66 +213,15 @@
         }
 
         private void moveViaStack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Kind inputKind, Kind resultKind) {
+            int inputKindSize = crb.target.getSizeInBytes(inputKind);
             int resultKindSize = crb.target.getSizeInBytes(resultKind);
+            assert inputKindSize == resultKindSize;
             try (ScratchRegister sc = masm.getScratchRegister()) {
                 Register scratch = sc.getRegister();
                 SPARCAddress tempAddress = generateSimm13OffsetLoad((SPARCAddress) crb.asAddress(temp), masm, scratch);
-                switch (inputKind) {
-                    case Float:
-                        assert resultKindSize == 4;
-                        masm.stf(asFloatReg(input), tempAddress);
-                        break;
-                    case Double:
-                        assert resultKindSize == 8;
-                        masm.stdf(asDoubleReg(input), tempAddress);
-                        break;
-                    case Long:
-                    case Int:
-                    case Short:
-                    case Char:
-                    case Byte:
-                        if (resultKindSize == 8) {
-                            masm.stx(asLongReg(input), tempAddress);
-                        } else if (resultKindSize == 4) {
-                            masm.stw(asIntReg(input), tempAddress);
-                        } else if (resultKindSize == 2) {
-                            masm.sth(asIntReg(input), tempAddress);
-                        } else if (resultKindSize == 1) {
-                            masm.stb(asIntReg(input), tempAddress);
-                        } else {
-                            throw JVMCIError.shouldNotReachHere();
-                        }
-                        break;
-                    default:
-                        JVMCIError.shouldNotReachHere();
-                }
-                delayedControlTransfer.emitControlTransfer(crb, masm);
-                switch (resultKind) {
-                    case Long:
-                        masm.ldx(tempAddress, asLongReg(result));
-                        break;
-                    case Int:
-                        masm.ldsw(tempAddress, asIntReg(result));
-                        break;
-                    case Short:
-                        masm.ldsh(tempAddress, asIntReg(input));
-                        break;
-                    case Char:
-                        masm.lduh(tempAddress, asIntReg(input));
-                        break;
-                    case Byte:
-                        masm.ldsb(tempAddress, asIntReg(input));
-                        break;
-                    case Float:
-                        masm.ldf(tempAddress, asFloatReg(result));
-                        break;
-                    case Double:
-                        masm.lddf(tempAddress, asDoubleReg(result));
-                        break;
-                    default:
-                        JVMCIError.shouldNotReachHere();
-                        break;
-                }
+                masm.st(asRegister(input), tempAddress, resultKindSize);
+                getDelayedControlTransfer().emitControlTransfer(crb, masm);
+                masm.ld(tempAddress, asRegister(result), resultKindSize, false);
             }
         }
     }
@@ -353,11 +263,11 @@
         @Def({REG}) protected AllocatableValue result;
         protected boolean signExtend;
 
-        public LoadOp(Kind kind, AllocatableValue result, SPARCAddressValue address, LIRFrameState state) {
+        public LoadOp(PlatformKind kind, AllocatableValue result, SPARCAddressValue address, LIRFrameState state) {
             this(kind, result, address, state, false);
         }
 
-        public LoadOp(Kind kind, AllocatableValue result, SPARCAddressValue address, LIRFrameState state, boolean signExtend) {
+        public LoadOp(PlatformKind kind, AllocatableValue result, SPARCAddressValue address, LIRFrameState state, boolean signExtend) {
             super(TYPE, SIZE, kind, address, state);
             this.result = result;
             this.signExtend = signExtend;
@@ -365,7 +275,7 @@
 
         @Override
         public void emitMemAccess(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            emitLoad(crb, masm, address.toAddress(), result, signExtend, kind, delayedControlTransfer, state);
+            emitLoad(crb, masm, address.toAddress(), result, signExtend, kind, getDelayedControlTransfer(), state);
         }
     }
 
@@ -385,7 +295,7 @@
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             SPARCAddress address = addressValue.toAddress();
-            loadEffectiveAddress(crb, masm, address, asLongReg(result), delayedControlTransfer);
+            loadEffectiveAddress(crb, masm, address, asLongReg(result), getDelayedControlTransfer());
         }
     }
 
@@ -429,7 +339,7 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            delayedControlTransfer.emitControlTransfer(crb, masm);
+            getDelayedControlTransfer().emitControlTransfer(crb, masm);
             masm.membar(barriers);
         }
     }
@@ -449,7 +359,7 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            delayedControlTransfer.emitControlTransfer(crb, masm);
+            getDelayedControlTransfer().emitControlTransfer(crb, masm);
             SPARCAddress addr = input.toAddress();
             crb.recordImplicitException(masm.position(), state);
             // Just need to check whether this is a valid address or not; alignment is not
@@ -487,7 +397,7 @@
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             move(crb, masm, result, newValue, SPARCDelayedControlTransfer.DUMMY);
-            compareAndSwap(crb, masm, address, cmpValue, result, delayedControlTransfer);
+            compareAndSwap(crb, masm, address, cmpValue, result, getDelayedControlTransfer());
         }
     }
 
@@ -507,7 +417,7 @@
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             SPARCAddress address = (SPARCAddress) crb.asAddress(slot);
-            loadEffectiveAddress(crb, masm, address, asLongReg(result), delayedControlTransfer);
+            loadEffectiveAddress(crb, masm, address, asLongReg(result), getDelayedControlTransfer());
         }
     }
 
@@ -535,14 +445,14 @@
 
         @Use({REG}) protected AllocatableValue input;
 
-        public StoreOp(Kind kind, SPARCAddressValue address, AllocatableValue input, LIRFrameState state) {
+        public StoreOp(PlatformKind kind, SPARCAddressValue address, AllocatableValue input, LIRFrameState state) {
             super(TYPE, SIZE, kind, address, state);
             this.input = input;
         }
 
         @Override
         public void emitMemAccess(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            emitStore(input, address.toAddress(), kind, delayedControlTransfer, state, crb, masm);
+            emitStore(input, address.toAddress(), kind, getDelayedControlTransfer(), state, crb, masm);
         }
     }
 
@@ -552,7 +462,7 @@
 
         protected final JavaConstant input;
 
-        public StoreConstantOp(Kind kind, SPARCAddressValue address, JavaConstant input, LIRFrameState state) {
+        public StoreConstantOp(PlatformKind kind, SPARCAddressValue address, JavaConstant input, LIRFrameState state) {
             super(TYPE, SIZE, kind, address, state);
             this.input = input;
             if (!input.isDefaultForKind()) {
@@ -565,32 +475,12 @@
             try (ScratchRegister sc = masm.getScratchRegister()) {
                 Register scratch = sc.getRegister();
                 SPARCAddress addr = generateSimm13OffsetLoad(address.toAddress(), masm, scratch);
-                delayedControlTransfer.emitControlTransfer(crb, masm);
+                getDelayedControlTransfer().emitControlTransfer(crb, masm);
                 if (state != null) {
                     crb.recordImplicitException(masm.position(), state);
                 }
-                switch ((Kind) kind) {
-                    case Boolean:
-                    case Byte:
-                        masm.stb(g0, addr);
-                        break;
-                    case Short:
-                    case Char:
-                        masm.sth(g0, addr);
-                        break;
-                    case Int:
-                        masm.stw(g0, addr);
-                        break;
-                    case Long:
-                    case Object:
-                        masm.stx(g0, addr);
-                        break;
-                    case Float:
-                    case Double:
-                        throw JVMCIError.shouldNotReachHere("Cannot store float constants to memory");
-                    default:
-                        throw JVMCIError.shouldNotReachHere();
-                }
+                int byteCount = crb.target.getSizeInBytes(kind);
+                masm.st(g0, addr, byteCount);
             }
         }
     }
@@ -646,16 +536,21 @@
         }
     }
 
-    public static void stack2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) {
+    public static void stack2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, PlatformKind resultKind, PlatformKind inputKind, Value result, Value input,
+                    SPARCDelayedControlTransfer delaySlotLir) {
         try (ScratchRegister sc = masm.getScratchRegister()) {
             SPARCAddress inputAddress = (SPARCAddress) crb.asAddress(input);
             Value scratchRegisterValue = sc.getRegister().asValue(LIRKind.combine(input));
-            emitLoad(crb, masm, inputAddress, scratchRegisterValue, false, input.getPlatformKind(), SPARCDelayedControlTransfer.DUMMY, null);
+            emitLoad(crb, masm, inputAddress, scratchRegisterValue, false, inputKind, SPARCDelayedControlTransfer.DUMMY, null);
             SPARCAddress resultAddress = (SPARCAddress) crb.asAddress(result);
-            emitStore(scratchRegisterValue, resultAddress, result.getPlatformKind(), delaySlotLir, null, crb, masm);
+            emitStore(scratchRegisterValue, resultAddress, resultKind, delaySlotLir, null, crb, masm);
         }
     }
 
+    public static void stack2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) {
+        stack2stack(crb, masm, result.getPlatformKind(), input.getPlatformKind(), result, input, delaySlotLir);
+    }
+
     public static void reg2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) {
         SPARCAddress resultAddress = (SPARCAddress) crb.asAddress(result);
         emitStore(input, resultAddress, result.getPlatformKind(), delaySlotLir, null, crb, masm);
@@ -667,33 +562,15 @@
         if (src.equals(dst)) {
             return;
         }
-        switch (input.getKind()) {
-            case Boolean:
-            case Byte:
-            case Short:
-            case Char:
-            case Int:
-            case Long:
-            case Object:
-                delaySlotLir.emitControlTransfer(crb, masm);
-                masm.mov(src, dst);
-                break;
-            case Float:
-                if (result.getPlatformKind() == Kind.Float) {
-                    masm.fsrc2s(src, dst);
-                } else {
-                    throw JVMCIError.shouldNotReachHere();
-                }
-                break;
-            case Double:
-                if (result.getPlatformKind() == Kind.Double) {
-                    masm.fsrc2d(src, dst);
-                } else {
-                    throw JVMCIError.shouldNotReachHere();
-                }
-                break;
-            default:
-                throw JVMCIError.shouldNotReachHere("Input is a: " + input.getKind());
+        delaySlotLir.emitControlTransfer(crb, masm);
+        if (SPARC.isCPURegister(src) && SPARC.isCPURegister(dst)) {
+            masm.mov(src, dst);
+        } else if (SPARC.isSingleFloatRegister(src) && SPARC.isSingleFloatRegister(dst)) {
+            masm.fsrc2s(src, dst);
+        } else if (SPARC.isDoubleFloatRegister(src) && SPARC.isDoubleFloatRegister(dst)) {
+            masm.fsrc2d(src, dst);
+        } else {
+            throw JVMCIError.shouldNotReachHere(String.format("Trying to move between register domains src: %s dst: %s", src, dst));
         }
     }
 
@@ -737,7 +614,7 @@
                             throw JVMCIError.shouldNotReachHere();
                         } else {
                             Runnable recordReference = () -> crb.recordDataReferenceInCode(input, input.getKind().getByteCount());
-                            loadFromConstantTable(crb, masm, input.getKind(), constantTableBase, resultRegister, delaySlotLir, recordReference);
+                            loadFromConstantTable(crb, masm, Int, constantTableBase, resultRegister, delaySlotLir, recordReference);
                         }
                     }
                     break;
@@ -821,7 +698,7 @@
         }
     }
 
-    private static void emitLoad(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCAddress address, Value result, boolean signExtend, PlatformKind kind,
+    public static void emitLoad(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCAddress address, Value result, boolean signExtend, PlatformKind kind,
                     SPARCDelayedControlTransfer delayedControlTransfer, LIRFrameState state) {
         try (ScratchRegister sc = masm.getScratchRegister()) {
             Register scratch = sc.getRegister();
@@ -831,51 +708,8 @@
             if (state != null) {
                 crb.recordImplicitException(masm.position(), state);
             }
-            switch ((Kind) kind) {
-                case Boolean:
-                case Byte:
-                    if (signExtend) {
-                        masm.ldsb(addr, dst);
-                    } else {
-                        masm.ldub(addr, dst);
-                    }
-                    break;
-                case Short:
-                    if (signExtend) {
-                        masm.ldsh(addr, dst);
-                    } else {
-                        masm.lduh(addr, dst);
-                    }
-                    break;
-                case Char:
-                    if (signExtend) {
-                        masm.ldsh(addr, dst);
-                    } else {
-                        masm.lduh(addr, dst);
-                    }
-                    break;
-                case Int:
-                    if (signExtend) {
-                        masm.ldsw(addr, dst);
-                    } else {
-                        masm.lduw(addr, dst);
-                    }
-                    break;
-                case Long:
-                    masm.ldx(addr, dst);
-                    break;
-                case Float:
-                    masm.ldf(addr, dst);
-                    break;
-                case Double:
-                    masm.lddf(addr, dst);
-                    break;
-                case Object:
-                    masm.ldx(addr, dst);
-                    break;
-                default:
-                    throw JVMCIError.shouldNotReachHere();
-            }
+            int byteCount = crb.target.getSizeInBytes(kind);
+            masm.ld(addr, dst, byteCount, signExtend);
         }
     }
 
@@ -888,33 +722,8 @@
             if (state != null) {
                 crb.recordImplicitException(masm.position(), state);
             }
-            switch ((Kind) kind) {
-                case Boolean:
-                case Byte:
-                    masm.stb(asRegister(input), addr);
-                    break;
-                case Short:
-                case Char:
-                    masm.sth(asRegister(input), addr);
-                    break;
-                case Int:
-                    masm.stw(asRegister(input), addr);
-                    break;
-                case Long:
-                    masm.stx(asRegister(input), addr);
-                    break;
-                case Object:
-                    masm.stx(asRegister(input), addr);
-                    break;
-                case Float:
-                    masm.stf(asRegister(input), addr);
-                    break;
-                case Double:
-                    masm.stdf(asRegister(input), addr);
-                    break;
-                default:
-                    throw JVMCIError.shouldNotReachHere("missing: " + kind);
-            }
+            int byteCount = crb.target.getSizeInBytes(kind);
+            masm.st(asRegister(input), addr, byteCount);
         }
     }
 
@@ -924,7 +733,7 @@
      * generated patterns by this method must be understood by
      * CodeInstaller::pd_patch_DataSectionReference (jvmciCodeInstaller_sparc.cpp).
      */
-    public static void loadFromConstantTable(CompilationResultBuilder crb, SPARCMacroAssembler masm, Kind kind, Register constantTableBase, Register dest,
+    public static void loadFromConstantTable(CompilationResultBuilder crb, SPARCMacroAssembler masm, PlatformKind kind, Register constantTableBase, Register dest,
                     SPARCDelayedControlTransfer delaySlotInstruction, Runnable recordReference) {
         SPARCAddress address;
         ScratchRegister scratch = null;
@@ -941,30 +750,8 @@
                 new Sethix(0, sr, true).emit(masm);
                 address = new SPARCAddress(sr, 0);
             }
-            switch (kind) {
-                case Boolean:
-                case Byte:
-                    masm.ldub(address, dest);
-                    break;
-                case Short:
-                case Char:
-                    masm.lduh(address, dest);
-                    break;
-                case Int:
-                    masm.lduw(address, dest);
-                    break;
-                case Long:
-                    masm.ldx(address, dest);
-                    break;
-                case Float:
-                    masm.ldf(address, dest);
-                    break;
-                case Double:
-                    masm.lddf(address, dest);
-                    break;
-                default:
-                    throw new InternalError("Unknown constant load kind: " + kind);
-            }
+            int byteCount = crb.target.getSizeInBytes(kind);
+            masm.ld(address, dest, byteCount, false);
         } finally {
             if (scratch != null) {
                 scratch.close();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTailDelayedLIRInstruction.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTailDelayedLIRInstruction.java	Mon Aug 10 16:33:57 2015 +0200
@@ -44,6 +44,5 @@
  * {@link SPARCDelayedControlTransfer#emitControlTransfer(com.oracle.graal.lir.asm.CompilationResultBuilder, SPARCMacroAssembler)}
  * . The DelayedControlTransfer instruction will emit the code just with Nop in the delay slot.
  */
-public interface SPARCTailDelayedLIRInstruction {
-    void setDelayedControlTransfer(SPARCDelayedControlTransfer holder);
+public interface SPARCTailDelayedLIRInstruction extends SPARCLIRInstructionMixin {
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Mon Aug 10 16:33:57 2015 +0200
@@ -183,7 +183,7 @@
         }
     }
 
-    private AbstractAddress recordDataSectionReference(Data data) {
+    public AbstractAddress recordDataSectionReference(Data data) {
         assert data != null;
         DataSectionReference reference = compilationResult.getDataSection().insertData(data);
         compilationResult.recordDataPatch(asm.position(), reference);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Mon Aug 10 16:33:57 2015 +0200
@@ -31,6 +31,7 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
+
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 
@@ -417,24 +418,20 @@
         if (inlineGraph.getNodes(SimpleInfopointNode.TYPE).isEmpty()) {
             return;
         }
-        BytecodePosition pos = null;
+        BytecodePosition caller = null;
         for (SimpleInfopointNode original : inlineGraph.getNodes(SimpleInfopointNode.TYPE)) {
+            if (caller == null) {
+                assert invoke.stateAfter() != null;
+                caller = new BytecodePosition(FrameState.toBytecodePosition(invoke.stateAfter().outerFrameState()), invoke.stateAfter().method(), invoke.bci());
+            }
             SimpleInfopointNode duplicate = (SimpleInfopointNode) duplicates.get(original);
-            pos = processSimpleInfopoint(invoke, duplicate, pos);
+            addSimpleInfopointCaller(duplicate, caller);
         }
     }
 
-    public static BytecodePosition processSimpleInfopoint(Invoke invoke, SimpleInfopointNode infopointNode, BytecodePosition incomingPos) {
-        BytecodePosition pos = processBytecodePosition(invoke, incomingPos);
-        infopointNode.addCaller(pos);
+    public static void addSimpleInfopointCaller(SimpleInfopointNode infopointNode, BytecodePosition caller) {
+        infopointNode.addCaller(caller);
         assert infopointNode.verify();
-        return pos;
-    }
-
-    public static BytecodePosition processBytecodePosition(Invoke invoke, BytecodePosition incomingPos) {
-        assert invoke.stateAfter() != null;
-        assert incomingPos == null || incomingPos.equals(InliningUtil.processBytecodePosition(invoke, null)) : incomingPos + " " + InliningUtil.processBytecodePosition(invoke, null);
-        return incomingPos != null ? incomingPos : new BytecodePosition(FrameState.toBytecodePosition(invoke.stateAfter().outerFrameState()), invoke.stateAfter().method(), invoke.bci());
     }
 
     public static void processMonitorId(FrameState stateAfter, MonitorIdNode monitorIdNode) {
@@ -590,7 +587,7 @@
                 }
             }
         }
-        return null;
+        return nonReplaceableFrameState;
     }
 
     public static ValueNode mergeReturns(AbstractMergeNode merge, List<? extends ReturnNode> returnNodes, List<Node> canonicalizedNodes) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/PEGraphDecoder.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/PEGraphDecoder.java	Mon Aug 10 16:33:57 2015 +0200
@@ -28,7 +28,9 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
+
 import com.oracle.graal.debug.*;
+
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.options.*;
 
@@ -110,7 +112,7 @@
             if (bytecodePosition == null) {
                 ensureOuterStateDecoded(this);
                 ensureExceptionStateDecoded(this);
-                bytecodePosition = InliningUtil.processBytecodePosition(invokeData.invoke, null);
+                bytecodePosition = new BytecodePosition(FrameState.toBytecodePosition(outerState), method, invokeData.invoke.bci());
             }
             return bytecodePosition;
         }
@@ -582,7 +584,7 @@
     protected void handleFixedNode(MethodScope s, LoopScope loopScope, int nodeOrderId, FixedNode node) {
         PEMethodScope methodScope = (PEMethodScope) s;
         if (node instanceof SimpleInfopointNode && methodScope.isInlinedMethod()) {
-            InliningUtil.processSimpleInfopoint(methodScope.invokeData.invoke, (SimpleInfopointNode) node, methodScope.getBytecodePosition());
+            InliningUtil.addSimpleInfopointCaller((SimpleInfopointNode) node, methodScope.getBytecodePosition());
         }
         super.handleFixedNode(s, loopScope, nodeOrderId, node);
     }
--- a/graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java	Mon Aug 10 16:33:57 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,13 +22,11 @@
  */
 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 static jdk.internal.jvmci.code.CallingConvention.Type.*;
 import static jdk.internal.jvmci.meta.Kind.*;
-import static jdk.internal.jvmci.sparc.SPARC.CPUFeature.*;
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
@@ -36,7 +34,7 @@
 
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.ScratchRegister;
 import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.lir.asm.*;
@@ -62,13 +60,7 @@
                     SPARCAddress verifiedEntryPointAddress = new SPARCAddress(spillRegister, config.nmethodEntryOffset);
 
                     asm.ldx(codeBlobAddress, spillRegister);
-                    if (asm.hasFeature(CBCOND)) {
-                        asm.cbcondx(Equal, spillRegister, 0, doProlog);
-                    } else {
-                        asm.cmp(spillRegister, 0);
-                        asm.bpcc(Equal, NOT_ANNUL, doProlog, Xcc, PREDICT_NOT_TAKEN);
-                        asm.nop();
-                    }
+                    asm.compareBranch(spillRegister, 0, Equal, Xcc, doProlog, PREDICT_NOT_TAKEN, null);
                     asm.ldx(verifiedEntryPointAddress, spillRegister); // in delay slot
                     asm.jmp(spillRegister);
                     asm.nop();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/TruffleEnsureVirtualizedTest.java	Mon Aug 10 16:33:57 2015 +0200
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.truffle.test;
+
+import jdk.internal.jvmci.code.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.directives.*;
+import com.oracle.graal.truffle.test.nodes.*;
+import com.oracle.truffle.api.frame.*;
+
+public class TruffleEnsureVirtualizedTest extends PartialEvaluationTest {
+
+    private abstract class TestNode extends AbstractTestNode {
+        @Override
+        public int execute(VirtualFrame frame) {
+            executeVoid(frame);
+            return 0;
+        }
+
+        public abstract void executeVoid(VirtualFrame frame);
+    }
+
+    private void testEnsureVirtualized(boolean bailoutExpected, TestNode node) {
+        RootTestNode rootNode = new RootTestNode(new FrameDescriptor(), "ensureVirtualized", node);
+        try {
+            compileHelper("ensureVirtualized", rootNode, new Object[0]);
+            if (bailoutExpected) {
+                Assert.fail("Expected bailout exception due to ensureVirtualized");
+            }
+        } catch (BailoutException e) {
+            if (!bailoutExpected) {
+                throw e;
+            }
+        }
+    }
+
+    public static int intField;
+    public static boolean booleanField;
+    public static Object field;
+
+    @Test
+    public void test1() {
+        testEnsureVirtualized(false, new TestNode() {
+            @Override
+            public void executeVoid(VirtualFrame frame) {
+                Integer object = new Integer(intField);
+                GraalDirectives.ensureVirtualized(object);
+            }
+        });
+    }
+
+    @Test
+    public void test2() {
+        testEnsureVirtualized(true, new TestNode() {
+            @Override
+            public void executeVoid(VirtualFrame frame) {
+                Integer object = new Integer(intField);
+                GraalDirectives.ensureVirtualized(object);
+                field = object; // assert here
+            }
+        });
+    }
+
+    @Test
+    public void test3() {
+        testEnsureVirtualized(true, new TestNode() {
+            @Override
+            public void executeVoid(VirtualFrame frame) {
+                Integer object = new Integer(intField);
+                field = object;
+                GraalDirectives.ensureVirtualized(object); // assert here
+            }
+        });
+    }
+
+    @Test
+    public void testHere1() {
+        testEnsureVirtualized(false, new TestNode() {
+            @Override
+            public void executeVoid(VirtualFrame frame) {
+                Integer object = new Integer(intField);
+                GraalDirectives.ensureVirtualizedHere(object);
+            }
+        });
+    }
+
+    @Test
+    public void testHere2() {
+        testEnsureVirtualized(false, new TestNode() {
+            @Override
+            public void executeVoid(VirtualFrame frame) {
+                Integer object = new Integer(intField);
+                GraalDirectives.ensureVirtualizedHere(object);
+                field = object;
+            }
+        });
+    }
+
+    @Test
+    public void testHere3() {
+        testEnsureVirtualized(true, new TestNode() {
+            @Override
+            public void executeVoid(VirtualFrame frame) {
+                Integer object = new Integer(intField);
+                field = object;
+                GraalDirectives.ensureVirtualizedHere(object); // assert here
+            }
+        });
+    }
+
+    @Test
+    public void testBoxing1() {
+        testEnsureVirtualized(true, new TestNode() {
+            @Override
+            public void executeVoid(VirtualFrame frame) {
+                Integer object = intField;
+                GraalDirectives.ensureVirtualizedHere(object); // assert here
+            }
+        });
+    }
+
+    @Test
+    public void testBoxing2() {
+        testEnsureVirtualized(true, new TestNode() {
+            @Override
+            public void executeVoid(VirtualFrame frame) {
+                Integer object = intField;
+                GraalDirectives.ensureVirtualized(object); // assert here
+                field = object;
+            }
+        });
+    }
+
+    @Test
+    public void testControlFlow1() {
+        testEnsureVirtualized(false, new TestNode() {
+            @Override
+            public void executeVoid(VirtualFrame frame) {
+                Integer object = new Integer(intField);
+                if (booleanField) {
+                    GraalDirectives.ensureVirtualized(object);
+                }
+                field = object;
+            }
+        });
+    }
+
+    @Test
+    public void testControlFlow2() {
+        testEnsureVirtualized(true, new TestNode() {
+            @Override
+            public void executeVoid(VirtualFrame frame) {
+                Integer object = new Integer(intField);
+                if (booleanField) {
+                    GraalDirectives.ensureVirtualized(object);
+                } else {
+                    GraalDirectives.ensureVirtualized(object);
+                }
+                field = object; // assert here
+            }
+        });
+    }
+
+    @Test
+    public void testControlFlow3() {
+        testEnsureVirtualized(true, new TestNode() {
+            @Override
+            public void executeVoid(VirtualFrame frame) {
+                Integer object = new Integer(intField);
+                GraalDirectives.ensureVirtualized(object);
+                if (booleanField) {
+                    field = 1;
+                } else {
+                    field = 2;
+                }
+                field = object; // assert here
+            }
+        });
+    }
+
+    @Test
+    public void testControlFlow4() {
+        testEnsureVirtualized(true, new TestNode() {
+            @Override
+            public void executeVoid(VirtualFrame frame) {
+                Integer object = new Integer(intField);
+                if (booleanField) {
+                    field = object;
+                } else {
+                    field = 2;
+                }
+                GraalDirectives.ensureVirtualized(object); // assert here
+            }
+        });
+    }
+
+    @Test
+    public void testControlFlow5() {
+        testEnsureVirtualized(true, new TestNode() {
+            @Override
+            public void executeVoid(VirtualFrame frame) {
+                Integer object = new Integer(intField);
+                if (booleanField) {
+                    field = object;
+                } else {
+                    field = 2;
+                }
+                GraalDirectives.ensureVirtualizedHere(object); // assert here
+            }
+        });
+    }
+
+    public static final class TestClass {
+        Object a;
+        Object b;
+    }
+
+    @Test
+    public void testIndirect1() {
+        testEnsureVirtualized(true, new TestNode() {
+            @Override
+            public void executeVoid(VirtualFrame frame) {
+                Integer object = new Integer(intField);
+                TestClass t = new TestClass();
+                t.a = object;
+                GraalDirectives.ensureVirtualized(object);
+
+                if (booleanField) {
+                    field = t; // assert here
+                } else {
+                    field = 2;
+                }
+            }
+        });
+    }
+
+    @Test
+    public void testIndirect2() {
+        testEnsureVirtualized(false, new TestNode() {
+            @Override
+            public void executeVoid(VirtualFrame frame) {
+                Integer object = new Integer(intField);
+                TestClass t = new TestClass();
+                t.a = object;
+                GraalDirectives.ensureVirtualized(t);
+
+                if (booleanField) {
+                    field = object;
+                } else {
+                    field = 2;
+                }
+            }
+        });
+    }
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java	Thu Aug 06 18:57:34 2015 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java	Mon Aug 10 16:33:57 2015 +0200
@@ -38,6 +38,7 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.virtual.*;
 import com.oracle.graal.replacements.nodes.arithmetic.*;
 import com.oracle.graal.truffle.*;
 import com.oracle.graal.truffle.nodes.*;
@@ -203,6 +204,18 @@
                 return true;
             }
         });
+        r.register1("ensureVirtualized", Object.class, new InvocationPlugin() {
+            public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
+                b.add(new EnsureVirtualizedNode(object, false));
+                return true;
+            }
+        });
+        r.register1("ensureVirtualizedHere", Object.class, new InvocationPlugin() {
+            public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
+                b.add(new EnsureVirtualizedNode(object, true));
+                return true;
+            }
+        });
     }
 
     public static void registerCompilerAssertsPlugins(InvocationPlugins plugins, boolean canDelayIntrinsification) {
--- a/mx.graal/suite.py	Thu Aug 06 18:57:34 2015 +0200
+++ b/mx.graal/suite.py	Mon Aug 10 16:33:57 2015 +0200
@@ -6,7 +6,7 @@
     "suites": [
             {
                "name" : "jvmci",
-               "version" : "31e0737e2fcec24b6f1aa01ffbf0e683c0ef4044",
+               "version" : "7dd034e68f2e8906955fc05429d42da80482b6b6",
                "urls" : [
                     {"url" : "http://lafo.ssw.uni-linz.ac.at/hg/graal-jvmci-8", "kind" : "hg"},
                     {"url" : "http://lafo.ssw.uni-linz.ac.at/nexus/content/repositories/snapshots", "kind" : "binary"},