changeset 16330:41d479400da8

Merge
author Lukas Stadler <lukas.stadler@oracle.com>
date Mon, 30 Jun 2014 18:46:36 +0200
parents fb90ad461cdb (current diff) 281c30cf1952 (diff)
children c8b0f10e3220
files graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractObjectStamp.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ObjectStamp.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/PrimitiveStamp.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java graal/com.oracle.graal.hotspotvmconfig/src/com/oracle/graal/hotspotvmconfig/HotSpotVMConstant.java graal/com.oracle.graal.hotspotvmconfig/src/com/oracle/graal/hotspotvmconfig/HotSpotVMField.java graal/com.oracle.graal.hotspotvmconfig/src/com/oracle/graal/hotspotvmconfig/HotSpotVMFlag.java graal/com.oracle.graal.hotspotvmconfig/src/com/oracle/graal/hotspotvmconfig/HotSpotVMType.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMap.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java test/whitelist_baseline.txt
diffstat 24 files changed, 852 insertions(+), 124 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java	Mon Jun 30 18:03:24 2014 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java	Mon Jun 30 18:46:36 2014 +0200
@@ -107,17 +107,17 @@
     }
 
     public static Register asObjectReg(Value value) {
-        assert value.getKind() == Kind.Object;
+        assert value.getKind() == Kind.Object : value.getKind();
         return asRegister(value);
     }
 
     public static Register asFloatReg(Value value) {
-        assert value.getKind() == Kind.Float;
+        assert value.getKind() == Kind.Float : value.getKind();
         return asRegister(value);
     }
 
     public static Register asDoubleReg(Value value) {
-        assert value.getKind() == Kind.Double;
+        assert value.getKind() == Kind.Double : value.getKind();
         return asRegister(value);
     }
 
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Mon Jun 30 18:03:24 2014 +0200
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Mon Jun 30 18:46:36 2014 +0200
@@ -456,6 +456,43 @@
 
     // @formatter:off
     /**
+     * Instruction format for fcmp
+     *
+     * | 10  | --- |cc1|cc0|desc |   rs1   |   opf  | rs2 |
+     * |31 30|29 27|26 |25 |24 19|18     14|13     5|4   0|
+     */
+    // @formatter:on
+    public static class Fmt3c {
+        private int op;
+        private int cc;
+        private int desc;
+        private int opf;
+        private int rs1;
+        private int rs2;
+
+        public Fmt3c(Ops op, CC cc, int desc, Opfs opf, Register rs1, Register rs2) {
+            this.op = op.getValue();
+            this.opf = opf.getValue();
+            this.desc = desc;
+            this.rs1 = rs1.encoding();
+            this.rs2 = rs2.encoding();
+            this.cc = cc.getValue();
+        }
+
+        public void emit(SPARCAssembler masm) {
+            assert op == 2 || op == 3;
+            assert cc >= 0 && cc < 0x4;
+            assert opf >= 0 && opf < 0x200;
+            assert rs1 >= 0 && rs1 < 0x20;
+            assert rs2 >= 0 && rs2 < 0x20;
+            assert desc >= 0 && desc < 0x40;
+
+            masm.emitInt(op << 30 | cc << 25 | desc << 19 | rs1 << 14 | opf << 5 | rs2);
+        }
+    }
+
+    // @formatter:off
+    /**
      * Instruction format for Arithmetic, Logical, Moves, Tcc, Prefetch, and Misc.
      *
      * | 10  |   rd   |   op3   |   rs1   | i|     imm_asi   |   rs2   |
@@ -1043,7 +1080,9 @@
         Stf(0b100100, "stf"),
         Stfsr(0x25, "stfsr"),
         Staf(0x26, "staf"),
-        Stdf(0b100111, "stdf");
+        Stdf(0b100111, "stdf"),
+
+        Fcmp(0b110101, "fcmp");
 
         // @formatter:on
 
@@ -1181,6 +1220,11 @@
         Fnsmuld(0x79, "fnsmuld"),
         Fnhadds(0x71, "fnhadds"),
         Fnhaddd(0x72, "fnhaddd"),
+        Movdtox(0x110, "movdtox"),
+        Movstouw(0x111, "movstouw"),
+        Movstosw(0x113, "movstosw"),
+        Movxtod(0x118, "movxtod"),
+        Movwtos(0x119, "movwtos"),
         // end VIS3
 
         // start CAMMELLIA
@@ -1215,9 +1259,9 @@
         Fsubq(0x47, "fsubq"),
         Fmuls(0x49, "fmuls"),
         Fmuld(0x4A, "fmuld"),
-        Fdivs(0x4C, "fdivs"),
-        Fdivd(0x4D, "fdivd"),
-        Fdivq(0x4E, "fdivq"),
+        Fdivs(0x4D, "fdivs"),
+        Fdivd(0x4E, "fdivd"),
+        Fdivq(0x4F, "fdivq"),
 
         Fsqrts(0x29, "fsqrts"),
         Fsqrtd(0x2A, "fsqrtd"),
@@ -1228,7 +1272,24 @@
         Fdmuldq(0x6E, "fdmulq"),
 
         Fstoi(0xD1, "fstoi"),
-        Fdtoi(0xD2, "fdtoi");
+        Fdtoi(0xD2, "fdtoi"),
+        Fstox(0x81, "fstox"),
+        Fdtox(0x82, "fdtox"),
+        Fxtos(0x84, "fxtos"),
+        Fxtod(0x88, "fxtod"),
+        Fxtoq(0x8C, "fxtoq"),
+        Fitos(0xC4, "fitos"),
+        Fdtos(0xC6, "fdtos"),
+        Fitod(0xC8, "fitod"),
+        Fstod(0xC9, "fstod"),
+        Fitoq(0xCC, "fitoq"),
+
+
+        Fcmps(0x51, "fcmps"),
+        Fcmpd(0x52, "fcmpd"),
+        Fcmpq(0x53, "fcmpq"),
+
+        ;
         // @formatter:on
 
         private final int value;
@@ -1278,10 +1339,18 @@
         }
     }
 
+    /**
+     * Condition Codes to use for instruction
+     */
     public enum CC {
         // @formatter:off
-
+        /**
+         * Condition is considered as 32bit operation condition
+         */
         Icc(0b00, "icc"),
+        /**
+         * Condition is considered as 64bit operation condition
+         */
         Xcc(0b10, "xcc"),
         Ptrcc(getHostWordKind() == Kind.Long ? Xcc.getValue() : Icc.getValue(), "ptrcc"),
         Fcc0(0b00, "fcc0"),
@@ -1308,6 +1377,41 @@
         }
     }
 
+    public enum FCond {
+        Fba(0x8, "fba"),
+        Fbn(0x0, "fbn"),
+        Fbu(0x7, "fbu"),
+        Fbg(0x6, "fbg"),
+        Fbug(0x5, "fbug"),
+        Fbl(0x4, "fbl"),
+        Fbul(0x3, "fbul"),
+        Fblg(0x2, "fblg"),
+        Fbne(0x1, "fbne"),
+        Fbe(0x9, "fbe"),
+        Fbue(0xA, "fbue"),
+        Fbge(0xB, "fbge"),
+        Fbuge(0xC, "fbuge"),
+        Fble(0xD, "fble"),
+        Fbule(0xE, "fbule"),
+        Fbo(0xF, "fbo");
+        private final int value;
+        private final String operator;
+
+        private FCond(int value, String op) {
+            assert value >= 0 && value < 1 << 5 : value; // 4 bits
+            this.value = value;
+            this.operator = op;
+        }
+
+        public int getValue() {
+            return value;
+        }
+
+        public String getOperator() {
+            return operator;
+        }
+    }
+
     public enum ConditionFlag {
         // @formatter:off
 
@@ -1402,6 +1506,9 @@
         }
     }
 
+    /**
+     * Represents the <b>Address Space Identifier</b> defined in the SPARC architec
+     */
     public enum Asi {
         // @formatter:off
 
@@ -1656,6 +1763,48 @@
         }
     }
 
+    public static class Movwtos extends Fmt3p {
+        public Movwtos(Register src, Register dst) {
+            /* VIS3 only */
+            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Movwtos, g0, src, dst);
+        }
+    }
+
+    public static class Movxtod extends Fmt3p {
+        public Movxtod(Register src, Register dst) {
+            /* VIS3 only */
+            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Movxtod, g0, src, dst);
+        }
+    }
+
+    public static class Movdtox extends Fmt3p {
+        public Movdtox(Register src, Register dst) {
+            /* VIS3 only */
+            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Movdtox, g0, src, dst);
+        }
+    }
+
+    public static class Movstosw extends Fmt3p {
+        public Movstosw(Register src, Register dst) {
+            /* VIS3 only */
+            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Movstosw, g0, src, dst);
+        }
+    }
+
+    public static class Movstouw extends Fmt3p {
+        public Movstouw(Register src, Register dst) {
+            /* VIS3 only */
+            super(Ops.ArithOp, Op3s.Impdep1, Opfs.Movstouw, g0, src, dst);
+        }
+    }
+
+    public static class Fdtos extends Fmt3p {
+        public Fdtos(Register src, Register dst) {
+            /* VIS3 only */
+            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fdtos, g0, src, dst);
+        }
+    }
+
     public static class Bpa extends Fmt00c {
 
         public Bpa(int simm19) {
@@ -1906,6 +2055,9 @@
         }
     }
 
+    /**
+     * Compare and Branch if Carry Clear ( Greater not C Than or Equal, Unsigned )
+     */
     public static class Cwbcc extends Fmt00e {
 
         public Cwbcc(SPARCAssembler asm, Register src1, Register src2, int simm10) {
@@ -1917,6 +2069,9 @@
         }
     }
 
+    /**
+     * Compare and Branch if Carry Set (Less Than, Unsigned)
+     */
     public static class Cwbcs extends Fmt00e {
 
         public Cwbcs(SPARCAssembler asm, Register src1, Register src2, int simm10) {
@@ -1928,6 +2083,9 @@
         }
     }
 
+    /**
+     * Compare and Branch if Equal
+     */
     public static class Cwbe extends Fmt00e {
 
         public Cwbe(SPARCAssembler asm, Register src1, Register src2, int simm10) {
@@ -1939,6 +2097,9 @@
         }
     }
 
+    /**
+     * Compare and Branch if Greater
+     */
     public static class Cwbg extends Fmt00e {
 
         public Cwbg(SPARCAssembler asm, Register src1, Register src2, int simm10) {
@@ -1950,6 +2111,9 @@
         }
     }
 
+    /**
+     * Compare and Branch if Greater or Equal
+     */
     public static class Cwbge extends Fmt00e {
 
         public Cwbge(SPARCAssembler asm, Register src1, Register src2, int simm10) {
@@ -1961,6 +2125,9 @@
         }
     }
 
+    /**
+     * Compare and Branch if Greater Unsigned
+     */
     public static class Cwbgu extends Fmt00e {
 
         public Cwbgu(SPARCAssembler asm, Register src1, Register src2, int simm10) {
@@ -1972,6 +2139,9 @@
         }
     }
 
+    /**
+     * Compare and Branch if Less
+     */
     public static class Cwbl extends Fmt00e {
 
         public Cwbl(SPARCAssembler asm, Register src1, Register src2, int simm10) {
@@ -1983,6 +2153,9 @@
         }
     }
 
+    /**
+     * Compare and Branch if Less or Equal
+     */
     public static class Cwble extends Fmt00e {
 
         public Cwble(SPARCAssembler asm, Register src1, Register src2, int simm10) {
@@ -1994,6 +2167,9 @@
         }
     }
 
+    /**
+     * Compare and Branch if Less or Equal Unsigned
+     */
     public static class Cwbleu extends Fmt00e {
 
         public Cwbleu(SPARCAssembler asm, Register src1, Register src2, int simm10) {
@@ -2005,6 +2181,9 @@
         }
     }
 
+    /**
+     * Compare and Branch if Not Equal
+     */
     public static class Cwbne extends Fmt00e {
 
         public Cwbne(SPARCAssembler asm, Register src1, Register src2, int simm10) {
@@ -2016,6 +2195,9 @@
         }
     }
 
+    /**
+     * Compare and Branch if Negative
+     */
     public static class Cwbneg extends Fmt00e {
 
         public Cwbneg(SPARCAssembler asm, Register src1, Register src2, int simm10) {
@@ -2027,6 +2209,9 @@
         }
     }
 
+    /**
+     * Compare and Branch if Positive
+     */
     public static class Cwbpos extends Fmt00e {
 
         public Cwbpos(SPARCAssembler asm, Register src1, Register src2, int simm10) {
@@ -2038,6 +2223,9 @@
         }
     }
 
+    /**
+     * Compare and Branch if Overflow Clear
+     */
     public static class Cwbvc extends Fmt00e {
 
         public Cwbvc(SPARCAssembler asm, Register src1, Register src2, int simm10) {
@@ -2049,6 +2237,9 @@
         }
     }
 
+    /**
+     * Compare and Branch if Overflow Set
+     */
     public static class Cwbvs extends Fmt00e {
 
         public Cwbvs(SPARCAssembler asm, Register src1, Register src2, int simm10) {
@@ -2340,6 +2531,9 @@
         }
     }
 
+    /**
+     * Floating-point multiply-add single (fused)
+     */
     public static class Fmadds extends Fmt5a {
 
         public Fmadds(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) {
@@ -2347,6 +2541,9 @@
         }
     }
 
+    /**
+     * Floating-point multiply-add double (fused)
+     */
     public static class Fmaddd extends Fmt5a {
 
         public Fmaddd(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) {
@@ -2354,6 +2551,9 @@
         }
     }
 
+    /**
+     * 16-bit partitioned average
+     */
     public static class Fmean16 extends Fmt3p {
 
         public Fmean16(Register src1, Register src2, Register dst) {
@@ -2565,6 +2765,30 @@
         }
     }
 
+    public static class Fstox extends Fmt3n {
+
+        public Fstox(SPARCAssembler masm, Register src2, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fstox.getValue(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fdtox extends Fmt3n {
+
+        public Fdtox(SPARCAssembler masm, Register src2, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fdtox.getValue(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fstod extends Fmt3n {
+
+        public Fstod(SPARCAssembler masm, Register src2, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fstod.getValue(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    /**
+     * Convert Double to 32-bit Integer
+     */
     public static class Fdtoi extends Fmt3n {
 
         public Fdtoi(SPARCAssembler masm, Register src2, Register dst) {
@@ -2572,6 +2796,30 @@
         }
     }
 
+    public static class Fitos extends Fmt3n {
+
+        public Fitos(SPARCAssembler masm, Register src2, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fitos.getValue(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fitod extends Fmt3n {
+
+        public Fitod(SPARCAssembler masm, Register src2, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fitod.getValue(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fxtod extends Fmt3n {
+
+        public Fxtod(SPARCAssembler masm, Register src2, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fxtod.getValue(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    /**
+     * Flush register windows
+     */
     public static class Flushw extends Fmt10 {
 
         public Flushw() {
@@ -2770,6 +3018,20 @@
         }
     }
 
+    public static class Fcmp extends Fmt3c {
+
+        public Fcmp(CC cc, Opfs opf, Register r1, Register r2) {
+            super(Ops.ArithOp, cc, 0b110101, opf, r1, r2);
+        }
+    }
+
+    public static class Fbfcc extends Fmt00b {
+
+        public Fbfcc(SPARCAssembler asm, FCond cond, boolean annul, int disp) {
+            super(asm, Ops.BranchOp.getValue(), annul ? 1 : 0, cond.getValue(), 0b110, disp);
+        }
+    }
+
     public static class Illtrap extends Fmt00a {
 
         public Illtrap(int const22) {
@@ -2789,6 +3051,10 @@
         public Lddf(SPARCAddress src, Register dst) {
             super(Op3s.Lddf, src, dst);
         }
+
+        public Lddf(Register src, Register dst) {
+            super(Op3s.Lddf, src, dst);
+        }
     }
 
     public static class Ldf extends Fmt11 {
@@ -2796,6 +3062,10 @@
         public Ldf(SPARCAddress src, Register dst) {
             super(Op3s.Ldf, src, dst);
         }
+
+        public Ldf(Register src, Register dst) {
+            super(Op3s.Ldf, src, dst);
+        }
     }
 
     public static class Ldsb extends Fmt11 {
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Mon Jun 30 18:03:24 2014 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Mon Jun 30 18:46:36 2014 +0200
@@ -452,6 +452,9 @@
     public Value emitNegate(Value input) {
         Variable result = newVariable(input.getLIRKind());
         switch (input.getKind().getStackKind()) {
+            case Long:
+                append(new Op1Stack(LNEG, result, input));
+                break;
             case Int:
                 append(new Op1Stack(INEG, result, input));
                 break;
@@ -623,6 +626,7 @@
     @Override
     public Value emitRem(Value a, Value b, LIRFrameState state) {
         Variable result = newVariable(a.getLIRKind());
+        Variable q = null;
         switch (a.getKind().getStackKind()) {
             case Int:
                 append(new RemOp(IREM, result, a, loadNonConst(b), state, this));
@@ -630,6 +634,22 @@
             case Long:
                 append(new RemOp(LREM, result, a, loadNonConst(b), state, this));
                 break;
+            case Float:
+                q = newVariable(LIRKind.value(Kind.Float));
+                append(new Op2Stack(FDIV, q, a, b));
+                append(new Unary2Op(F2I, q, q));
+                append(new Unary2Op(I2F, q, q));
+                append(new Op2Stack(FMUL, q, q, b));
+                append(new Op2Stack(FSUB, result, a, q));
+                break;
+            case Double:
+                q = newVariable(LIRKind.value(Kind.Double));
+                append(new Op2Stack(DDIV, q, a, b));
+                append(new Unary2Op(D2L, q, q));
+                append(new Unary2Op(L2D, q, q));
+                append(new Op2Stack(DMUL, q, q, b));
+                append(new Op2Stack(DSUB, result, a, q));
+                break;
             default:
                 throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind());
         }
@@ -777,19 +797,33 @@
     @Override
     public Value emitFloatConvert(FloatConvert op, Value inputVal) {
         AllocatableValue input = asAllocatable(inputVal);
+        Kind fromRegisterKind = null;
+        Kind toRegisterKind = null;
+        SPARCArithmetic conversionInstruction = null;
         switch (op) {
             case D2F:
                 return emitConvert2Op(LIRKind.value(Kind.Float), D2F, input);
             case D2I:
-                return emitConvert2Op(LIRKind.value(Kind.Int), D2I, input);
+                fromRegisterKind = Kind.Double;
+                toRegisterKind = Kind.Int;
+                conversionInstruction = D2I;
+                break;
+            case F2L:
+                Variable v = newVariable(LIRKind.value(Kind.Double));
+                emitMove(v, input);
+                input = v;
             case D2L:
-                return emitConvert2Op(LIRKind.value(Kind.Long), D2L, input);
+                fromRegisterKind = Kind.Double;
+                toRegisterKind = Kind.Long;
+                conversionInstruction = D2L;
+                break;
             case F2D:
                 return emitConvert2Op(LIRKind.value(Kind.Double), F2D, input);
             case F2I:
-                return emitConvert2Op(LIRKind.value(Kind.Int), F2I, input);
-            case F2L:
-                return emitConvert2Op(LIRKind.value(Kind.Long), F2L, input);
+                fromRegisterKind = Kind.Float;
+                toRegisterKind = Kind.Int;
+                conversionInstruction = F2I;
+                break;
             case I2D:
                 return emitConvert2Op(LIRKind.value(Kind.Double), I2D, input);
             case I2F:
@@ -801,6 +835,13 @@
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
+        if (fromRegisterKind != null) {
+            AllocatableValue var = newVariable(LIRKind.value(toRegisterKind));
+            emitMove(var, emitConvert2Op(LIRKind.value(fromRegisterKind), conversionInstruction, input));
+            return var;
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
+        }
     }
 
     @Override
@@ -856,10 +897,17 @@
             append(new BinaryRegConst(SPARCArithmetic.LAND, result, asAllocatable(inputVal), Constant.forLong(mask)));
             return result;
         } else {
-            assert inputVal.getKind() == Kind.Int;
+            assert inputVal.getKind() == Kind.Int || inputVal.getKind() == Kind.Short || inputVal.getKind() == Kind.Byte : inputVal.getKind();
             Variable result = newVariable(LIRKind.value(Kind.Int));
             int mask = (int) IntegerStamp.defaultMask(fromBits);
-            append(new BinaryRegConst(SPARCArithmetic.IAND, result, asAllocatable(inputVal), Constant.forInt(mask)));
+            Constant constant = Constant.forInt(mask);
+            if (canInlineConstant(constant)) {
+                append(new BinaryRegConst(SPARCArithmetic.IAND, result, asAllocatable(inputVal), constant));
+            } else {
+                Variable maskVar = newVariable(LIRKind.value(Kind.Int));
+                emitMove(maskVar, constant);
+                append(new BinaryRegReg(IAND, result, maskVar, (inputVal)));
+            }
             if (toBits > 32) {
                 Variable longResult = newVariable(LIRKind.value(Kind.Long));
                 emitMove(longResult, result);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotForeignCallsProvider.java	Mon Jun 30 18:03:24 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotForeignCallsProvider.java	Mon Jun 30 18:46:36 2014 +0200
@@ -61,7 +61,8 @@
         register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF_NOFP, outgoingExceptionCc, incomingExceptionCc, NOT_REEXECUTABLE, ANY_LOCATION));
         register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF_NOFP, outgoingExceptionCc, incomingExceptionCc, NOT_REEXECUTABLE, ANY_LOCATION));
 
-        link(new SPARCDeoptimizationStub(providers, target, registerStubCall(UNCOMMON_TRAP_HANDLER, REEXECUTABLE, LEAF, NO_LOCATIONS)));
+        link(new SPARCDeoptimizationStub(providers, target, registerStubCall(DEOPTIMIZATION_HANDLER, REEXECUTABLE, LEAF, NO_LOCATIONS)));
+        link(new SPARCUncommonTrapStub(providers, target, registerStubCall(UNCOMMON_TRAP_HANDLER, REEXECUTABLE, LEAF, NO_LOCATIONS)));
 
         super.initialize(providers, config);
     }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java	Mon Jun 30 18:03:24 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java	Mon Jun 30 18:46:36 2014 +0200
@@ -61,6 +61,10 @@
 
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+        // Move the values up one level to be the input for the next call.
+        new SPARCMacroAssembler.Mov(asRegister(handlerInCallerPc), i2).emit(masm);
+        new SPARCMacroAssembler.Mov(asRegister(exception), i0).emit(masm);
+        new SPARCMacroAssembler.Mov(asRegister(exceptionPc), i1).emit(masm);
         leaveFrame(crb);
 
         // Restore SP from L7 if the exception PC is a method handle call site.
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Mon Jun 30 18:03:24 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Mon Jun 30 18:46:36 2014 +0200
@@ -290,6 +290,19 @@
         return result;
     }
 
+    @Override
+    public Value emitDeoptimizationFetchUnrollInfoCall(SaveRegistersOp saveRegisterOp) {
+        ForeignCallLinkage linkage = getForeignCalls().lookupForeignCall(FETCH_UNROLL_INFO);
+
+        Register threadRegister = getProviders().getRegisters().getThreadRegister();
+        Register stackPointerRegister = getProviders().getRegisters().getStackPointerRegister();
+        append(new SPARCHotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), threadRegister, stackPointerRegister));
+        Variable result = super.emitForeignCall(linkage, null, threadRegister.asValue(LIRKind.value(Kind.Long)));
+        append(new SPARCHotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadJavaFrameAnchorFlagsOffset(), threadRegister));
+
+        return result;
+    }
+
     public void emitNullCheck(Value address, LIRFrameState state) {
         assert address.getKind() == Kind.Object : address + " - " + address.getKind() + " not an object!";
         append(new NullCheckOp(load(address), state));
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java	Mon Jun 30 18:03:24 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java	Mon Jun 30 18:46:36 2014 +0200
@@ -28,12 +28,13 @@
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.sparc.*;
 
 /**
  * Pops the current frame off the stack.
  */
 @Opcode("LEAVE_CURRENT_STACK_FRAME")
-final class SPARCHotSpotLeaveCurrentStackFrameOp extends SPARCHotSpotEpilogueOp {
+final class SPARCHotSpotLeaveCurrentStackFrameOp extends SPARCLIRInstruction {
 
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
@@ -44,6 +45,6 @@
         new Mov(o3, i3).emit(masm);
         new Mov(o4, i4).emit(masm);
 
-        leaveFrame(crb);
+        crb.frameContext.leave(crb);
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveDeoptimizedStackFrameOp.java	Mon Jun 30 18:03:24 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveDeoptimizedStackFrameOp.java	Mon Jun 30 18:46:36 2014 +0200
@@ -28,12 +28,13 @@
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.sparc.*;
 
 /**
  * Pops the current frame off the stack including the return address.
  */
 @Opcode("LEAVE_DEOPTIMIZED_STACK_FRAME")
-final class SPARCHotSpotLeaveDeoptimizedStackFrameOp extends SPARCHotSpotEpilogueOp {
+final class SPARCHotSpotLeaveDeoptimizedStackFrameOp extends SPARCLIRInstruction {
 
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java	Mon Jun 30 18:03:24 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java	Mon Jun 30 18:46:36 2014 +0200
@@ -24,10 +24,12 @@
 
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 import static com.oracle.graal.sparc.SPARC.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
+import com.oracle.graal.asm.sparc.SPARCAssembler.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
@@ -48,8 +50,17 @@
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         // FIXME This is non-trivial. On SPARC we need to flush all register windows first before we
         // can patch the return address (see: frame::patch_pc).
-        // int frameSize = crb.frameMap.frameSize();
-        // new Stx(asRegister(address), new SPARCAddress(sp, frameSize));
-        new Ldx(new SPARCAddress(g0, 0x123), g0).emit(masm);
+        new Flushw().emit(masm);
+// int frameSize = crb.frameMap.frameSize();
+// new SPARCAssembler.Ldx(new SPARCAddress(o7, 1), g3).emit(masm);
+        // new Setx(8 * 15 - 1, g4, false).emit(masm);
+        new Mov(asLongReg(address), g4).emit(masm);
+        new Save(sp, -2000, sp).emit(masm);
+
+        new Sub(g4, 0, i7).emit(masm);
+        new Stx(i7, new SPARCAddress(fp, 8 * 15)).emit(masm);
+        new Restore(g0, g0, g0).emit(masm);
+        new Flushw().emit(masm);
+        // new Ldx(new SPARCAddress(g0, 0x123), g0).emit(masm);
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Mon Jun 30 18:03:24 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Mon Jun 30 18:46:36 2014 +0200
@@ -58,7 +58,15 @@
         ArrayList<Register> list = new ArrayList<>();
         for (Register reg : getAllocatableRegisters()) {
             if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) {
-                list.add(reg);
+                // Special treatment for double precision
+                if (kind == Kind.Double) {
+                    // Only even register numbers are valid double precision regs
+                    if (reg.number % 2 == 0) {
+                        list.add(reg);
+                    }
+                } else {
+                    list.add(reg);
+                }
             }
         }
 
@@ -201,8 +209,18 @@
                         locations[i] = register.asValue(target.getLIRKind(kind));
                     }
                     break;
+                case Double:
+                    if (!stackOnly && currentFloating < fpuParameterRegisters.length) {
+                        if (currentFloating % 2 != 0) {
+                            // Make register number even to be a double reg
+                            currentFloating++;
+                        }
+                        Register register = fpuParameterRegisters[currentFloating];
+                        currentFloating += 2; // Only every second is a double register
+                        locations[i] = register.asValue(target.getLIRKind(kind));
+                    }
+                    break;
                 case Float:
-                case Double:
                     if (!stackOnly && currentFloating < fpuParameterRegisters.length) {
                         Register register = fpuParameterRegisters[currentFloating++];
                         locations[i] = register.asValue(target.getLIRKind(kind));
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java	Mon Jun 30 18:03:24 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java	Mon Jun 30 18:46:36 2014 +0200
@@ -49,6 +49,9 @@
 
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+        // This Frame is left but the called unwind (which is sibling) method needs the exception as
+        // input in i0
+        new Mov(o0, i0).emit(masm);
         leaveFrame(crb);
 
         ForeignCallLinkage linkage = crb.foreignCalls.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER);
@@ -59,7 +62,6 @@
         // Get return address (is in o7 after leave).
         Register returnAddress = asRegister(cc.getArgument(1));
         new Mov(o7, returnAddress).emit(masm);
-
         Register scratch = g5;
         SPARCCall.indirectJmp(crb, masm, scratch, linkage);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCUncommonTrapStub.java	Mon Jun 30 18:46:36 2014 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.sparc;
+
+import static com.oracle.graal.sparc.SPARC.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.stubs.*;
+
+final class SPARCUncommonTrapStub extends UncommonTrapStub {
+
+    private RegisterConfig registerConfig;
+
+    public SPARCUncommonTrapStub(HotSpotProviders providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
+        super(providers, target, linkage);
+        // This is basically the maximum we can spare. All other G and O register are used.
+        Register[] allocatable = new Register[]{g1, g3, g4, g5, o0, o1, o2, o3, o4};
+        registerConfig = new SPARCHotSpotRegisterConfig(target, allocatable);
+    }
+
+    @Override
+    public RegisterConfig getRegisterConfig() {
+        return registerConfig;
+    }
+
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotForeignCallsProviderImpl.java	Mon Jun 30 18:03:24 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotForeignCallsProviderImpl.java	Mon Jun 30 18:46:36 2014 +0200
@@ -69,7 +69,7 @@
 
     /**
      * Creates and registers the details for linking a foreign call to a {@link Stub}.
-     * 
+     *
      * @param descriptor the signature of the call to the stub
      * @param reexecutable specifies if the stub call can be re-executed without (meaningful) side
      *            effects. Deoptimization will not return to a point before a stub call that cannot
@@ -83,7 +83,7 @@
 
     /**
      * Creates and registers the linkage for a foreign call.
-     * 
+     *
      * @param descriptor the signature of the foreign call
      * @param address the address of the code to call
      * @param outgoingCcType outgoing (caller) calling convention type
@@ -104,7 +104,7 @@
 
     /**
      * Creates a {@linkplain ForeignCallStub stub} for a foreign call.
-     * 
+     *
      * @param descriptor the signature of the call to the stub
      * @param address the address of the foreign code to call
      * @param prependThread true if the JavaThread value for the current thread is to be prepended
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_fadd.java	Mon Jun 30 18:03:24 2014 +0200
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_fadd.java	Mon Jun 30 18:46:36 2014 +0200
@@ -49,4 +49,14 @@
         runTest("test", 253.11f, 54.43f);
     }
 
+    @Test
+    public void run3() throws Throwable {
+        runTest("test", Float.MAX_VALUE, Float.MIN_VALUE);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        runTest("test", Float.MAX_VALUE / 2, Float.MAX_VALUE / 2);
+    }
+
 }
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_i2d.java	Mon Jun 30 18:03:24 2014 +0200
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_i2d.java	Mon Jun 30 18:46:36 2014 +0200
@@ -49,4 +49,24 @@
         runTest("test", -34);
     }
 
+    @Test
+    public void run3() throws Throwable {
+        runTest("test", Integer.MIN_VALUE);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        runTest("test", Integer.MAX_VALUE);
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        runTest("test", 34);
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        runTest("test", new Integer(Short.MAX_VALUE));
+    }
+
 }
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_lcmp.java	Mon Jun 30 18:03:24 2014 +0200
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_lcmp.java	Mon Jun 30 18:46:36 2014 +0200
@@ -49,4 +49,24 @@
         runTest("test", -1L, 0L);
     }
 
+    /**
+     * Test with ugly numbers (which probably does not fit into one instruction
+     *
+     * @throws Throwable
+     */
+    @Test
+    public void run3() throws Throwable {
+        runTest("test", 293521900824L, 97726785831L);
+    }
+
+    /**
+     * Test with big numbers where it makes difference if the value is handled with 64 bits
+     *
+     * @throws Throwable
+     */
+    @Test
+    public void run4() throws Throwable {
+        runTest("test", -1L, Long.MIN_VALUE);
+    }
+
 }
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/except/BC_ldiv2.java	Mon Jun 30 18:03:24 2014 +0200
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/except/BC_ldiv2.java	Mon Jun 30 18:46:36 2014 +0200
@@ -49,4 +49,19 @@
         runTest("test", 11L, 0L);
     }
 
+    @Test
+    public void run2() throws Throwable {
+        runTest("test", 11L, 1000000000000L);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        runTest("test", 1000000000000L, 11L);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        runTest("test", 1000000000000L, 0L);
+    }
+
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Mon Jun 30 18:03:24 2014 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Mon Jun 30 18:46:36 2014 +0200
@@ -28,38 +28,12 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Add;
-import com.oracle.graal.asm.sparc.SPARCAssembler.And;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Faddd;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fadds;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fdivd;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fdivs;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fdtoi;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fmuld;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fmuls;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fnegd;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fnegs;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fstoi;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fsubd;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fsubs;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Mulx;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Or;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Sdivx;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Sll;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Sllx;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Sra;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Srax;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Srl;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Srlx;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Sub;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Xor;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Neg;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Not;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Signx;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.gen.*;
+import com.oracle.graal.sparc.*;
 
 public enum SPARCArithmetic {
     // @formatter:off
@@ -150,17 +124,23 @@
         @Def({REG}) protected Value result;
         @Use({REG, CONST}) protected Value x;
         @Alive({REG, CONST}) protected Value y;
+        @State LIRFrameState state;
 
         public BinaryRegReg(SPARCArithmetic opcode, Value result, Value x, Value y) {
+            this(opcode, result, x, y, null);
+        }
+
+        public BinaryRegReg(SPARCArithmetic opcode, Value result, Value x, Value y, LIRFrameState state) {
             this.opcode = opcode;
             this.result = result;
             this.x = x;
             this.y = y;
+            this.state = state;
         }
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            emit(crb, masm, opcode, result, x, y, null);
+            emit(crb, masm, opcode, result, x, y, state);
         }
 
         @Override
@@ -288,9 +268,9 @@
         }
     }
 
-    public static void emit(CompilationResultBuilder crb, SPARCAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info) {
+    public static void emit(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info) {
         int exceptionOffset = -1;
-        if (isConstant(src1)) {
+        if (isConstant(src1) && !isConstant(src2)) {
             switch (opcode) {
                 case ISUB:
                     assert isSimm13(crb.asIntConst(src1));
@@ -303,6 +283,13 @@
                     throw GraalInternalError.unimplemented();
                     // new Sdivx(masm, asIntReg(src1), asIntReg(src2),
                     // asIntReg(dst));
+                case LDIV:
+                    int c = crb.asIntConst(src1);
+                    assert isSimm13(c);
+                    exceptionOffset = masm.position();
+                    new Sdivx(asLongReg(src2), c, asLongReg(dst)).emit(masm);
+                    new Mulx(asLongReg(src1), asLongReg(dst), asLongReg(dst)).emit(masm);
+                    break;
                 case FSUB:
                 case FDIV:
                 case DSUB:
@@ -330,7 +317,7 @@
                     new Sdivx(asIntReg(src1), crb.asIntConst(src2), asIntReg(dst)).emit(masm);
                     break;
                 case IAND:
-                    assert isSimm13(crb.asIntConst(src2));
+                    assert isSimm13(crb.asIntConst(src2)) : src2;
                     new And(asIntReg(src1), crb.asIntConst(src2), asIntReg(dst)).emit(masm);
                     break;
                 case ISHL:
@@ -366,7 +353,17 @@
                     new Mulx(asLongReg(src1), crb.asIntConst(src2), asLongReg(dst)).emit(masm);
                     break;
                 case LDIV:
-                    throw GraalInternalError.unimplemented();
+                    int c = crb.asIntConst(src2);
+                    exceptionOffset = masm.position();
+                    if (c == 0) { // Generate div by zero trap
+                        new Sdivx(SPARC.g0, 0, asLongReg(dst)).emit(masm);
+                    } else if (isConstant(src1)) { // Both are const, therefore just load the const
+                        new Setx(crb.asIntConst(src1) / c, asLongReg(dst), false).emit(masm);
+                    } else { // Otherwise try to divide
+                        assert isSimm13(crb.asLongConst(src2));
+                        new Sdivx(asLongReg(src1), crb.asIntConst(src2), asLongReg(dst)).emit(masm);
+                    }
+                    break;
                 case LUDIV:
                     throw GraalInternalError.unimplemented();
                 case LAND:
@@ -431,10 +428,10 @@
                     new Sll(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
                     break;
                 case ISHR:
-                    new Srl(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
+                    new Sra(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
                     break;
                 case IUSHR:
-                    new Sra(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
+                    new Srl(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
                     break;
                 case IREM:
                     throw GraalInternalError.unimplemented();
@@ -448,6 +445,7 @@
                     new Mulx(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
                     break;
                 case LDIV:
+                    exceptionOffset = masm.position();
                     new Sdivx(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
                     break;
                 case LUDIV:
@@ -502,16 +500,42 @@
                     throw GraalInternalError.shouldNotReachHere();
             }
         }
-
         if (info != null) {
             assert exceptionOffset != -1;
             crb.recordImplicitException(exceptionOffset, info);
         }
     }
 
-    public static void emit(CompilationResultBuilder crb, SPARCAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, Value scratch1, Value scratch2, LIRFrameState info) {
+    public static void emit(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, Value scratch1, Value scratch2, LIRFrameState info) {
         int exceptionOffset = -1;
-        if (isConstant(src1)) {
+        if (isConstant(src1) && isConstant(src2)) {
+            switch (opcode) {
+                case IREM: {
+                    int a = crb.asIntConst(src1);
+                    int b = crb.asIntConst(src2);
+                    if (b == 0) {
+                        exceptionOffset = masm.position();
+                        new Sdivx(SPARC.g0, 0, asIntReg(dst)).emit(masm);
+                    } else {
+                        new Setx(a % b, asIntReg(dst), false).emit(masm);
+                    }
+                }
+                    break;
+                case LREM: {
+                    long a = crb.asLongConst(src1);
+                    long b = crb.asLongConst(src2);
+                    if (b == 0) {
+                        exceptionOffset = masm.position();
+                        new Sdivx(SPARC.g0, 0, asLongReg(dst)).emit(masm);
+                    } else {
+                        new Setx(a % b, asLongReg(dst), false).emit(masm);
+                    }
+                }
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere("not implemented");
+            }
+        } else if (isConstant(src1)) {
             switch (opcode) {
                 default:
                     throw GraalInternalError.shouldNotReachHere();
@@ -521,12 +545,14 @@
                 case IREM:
                     assert isSimm13(crb.asIntConst(src2));
                     new Sra(asIntReg(src1), 0, asIntReg(src1)).emit(masm);
+                    exceptionOffset = masm.position();
                     new Sdivx(asIntReg(src1), crb.asIntConst(src2), asIntReg(scratch1)).emit(masm);
                     new Mulx(asIntReg(scratch1), crb.asIntConst(src2), asIntReg(scratch2)).emit(masm);
                     new Sub(asIntReg(src1), asIntReg(scratch2), asIntReg(dst)).emit(masm);
                     break;
                 case LREM:
                     assert isSimm13(crb.asIntConst(src2));
+                    exceptionOffset = masm.position();
                     new Sdivx(asLongReg(src1), crb.asIntConst(src2), asLongReg(scratch1)).emit(masm);
                     new Mulx(asLongReg(scratch1), crb.asIntConst(src2), asLongReg(scratch2)).emit(masm);
                     new Sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst)).emit(masm);
@@ -539,6 +565,17 @@
         } else {
             switch (opcode) {
                 case LREM:
+                    exceptionOffset = masm.position();
+                    new Sdivx(asLongReg(src1), asLongReg(src2), asLongReg(scratch1)).emit(masm);
+                    new Mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch2)).emit(masm);
+                    new Sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst)).emit(masm);
+                    break;
+                case IREM:
+                    exceptionOffset = masm.position();
+                    new Sdivx(asIntReg(src1), asIntReg(src2), asIntReg(scratch1)).emit(masm);
+                    new Mulx(asIntReg(scratch1), asIntReg(src2), asIntReg(scratch2)).emit(masm);
+                    new Sub(asIntReg(src1), asIntReg(scratch2), asIntReg(dst)).emit(masm);
+                    break;
                 case LUREM:
                     throw GraalInternalError.unimplemented();
                 default:
@@ -560,31 +597,90 @@
                 case INEG:
                     new Neg(asIntReg(src), asIntReg(dst)).emit(masm);
                     break;
+                case LNEG:
+                    new Neg(asLongReg(src), asLongReg(dst)).emit(masm);
+                    break;
                 case INOT:
                     new Not(asIntReg(src), asIntReg(dst)).emit(masm);
                     break;
                 case LNOT:
                     new Not(asLongReg(src), asLongReg(dst)).emit(masm);
                     break;
+                case D2F:
+                    new Fdtos(asDoubleReg(src), asFloatReg(dst)).emit(masm);
+                    break;
+                case L2D:
+                    if (src.getPlatformKind() == Kind.Long) {
+                        new Movxtod(asLongReg(src), asDoubleReg(dst)).emit(masm);
+                        new Fxtod(masm, asDoubleReg(dst), asDoubleReg(dst));
+                    } else if (src.getPlatformKind() == Kind.Double) {
+                        new Fxtod(masm, asDoubleReg(src), asDoubleReg(dst));
+                    } else {
+                        throw GraalInternalError.shouldNotReachHere("cannot handle source register " + src.getPlatformKind());
+                    }
+                    break;
                 case I2L:
                     new Signx(asIntReg(src), asLongReg(dst)).emit(masm);
                     break;
                 case L2I:
                     new Signx(asLongReg(src), asIntReg(dst)).emit(masm);
                     break;
+                case B2L:
+                    new Sllx(asIntReg(src), 56, asLongReg(dst)).emit(masm);
+                    new Srax(asLongReg(dst), 56, asLongReg(dst)).emit(masm);
+                    break;
+                case S2L:
+                    new Sllx(asIntReg(src), 48, asLongReg(dst)).emit(masm);
+                    new Srax(asLongReg(dst), 48, asLongReg(dst)).emit(masm);
+                    break;
                 case B2I:
                     new Sll(asIntReg(src), 24, asIntReg(dst)).emit(masm);
-                    new Srl(asIntReg(dst), 24, asIntReg(dst)).emit(masm);
+                    new Sra(asIntReg(dst), 24, asIntReg(dst)).emit(masm);
                     break;
                 case S2I:
                     new Sll(asIntReg(src), 16, asIntReg(dst)).emit(masm);
-                    new Srl(asIntReg(dst), 16, asIntReg(dst)).emit(masm);
+                    new Sra(asIntReg(dst), 16, asIntReg(dst)).emit(masm);
                     break;
                 case I2F:
-                    new Fstoi(masm, asIntReg(src), asFloatReg(dst));
+                    if (src.getPlatformKind() == Kind.Int) {
+                        new Movwtos(asIntReg(src), asFloatReg(dst)).emit(masm);
+                        new Fitos(masm, asFloatReg(dst), asFloatReg(dst));
+                    } else if (src.getPlatformKind() == Kind.Float) {
+                        new Fitos(masm, asFloatReg(src), asFloatReg(dst));
+                    } else {
+                        throw GraalInternalError.shouldNotReachHere("cannot handle source register " + src.getPlatformKind());
+                    }
+                    break;
+                case F2D:
+                    new Fstod(masm, asFloatReg(src), asDoubleReg(dst));
+                    break;
+                case F2L:
+                    new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(dst), asFloatReg(dst)).emit(masm);
+                    new Fbfcc(masm, FCond.Fbo, false, 4);
+                    new Fstox(masm, asFloatReg(src), asFloatReg(dst));
+                    new Fitos(masm, asFloatReg(dst), asFloatReg(dst));
+                    new Fsubs(asFloatReg(dst), asFloatReg(dst), asFloatReg(dst)).emit(masm);
                     break;
-                case I2D:
-                    new Fdtoi(masm, asIntReg(src), asDoubleReg(dst));
+                case F2I:
+                    new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(dst), asFloatReg(dst)).emit(masm);
+                    new Fbfcc(masm, FCond.Fbo, false, 4);
+                    new Fstoi(masm, asFloatReg(src), asFloatReg(dst));
+                    new Fitos(masm, asFloatReg(dst), asFloatReg(dst));
+                    new Fsubs(asFloatReg(dst), asFloatReg(dst), asFloatReg(dst)).emit(masm);
+                    break;
+                case D2L:
+                    new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(dst), asDoubleReg(dst)).emit(masm);
+                    new Fbfcc(masm, FCond.Fbo, false, 4);
+                    new Fdtox(masm, asDoubleReg(src), asDoubleReg(dst));
+                    new Fxtod(masm, asDoubleReg(dst), asDoubleReg(dst));
+                    new Fsubd(asDoubleReg(dst), asDoubleReg(dst), asDoubleReg(dst)).emit(masm);
+                    break;
+                case D2I:
+                    new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(dst), asDoubleReg(dst)).emit(masm);
+                    new Fbfcc(masm, FCond.Fbo, false, 4);
+                    new Fdtoi(masm, asDoubleReg(src), asDoubleReg(dst));
+                    new Fitod(masm, asDoubleReg(dst), asDoubleReg(dst));
+                    new Fsubd(asDoubleReg(dst), asDoubleReg(dst), asDoubleReg(dst)).emit(masm);
                     break;
                 case FNEG:
                     new Fnegs(masm, asFloatReg(src), asFloatReg(dst));
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java	Mon Jun 30 18:03:24 2014 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java	Mon Jun 30 18:46:36 2014 +0200
@@ -60,9 +60,17 @@
         @Override
         protected void verify() {
             super.verify();
-            assert (name().startsWith("I") && x.getKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) || (name().startsWith("L") && x.getKind() == Kind.Long && y.getKind() == Kind.Long) ||
-                            (name().startsWith("A") && x.getKind() == Kind.Object && y.getKind() == Kind.Object) ||
-                            (name().startsWith("F") && x.getKind() == Kind.Float && y.getKind() == Kind.Float) || (name().startsWith("D") && x.getKind() == Kind.Double && y.getKind() == Kind.Double);
+
+            // @formatter:off
+            assert  (name().startsWith("I") && (x.getKind() == Kind.Int || x.getKind()==Kind.Byte) &&
+                            (y.getKind().getStackKind() == Kind.Int || y.getKind().getStackKind() == Kind.Byte)) ||
+                    (name().startsWith("L") && x.getKind() == Kind.Long && y.getKind() == Kind.Long) ||
+                    (name().startsWith("A") && x.getKind() == Kind.Object && y.getKind() == Kind.Object) ||
+                    (name().startsWith("F") && x.getKind() == Kind.Float && y.getKind() == Kind.Float) ||
+                    (name().startsWith("D") && x.getKind() == Kind.Double && y.getKind() == Kind.Double)
+                    : "Name; " + name() + " x: " + x + " y: " + y;
+
+            // @formatter:on
         }
     }
 
@@ -79,11 +87,11 @@
                     new Cmp(asObjectReg(x), asObjectReg(y)).emit(masm);
                     break;
                 case FCMP:
-                    // masm.ucomiss(asFloatReg(x), asFloatReg(y));
-                    // break;
+                    new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(x), asFloatReg(y)).emit(masm);
+                    break;
                 case DCMP:
-                    // masm.ucomisd(asDoubleReg(x), asDoubleReg(y));
-                    // break;
+                    new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(x), asDoubleReg(y)).emit(masm);
+                    break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
             }
@@ -106,11 +114,11 @@
                         throw GraalInternalError.shouldNotReachHere("Only null object constants are allowed in comparisons");
                     }
                 case FCMP:
-                    // masm.ucomiss(asFloatReg(x), (AMD64Address) crb.asFloatConstRef(y));
-                    // break;
+                    new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(x), asFloatReg(y)).emit(masm);
+                    break;
                 case DCMP:
-                    // masm.ucomisd(asDoubleReg(x), (AMD64Address) crb.asDoubleConstRef(y));
-                    // break;
+                    new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(x), asDoubleReg(y)).emit(masm);
+                    break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
             }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Mon Jun 30 18:03:24 2014 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Mon Jun 30 18:46:36 2014 +0200
@@ -40,6 +40,8 @@
 import com.oracle.graal.asm.sparc.SPARCAssembler.Bpne;
 import com.oracle.graal.asm.sparc.SPARCAssembler.CC;
 import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag;
+import com.oracle.graal.asm.sparc.SPARCAssembler.FCond;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fbfcc;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Movcc;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Sub;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Bpgeu;
@@ -320,19 +322,17 @@
             // check that we don't overwrite an input operand before it is used.
             assert !result.equals(trueValue);
 
-            SPARCMove.move(crb, masm, result, falseValue);
-            cmove(crb, masm, kind, result, condition, trueValue);
-
-            if (unorderedIsTrue && !trueOnUnordered(condition)) {
-                // cmove(crb, masm, result, ConditionFlag.Parity, trueValue);
-                throw GraalInternalError.unimplemented();
-            } else if (!unorderedIsTrue && trueOnUnordered(condition)) {
-                // cmove(crb, masm, result, ConditionFlag.Parity, falseValue);
-                throw GraalInternalError.unimplemented();
+            SPARCMove.move(crb, masm, result, trueValue);
+            cmove(crb, masm, kind, result, condition, falseValue);
+            // TODO: This may be omitted, when doing the right check beforehand (There are
+            // instructions which control the unordered behavior as well)
+            if (!unorderedIsTrue) {
+                cmove(crb, masm, kind, result, ConditionFlag.F_Unordered, falseValue);
             }
         }
     }
 
+    @SuppressWarnings("unused")
     private static void cmove(CompilationResultBuilder crb, SPARCMacroAssembler masm, Kind kind, Value result, ConditionFlag cond, Value other) {
         if (!isRegister(other)) {
             SPARCMove.move(crb, masm, result, other);
@@ -347,6 +347,38 @@
             case Object:
                 new Movcc(cond, CC.Xcc, asRegister(other), asRegister(result)).emit(masm);
                 break;
+            case Float:
+            case Double:
+                FCond fc = null;
+                switch (cond) {
+                    case Equal:
+                        fc = FCond.Fbne;
+                        break;
+                    case Greater:
+                        fc = FCond.Fble;
+                        break;
+                    case GreaterEqual:
+                        fc = FCond.Fbl;
+                        break;
+                    case Less:
+                        fc = FCond.Fbge;
+                        break;
+                    case LessEqual:
+                        fc = FCond.Fbg;
+                        break;
+                    case F_Ordered:
+                        fc = FCond.Fbo;
+                        break;
+                    case F_Unordered:
+                        fc = FCond.Fbu;
+                        break;
+                    default:
+                        GraalInternalError.shouldNotReachHere("Unknown condition code " + cond);
+                        break;
+                }
+                new Fbfcc(masm, fc, true, 2);
+                SPARCMove.move(crb, masm, result, other);
+                break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
@@ -382,24 +414,15 @@
             case NE:
                 return ConditionFlag.NotEqual;
             case LT:
+                return ConditionFlag.Less;
             case LE:
+                return ConditionFlag.LessEqual;
             case GE:
+                return ConditionFlag.GreaterEqual;
             case GT:
+                return ConditionFlag.Greater;
             default:
-                throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
-    private static boolean trueOnUnordered(ConditionFlag condition) {
-        switch (condition) {
-            case NotEqual:
-            case Less:
-                return false;
-            case Equal:
-            case GreaterEqual:
-                return true;
-            default:
-                throw GraalInternalError.shouldNotReachHere();
+                throw GraalInternalError.shouldNotReachHere("Unimplemented for " + cond);
         }
     }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Mon Jun 30 18:03:24 2014 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Mon Jun 30 18:46:36 2014 +0200
@@ -23,24 +23,23 @@
 package com.oracle.graal.lir.sparc;
 
 import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 import static com.oracle.graal.sparc.SPARC.*;
 
+import com.oracle.graal.api.code.CompilationResult.RawData;
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.CompilationResult.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.asm.sparc.SPARCAssembler.*;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.ImplicitNullCheck;
-import com.oracle.graal.lir.StandardOp.MoveOp;
-import com.oracle.graal.lir.StandardOp.NullCheck;
+import com.oracle.graal.lir.StandardOp.*;
 import com.oracle.graal.lir.asm.*;
 
 public class SPARCMove {
 
-    @Opcode("MOVE")
+    @Opcode("MOVE_TOREG")
     public static class MoveToRegOp extends SPARCLIRInstruction implements MoveOp {
 
         @Def({REG, HINT}) protected AllocatableValue result;
@@ -67,7 +66,7 @@
         }
     }
 
-    @Opcode("MOVE")
+    @Opcode("MOVE_FROMREG")
     public static class MoveFromRegOp extends SPARCLIRInstruction implements MoveOp {
 
         @Def({REG, STACK}) protected AllocatableValue result;
@@ -207,7 +206,8 @@
             SPARCAddress addr = (SPARCAddress) crb.recordDataReferenceInCode(rawData);
             assert addr == masm.getPlaceholder();
             final boolean forceRelocatable = true;
-            new Setx(0, asRegister(result), forceRelocatable).emit(masm);
+            Register dstReg = asRegister(result);
+            new Setx(0, dstReg, forceRelocatable).emit(masm);
         }
     }
 
@@ -319,9 +319,13 @@
                     new Stx(asRegister(input), addr).emit(masm);
                     break;
                 case Float:
+                    new Stf(asRegister(input), addr).emit(masm);
+                    break;
                 case Double:
+                    new Stdf(asRegister(input), addr).emit(masm);
+                    break;
                 default:
-                    throw GraalInternalError.shouldNotReachHere("missing: " + address.getKind());
+                    throw GraalInternalError.shouldNotReachHere("missing: " + kind);
             }
         }
     }
@@ -391,10 +395,14 @@
         }
     }
 
+    @SuppressWarnings("unused")
     private static void reg2reg(SPARCAssembler masm, Value result, Value input) {
         final Register src = asRegister(input);
         final Register dst = asRegister(result);
-        if (src.equals(dst)) {
+        // implicit conversions between double and float registers can happen in the "same Register"
+// f0->d0
+        boolean isFloatToDoubleConversion = result.getKind() == Kind.Double && input.getKind() == Kind.Float;
+        if (src.equals(dst) && !isFloatToDoubleConversion) {
             return;
         }
         switch (input.getKind()) {
@@ -404,10 +412,31 @@
                 new Mov(src, dst).emit(masm);
                 break;
             case Float:
-                new Fmovs(src, dst).emit(masm);
+                switch (result.getKind()) {
+                    case Long:
+                        new Movstosw(src, dst).emit(masm);
+                        break;
+                    case Int:
+                        new Movstouw(src, dst).emit(masm);
+                        break;
+                    case Float:
+                        new Fmovs(src, dst).emit(masm);
+                        break;
+                    case Double:
+                        new Fstod(masm, src, dst);
+                        break;
+                    default:
+                        throw GraalInternalError.shouldNotReachHere();
+                }
                 break;
             case Double:
-                new Fmovd(src, dst).emit(masm);
+                if (result.getPlatformKind() == Kind.Long) {
+                    new Movdtox(src, dst).emit(masm);
+                } else if (result.getPlatformKind() == Kind.Int) {
+                    new Movstouw(src, dst).emit(masm);
+                } else {
+                    new Fmovd(src, dst).emit(masm);
+                }
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
@@ -455,6 +484,7 @@
     }
 
     private static void const2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Constant input) {
+        Register scratch = g5;
         switch (input.getKind().getStackKind()) {
             case Int:
                 if (crb.codeCache.needsDataPatch(input)) {
@@ -481,7 +511,19 @@
                 }
                 break;
             case Float:
-                new Ldf((SPARCAddress) crb.asFloatConstRef(input), asFloatReg(result)).emit(masm);
+                crb.asFloatConstRef(input);
+                // First load the address into the scratch register
+                new Setx(0, scratch, true).emit(masm);
+                // Now load the float value
+                new Ldf(scratch, asFloatReg(result)).emit(masm);
+                break;
+            case Double:
+                crb.asDoubleConstRef(input);
+                scratch = g5;
+                // First load the address into the scratch register
+                new Setx(0, scratch, true).emit(masm);
+                // Now load the float value
+                new Lddf(scratch, asDoubleReg(result)).emit(masm);
                 break;
             case Object:
                 if (input.isNull()) {
--- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp	Mon Jun 30 18:03:24 2014 +0200
+++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp	Mon Jun 30 18:46:36 2014 +0200
@@ -59,11 +59,11 @@
 
 void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) {
   address pc = _instructions->start() + pc_offset;
+  address const_start = _constants->start();
   jint offset = DataSectionReference::offset(data);
 
   NativeMovRegMem* load = nativeMovRegMem_at(pc);
-  int disp = _constants_size + pc_offset - offset - BytesPerInstWord;
-  load->set_offset(-disp);
+  load->add_offset_in_bytes((long)const_start+offset);
 }
 
 void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Mon Jun 30 18:03:24 2014 +0200
+++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Mon Jun 30 18:46:36 2014 +0200
@@ -43,6 +43,9 @@
 #include "compiler/compileBroker.hpp"
 #include "shark/sharkCompiler.hpp"
 #endif
+#ifdef GRAAL
+#include "graal/graalJavaAccess.hpp"
+#endif
 
 #define __ masm->
 
@@ -990,6 +993,19 @@
 
   // Jump to the compiled code just as if compiled code was doing it.
   __ ld_ptr(G5_method, in_bytes(Method::from_compiled_offset()), G3);
+#ifdef GRAAL
+  // check if this call should be routed towards a specific entry point
+  __ ld(Address(G2_thread, in_bytes(JavaThread::graal_alternate_call_target_offset())), G1);
+  __ cmp(G0, G1);
+  Label no_alternative_target;
+  __ br(Assembler::equal, false, Assembler::pn, no_alternative_target);
+  __ delayed()->nop();
+
+  __ ld_ptr(G2_thread, in_bytes(JavaThread::graal_alternate_call_target_offset()), G3);
+  __ st(G0, Address(G2_thread, in_bytes(JavaThread::graal_alternate_call_target_offset())));
+
+  __ bind(no_alternative_target);
+#endif
 
   // 6243940 We might end up in handle_wrong_method if
   // the callee is deoptimized as we race thru here. If that
@@ -3483,6 +3499,46 @@
   __ ba(cont);
   __ delayed()->mov(Deoptimization::Unpack_deopt, L0deopt_mode);
 
+
+#ifdef GRAAL
+  masm->block_comment("BEGIN GRAAL");
+  int implicit_exception_uncommon_trap_offset = __ offset() - start;
+  //__ pushptr(Address(G2_thread, in_bytes(JavaThread::graal_implicit_exception_pc_offset())));
+  __ ld_ptr(G2_thread, in_bytes(JavaThread::graal_implicit_exception_pc_offset()), O7);
+  //__ add(G0, 0x321, O7);
+  __ add(O7, -8, O7);
+  //__ st_ptr(I7, SP, I7->sp_offset_in_saved_window()*wordSize + STACK_BIAS);
+  // Save everything in sight.
+  masm->block_comment("save_live_regs");
+  (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
+  masm->block_comment("/save_live_regs");
+  //__ ld_ptr(G2_thread, in_bytes(JavaThread::graal_implicit_exception_pc_offset()), O7);
+  // fetch_unroll_info needs to call last_java_frame()
+  masm->block_comment("set_last_java_frame");
+  __ set_last_Java_frame(SP, NULL);
+  masm->block_comment("/set_last_java_frame");
+
+  //__ movl(c_rarg1, Address(r15_thread, in_bytes(ThreadShadow::pending_deoptimization_offset())));
+  __ ld(G2_thread, in_bytes(ThreadShadow::pending_deoptimization_offset()), O1);
+  //__ movl(Address(r15_thread, in_bytes(ThreadShadow::pending_deoptimization_offset())), -1);
+  __ sub(G0, 1, L1);
+  __ st_ptr(L1, G2_thread, in_bytes(ThreadShadow::pending_deoptimization_offset()));
+
+  __ mov((int32_t)Deoptimization::Unpack_reexecute, L0deopt_mode);
+  __ mov(G2_thread, O0);
+  __ call(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap));
+  __ delayed()->nop();
+  oop_maps->add_gc_map( __ offset()-start, map->deep_copy());
+  __ get_thread();
+  __ add(O7, 8, O7);
+  __ reset_last_Java_frame();
+
+  Label after_fetch_unroll_info_call;
+  __ ba(after_fetch_unroll_info_call);
+  __ delayed()->nop(); // Delay slot
+  masm->block_comment("END GRAAL");
+#endif // GRAAL
+
   int exception_offset = __ offset() - start;
 
   // restore G2, the trampoline destroyed it
@@ -3560,6 +3616,9 @@
 
   __ reset_last_Java_frame();
 
+#ifdef GRAAL
+  __ bind(after_fetch_unroll_info_call);
+#endif
   // NOTE: we know that only O0/O1 will be reloaded by restore_result_registers
   // so this move will survive
 
@@ -3568,7 +3627,6 @@
   __ mov(O0, O2UnrollBlock->after_save());
 
   RegisterSaver::restore_result_registers(masm);
-
   Label noException;
   __ cmp_and_br_short(G4deopt_mode, Deoptimization::Unpack_exception, Assembler::notEqual, Assembler::pt, noException);
 
@@ -3625,6 +3683,9 @@
   masm->flush();
   _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_words);
   _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
+#ifdef GRAAL
+  _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset);
+#endif
 }
 
 #ifdef COMPILER2
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Mon Jun 30 18:03:24 2014 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Mon Jun 30 18:46:36 2014 +0200
@@ -587,7 +587,23 @@
   } else if (jap.get_ret_type() == T_OBJECT || jap.get_ret_type() == T_ARRAY) {
     return JNIHandles::make_local((oop) result.get_jobject());
   } else {
-    oop o = java_lang_boxing_object::create(jap.get_ret_type(), (jvalue *) result.get_value_addr(), CHECK_NULL);
+    jvalue *value = (jvalue *) result.get_value_addr();
+    // Narrow the value down if required (Important on big endian machines)
+    switch (jap.get_ret_type()) {
+      case T_BOOLEAN:
+       value->z = (jboolean) value->i;
+       break;
+      case T_BYTE:
+       value->b = (jbyte) value->i;
+       break;
+      case T_CHAR:
+       value->c = (jchar) value->i;
+       break;
+      case T_SHORT:
+       value->s = (jshort) value->i;
+       break;
+     }
+    oop o = java_lang_boxing_object::create(jap.get_ret_type(), value, CHECK_NULL);
     return JNIHandles::make_local(o);
   }
 C2V_END