changeset 16943:f8e60d11c0ec

Merge
author Stefan Anzinger <stefan.anzinger@oracle.com>
date Mon, 25 Aug 2014 21:15:59 -0700
parents ae0f235469db (diff) 87a40fe1ba0c (current diff)
children a04d9cbc149f 4feac7e51f42
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionHandle.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionInterface.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionPointer.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeLibraryHandle.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/nfi/NativeFunctionInterfaceTest.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/HostBackend.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/InputType.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeInfo.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/DonorThreadPool.java graal/com.oracle.graal.hotspot.jdk8.test/src/com/oracle/graal/hotspot/jdk8/test/CRC32UpdateByteBufferSubstitutionTest.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEnterUnpackFramesStackFrameOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveUnpackFramesStackFrameOp.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/BytecodeVerificationTest.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/GraalClassLoaderTest.java graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/GuardsTest.java graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/SlowPathTest.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Generic.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/PolymorphicLimit.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/AbstractParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/Utils.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/ExtensionContext.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableAnnotationMirror.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableElementFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableExecutableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableVariableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeAnnotationMirror.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeAnnotationValue.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeCompilationUnit.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeElementScanner.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeExecutableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeImport.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeNames.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTree.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTreeBuilder.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTreeKind.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTypeElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTypeMirror.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeVariableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/GeneratedElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/AbstractCodeWriter.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/FixWarningsVisitor.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/GenerateOverrideVisitor.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/OrganizedImports.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/AbstractCompiler.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/Compiler.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/CompilerFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/JDTCompiler.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/JavaCCompiler.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/CreateCastData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/CreateCastParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/GenericParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeChildData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeExecutionData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeFieldData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ShortCircuitData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ShortCircuitParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGuardData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationThrowsData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ActualParameter.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ClassElementFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/CodeElementFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/CompilationUnitFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MessageContainer.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MethodSpec.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ParameterSpec.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/Template.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethod.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/ImplicitCastData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/ImplicitCastParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCastData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCastParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCheckData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCheckParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemCodeGenerator.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemParser.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLASTProber.java
diffstat 29 files changed, 1114 insertions(+), 153 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java	Mon Aug 25 21:15:59 2014 -0700
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.asm.amd64.test;
 
+import static org.junit.Assume.*;
+
 import java.nio.*;
 
 import org.junit.*;
@@ -35,6 +37,11 @@
 
 public class SimpleAssemblerTest extends AssemblerTest {
 
+    @Before
+    public void assumeNotSparc() {
+        assumeFalse(System.getProperty("os.arch").toLowerCase().contains("sparc"));
+    }
+
     @Test
     public void intTest() {
         CodeGenTest test = new CodeGenTest() {
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Mon Aug 25 21:15:59 2014 -0700
@@ -77,6 +77,7 @@
             final int inst = masm.getInt(pos);
             Op2s op2 = Op2s.byValue((inst&OP2_MASK) >> OP2_SHIFT);
             switch(op2) {
+                case Br:
                 case Fb:
                     return Fmt00b.read(masm, op2, pos);
                 case Sethi:
@@ -213,6 +214,10 @@
         private static final int DISP22_MASK = 0b00000000001111111111111111111111;
         // @formatter:on
 
+        public Fmt00b(boolean annul, ConditionFlag cond, Op2s op2, Label label) {
+            this(annul ? 1 : 0, cond.getValue(), op2.getValue(), 0, label);
+        }
+
         public Fmt00b(boolean annul, FCond cond, Op2s op2, Label label) {
             this(annul ? 1 : 0, cond.getValue(), op2.getValue(), 0, label);
         }
@@ -810,14 +815,19 @@
         }
 
         public void verify() {
-            assert ((rd << RD_SHIFT) & RD_MASK) == (rd << RD_SHIFT);
-            assert ((op3 << OP3_SHIFT) & OP3_MASK) == (op3 << OP3_SHIFT);
-            assert ((rs1 << RS1_SHIFT) & RS1_MASK) == (rs1 << RS1_SHIFT);
-            assert ((i << I_SHIFT) & I_MASK) == (i << I_SHIFT);
-            assert ((x << X_SHIFT) & X_MASK) == (x << X_SHIFT);
-            assert ((immAsi << IMM_ASI_SHIFT) & IMM_ASI_MASK) == (immAsi << IMM_ASI_SHIFT);
-            assert ((rs2 << RS2_SHIFT) & RS2_MASK) == (rs2 << RS2_SHIFT);
-            assert isSimm13(simm13);
+            assert ((rd << RD_SHIFT) & RD_MASK) == (rd << RD_SHIFT) : this;
+            assert ((op3 << OP3_SHIFT) & OP3_MASK) == (op3 << OP3_SHIFT) : this;
+            assert ((rs1 << RS1_SHIFT) & RS1_MASK) == (rs1 << RS1_SHIFT) : this;
+            assert ((i << I_SHIFT) & I_MASK) == (i << I_SHIFT) : this;
+            assert ((x << X_SHIFT) & X_MASK) == (x << X_SHIFT) : this;
+            assert ((immAsi << IMM_ASI_SHIFT) & IMM_ASI_MASK) == (immAsi << IMM_ASI_SHIFT) : this;
+            assert ((rs2 << RS2_SHIFT) & RS2_MASK) == (rs2 << RS2_SHIFT) : this;
+            assert isSimm13(simm13) : this;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("%s: [rd: 0x%x, op3: 0x%x, rs1: 0x%x, i: 0x%x, x: 0x%x, immAsi: 0x%x, rs2: 0x%x, simm13: 0x%x", getClass().getName(), rd, op3, rs1, i, x, immAsi, rs2, simm13);
         }
     }
 
@@ -1432,7 +1442,8 @@
         Movstouw(0x111, "movstouw"),
         Movstosw(0x113, "movstosw"),
         Movxtod(0x118, "movxtod"),
-        Movwtos(0x119, "movwtos"),
+        Movwtos(0b1_0001_1001, "movwtos"),
+        UMulxhi(0b0_0001_0110, "umulxhi"),
         // end VIS3
 
         // start CAMMELLIA
@@ -1682,6 +1693,18 @@
         public String getOperator() {
             return operator;
         }
+
+        public ConditionFlag negate() {
+            switch (this) {
+                case CarrySet:
+                    return CarryClear;
+                case CarryClear:
+                    return CarrySet;
+                default:
+                    GraalInternalError.unimplemented();
+            }
+            return null;
+        }
     }
 
     public enum RCondition {
@@ -1978,6 +2001,13 @@
         }
     }
 
+    public static class Umulxhi extends Fmt3p {
+        public Umulxhi(Register src1, Register src2, Register dst) {
+            /* VIS3 only */
+            super(Ops.ArithOp, Op3s.Impdep1, Opfs.UMulxhi, src1, src2, dst);
+        }
+    }
+
     public static class Movxtod extends Fmt3p {
         public Movxtod(Register src, Register dst) {
             /* VIS3 only */
@@ -2812,6 +2842,13 @@
         }
     }
 
+    public static class Fsmuld extends Fmt3p {
+
+        public Fsmuld(Register src1, Register src2, Register dst) {
+            super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fsmuld, src1, src2, dst);
+        }
+    }
+
     public static class Fmul8x16 extends Fmt3p {
 
         public Fmul8x16(Register src1, Register src2, Register dst) {
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Mon Aug 25 21:15:59 2014 -0700
@@ -327,7 +327,7 @@
         public void emit(SPARCMacroAssembler masm) {
             if (value == 0) {
                 new Clr(dst).emit(masm);
-            } else if (-4095 <= value && value <= 4096) {
+            } else if (isSimm13(value)) {
                 new Or(g0, value, dst).emit(masm);
             } else if (value >= 0 && ((value & 0x3FFF) == 0)) {
                 new Sethi(hi22(value), dst).emit(masm);
--- a/graal/com.oracle.graal.compiler.amd64.test/src/com/oracle/graal/compiler/amd64/test/AMD64AllocatorTest.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.compiler.amd64.test/src/com/oracle/graal/compiler/amd64/test/AMD64AllocatorTest.java	Mon Aug 25 21:15:59 2014 -0700
@@ -32,7 +32,7 @@
 
     @Before
     public void setUp() {
-        assumeTrue(isArchitecture("AMD64"));
+        assumeTrue(isArchitecture("x86_64"));
     }
 
     @Test
--- a/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/SPARCAllocatorTest.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/SPARCAllocatorTest.java	Mon Aug 25 21:15:59 2014 -0700
@@ -55,7 +55,7 @@
 
     @Test
     public void test3() {
-        test("test3snippet", 4, 0, 0);
+        test("test3snippet", 3, 1, 0);
     }
 
     public static long test3snippet(long x) {
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Mon Aug 25 21:15:59 2014 -0700
@@ -35,6 +35,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.asm.sparc.SPARCAssembler.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.calc.*;
 import com.oracle.graal.compiler.common.type.*;
@@ -232,7 +233,7 @@
                 break;
             case Float:
             case Double:
-                append(new BranchOp(cond, trueDestination, falseDestination, kind));
+                append(new BranchOp(finalCondition, trueDestination, falseDestination, kind));
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere("" + left.getKind());
@@ -241,8 +242,7 @@
 
     @Override
     public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, double overflowProbability) {
-        // append(new BranchOp(negated ? ConditionFlag.NoOverflow : ConditionFlag.Overflow, label));
-        throw GraalInternalError.unimplemented();
+        append(new BranchOp(ConditionFlag.CarrySet, overflow, noOverflow, Kind.Long));
     }
 
     @Override
@@ -308,10 +308,10 @@
         switch ((Kind) cmpKind) {
             case Short:
             case Char:
-                append(new CompareOp(ICMP, emitZeroExtend(left, 16, 32), emitZeroExtend(right, 16, 32)));
+                append(new CompareOp(ICMP, emitSignExtend(left, 16, 32), emitSignExtend(right, 16, 32)));
                 break;
             case Byte:
-                append(new CompareOp(ICMP, emitZeroExtend(left, 8, 32), emitZeroExtend(right, 8, 32)));
+                append(new CompareOp(ICMP, emitSignExtend(left, 8, 32), emitSignExtend(right, 8, 32)));
                 break;
             case Int:
                 append(new CompareOp(ICMP, left, right));
@@ -355,9 +355,7 @@
 
     @Override
     public void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget) {
-        // a temp is needed for loading long and object constants
-        boolean needsTemp = key.getKind() == Kind.Long || key.getKind() == Kind.Object;
-        append(new StrategySwitchOp(strategy, keyTargets, defaultTarget, key, needsTemp ? newVariable(key.getLIRKind()) : Value.ILLEGAL));
+        append(new StrategySwitchOp(strategy, keyTargets, defaultTarget, key, newVariable(key.getLIRKind())));
     }
 
     @Override
@@ -457,16 +455,16 @@
         Variable result = newVariable(LIRKind.derive(input));
         switch (input.getKind().getStackKind()) {
             case Long:
-                append(new Op1Stack(LNEG, result, input));
+                append(new Unary2Op(LNEG, result, load(input)));
                 break;
             case Int:
-                append(new Op1Stack(INEG, result, input));
+                append(new Unary2Op(INEG, result, load(input)));
                 break;
             case Float:
-                append(new Op1Stack(FNEG, result, input));
+                append(new Unary2Op(FNEG, result, load(input)));
                 break;
             case Double:
-                append(new Op1Stack(DNEG, result, input));
+                append(new Unary2Op(DNEG, result, load(input)));
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
@@ -479,10 +477,10 @@
         Variable result = newVariable(LIRKind.derive(input));
         switch (input.getKind().getStackKind()) {
             case Int:
-                append(new Op1Stack(INOT, result, input));
+                append(new Unary2Op(INOT, result, load(input)));
                 break;
             case Long:
-                append(new Op1Stack(LNOT, result, input));
+                append(new Unary2Op(LNOT, result, load(input)));
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
@@ -597,12 +595,33 @@
 
     @Override
     public Value emitMulHigh(Value a, Value b) {
-        throw GraalInternalError.unimplemented();
+        switch (a.getKind().getStackKind()) {
+            case Int:
+                return emitMulHigh(IMUL, a, b);
+            case Long:
+                return emitMulHigh(LMUL, a, b);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
     }
 
     @Override
     public Value emitUMulHigh(Value a, Value b) {
-        throw GraalInternalError.unimplemented();
+        switch (a.getKind().getStackKind()) {
+            case Int:
+                return emitMulHigh(IUMUL, a, b);
+            case Long:
+                return emitMulHigh(LUMUL, a, b);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    private Value emitMulHigh(SPARCArithmetic opcode, Value a, Value b) {
+        Variable result = newVariable(LIRKind.derive(a, b));
+        MulHighOp mulHigh = new MulHighOp(opcode, load(a), load(b), result, newVariable(LIRKind.derive(a, b)));
+        append(mulHigh);
+        return result;
     }
 
     @Override
@@ -665,10 +684,10 @@
         Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind().getStackKind()) {
             case Int:
-                append(new RemOp(IUREM, result, a, loadNonConst(b), state, this));
+                append(new RemOp(IUREM, result, load(a), load(b), state, this));
                 break;
             case Long:
-                append(new RemOp(LUREM, result, a, loadNonConst(b), state, this));
+                append(new RemOp(LUREM, result, load(a), loadNonConst(b), state, this));
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
@@ -680,9 +699,13 @@
     @Override
     public Value emitUDiv(Value a, Value b, LIRFrameState state) {
         SPARCArithmetic op;
+        Value actualA = a;
+        Value actualB = b;
         switch (a.getKind().getStackKind()) {
             case Int:
                 op = IUDIV;
+                actualA = emitZeroExtend(actualA, 32, 64);
+                actualB = emitZeroExtend(actualB, 32, 64);
                 break;
             case Long:
                 op = LUDIV;
@@ -690,7 +713,7 @@
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
-        return emitBinary(op, false, a, b, state);
+        return emitBinary(op, false, actualA, actualB, state);
     }
 
     @Override
@@ -912,14 +935,14 @@
             append(new BinaryRegConst(SPARCArithmetic.LAND, result, asAllocatable(inputVal), Constant.forLong(mask), null));
             return result;
         } else {
-            assert inputVal.getKind() == Kind.Int || inputVal.getKind() == Kind.Short || inputVal.getKind() == Kind.Byte : inputVal.getKind();
+            assert inputVal.getKind() == Kind.Int || inputVal.getKind() == Kind.Short || inputVal.getKind() == Kind.Byte || inputVal.getKind() == Kind.Char : inputVal.getKind();
             Variable result = newVariable(LIRKind.derive(inputVal).changeType(Kind.Int));
             long mask = IntegerStamp.defaultMask(fromBits);
-            Constant constant = Constant.forLong(mask);
-            if (canInlineConstant(constant)) {
+            Constant constant = Constant.forInt((int) mask);
+            if (fromBits == 32) {
+                append(new ShiftOp(IUSHR, result, inputVal, Constant.forInt(0)));
+            } else if (canInlineConstant(constant)) {
                 append(new BinaryRegConst(SPARCArithmetic.IAND, result, asAllocatable(inputVal), constant, null));
-            } else if (fromBits == 32) {
-                append(new ShiftOp(IUSHR, result, inputVal, Constant.forInt(0)));
             } else {
                 Variable maskVar = newVariable(LIRKind.derive(inputVal).changeType(Kind.Int));
                 emitMove(maskVar, constant);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Mon Aug 25 21:15:59 2014 -0700
@@ -26,11 +26,10 @@
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.sparc.SPARC.*;
+import static com.oracle.graal.compiler.common.UnsafeAccess.*;
 
 import java.util.*;
 
-import sun.misc.*;
-
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
@@ -61,8 +60,6 @@
  */
 public class SPARCHotSpotBackend extends HotSpotHostBackend {
 
-    private static final Unsafe unsafe = Unsafe.getUnsafe();
-
     public SPARCHotSpotBackend(HotSpotGraalRuntime runtime, HotSpotProviders providers) {
         super(runtime, providers);
     }
@@ -139,12 +136,18 @@
         @Override
         public void enter(CompilationResultBuilder crb) {
             final int frameSize = crb.frameMap.totalFrameSize();
-
+            final int stackpoinerChange = -frameSize;
             SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm;
             if (!isStub && pagesToBang > 0) {
                 emitStackOverflowCheck(crb, pagesToBang, false);
             }
-            new Save(sp, -frameSize, sp).emit(masm);
+
+            if (SPARCAssembler.isSimm13(stackpoinerChange)) {
+                new Save(sp, stackpoinerChange, sp).emit(masm);
+            } else {
+                new Setx(stackpoinerChange, g3).emit(masm);
+                new Save(sp, g3, sp).emit(masm);
+            }
 
             if (ZapStackOnMethodEntry.getValue()) {
                 final int slotSize = 8;
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java	Mon Aug 25 21:15:59 2014 -0700
@@ -29,12 +29,8 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.CC;
-import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Jmpl;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Lduw;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Movcc;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp;
+import com.oracle.graal.asm.sparc.SPARCAssembler.*;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
@@ -74,5 +70,6 @@
         new Movcc(ConditionFlag.NotZero, CC.Icc, l7, sp).emit(masm);
 
         new Jmpl(asRegister(handlerInCallerPc), 0, g0).emit(masm);
+        new Nop().emit(masm);
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Mon Aug 25 21:15:59 2014 -0700
@@ -206,12 +206,15 @@
     }
 
     public Value emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) {
+        Variable newValueTemp = newVariable(newValue.getLIRKind());
+        emitMove(newValueTemp, newValue);
+
         LIRKind kind = newValue.getLIRKind();
         assert kind.equals(expectedValue.getLIRKind());
         Kind memKind = (Kind) kind.getPlatformKind();
         SPARCAddressValue addressValue = asAddressValue(address);
-        append(new CompareAndSwapOp(asAllocatable(addressValue), asAllocatable(expectedValue), asAllocatable(newValue)));
-        return emitConditionalMove(memKind, expectedValue, newValue, Condition.EQ, true, trueValue, falseValue);
+        append(new CompareAndSwapOp(asAllocatable(addressValue), asAllocatable(expectedValue), asAllocatable(newValueTemp)));
+        return emitConditionalMove(memKind, expectedValue, newValueTemp, Condition.EQ, true, trueValue, falseValue);
     }
 
     public StackSlot getDeoptimizationRescueSlot() {
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java	Mon Aug 25 21:15:59 2014 -0700
@@ -36,6 +36,9 @@
 @Opcode("LEAVE_CURRENT_STACK_FRAME")
 final class SPARCHotSpotLeaveCurrentStackFrameOp extends SPARCLIRInstruction {
 
+    public SPARCHotSpotLeaveCurrentStackFrameOp() {
+    }
+
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         // Save O registers over restore.
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveUnpackFramesStackFrameOp.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveUnpackFramesStackFrameOp.java	Mon Aug 25 21:15:59 2014 -0700
@@ -63,5 +63,7 @@
         new Stx(g0, new SPARCAddress(thread, threadLastJavaSpOffset)).emit(masm);
         new Stx(g0, new SPARCAddress(thread, threadLastJavaPcOffset)).emit(masm);
         new Stw(g0, new SPARCAddress(thread, threadJavaFrameAnchorFlagsOffset)).emit(masm);
+
+        new Movdtox(f31, i0).emit(masm);
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Mon Aug 25 21:15:59 2014 -0700
@@ -30,6 +30,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.lir.*;
@@ -85,8 +86,14 @@
     private final Register[] cpuCalleeParameterRegisters = {i0, i1, i2, i3, i4, i5};
 
     private final Register[] fpuParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7};
-
-    private final Register[] callerSaveRegisters = {g1, g3, g4, g5, o0, o1, o2, o3, o4, o5, o7};
+    // @formatter:off
+    private final Register[] callerSaveRegisters =
+                   {g1, g3, g4, g5, o0, o1, o2, o3, o4, o5, o7,
+                    f0,  f1,  f2,  f3,  f4,  f5,  f6,  f7,
+                    f8,  f9,  f10, f11, f12, f13, f14, f15,
+                    f16, f17, f18, f19, f20, f21, f22, f23,
+                    f24, f25, f26, f27, f28, f29, f30, f31};
+    // @formatter:on
 
     /**
      * Registers saved by the callee. This lists all L and I registers which are saved in the
@@ -238,10 +245,7 @@
             if (locations[i] == null) {
                 // Stack slot is always aligned to its size in bytes but minimum wordsize
                 int typeSize = SPARC.spillSlotSize(target, kind);
-                int modulus = currentStackOffset % typeSize;
-                if (modulus != 0) {
-                    currentStackOffset += typeSize - modulus;
-                }
+                currentStackOffset = NumUtil.roundUp(currentStackOffset, typeSize);
                 locations[i] = StackSlot.get(target.getLIRKind(kind.getStackKind()), currentStackOffset, !type.out);
                 currentStackOffset += typeSize;
             }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java	Mon Aug 25 21:15:59 2014 -0700
@@ -28,6 +28,7 @@
 import static com.oracle.graal.sparc.SPARC.*;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.asm.sparc.SPARCAssembler.*;
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov;
 import com.oracle.graal.hotspot.stubs.*;
@@ -61,7 +62,7 @@
 
         // Get return address (is in o7 after leave).
         Register returnAddress = asRegister(cc.getArgument(1));
-        new Mov(o7, returnAddress).emit(masm);
+        new Add(o7, Return.PC_RETURN_OFFSET, returnAddress).emit(masm);
         Register scratch = g5;
         SPARCCall.indirectJmp(crb, masm, scratch, linkage);
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java	Mon Aug 25 21:15:59 2014 -0700
@@ -223,25 +223,48 @@
         int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask();
         int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask();
 
+        Unsigned vectorSize = Word.unsigned(VECTOR_SIZE);
         Unsigned srcOffset = Word.unsigned(srcPos).shiftLeft(log2ElementSize).add(headerSize);
         Unsigned destOffset = Word.unsigned(destPos).shiftLeft(log2ElementSize).add(headerSize);
         Unsigned destStart = destOffset;
-        Unsigned sizeInBytes = Word.unsigned(length).shiftLeft(log2ElementSize);
         Unsigned destEnd = destOffset.add(Word.unsigned(length).shiftLeft(log2ElementSize));
 
-        Unsigned nonVectorBytes = sizeInBytes.unsignedRemainder(Word.unsigned(VECTOR_SIZE));
+        Unsigned destVectorEnd = null;
+        Unsigned nonVectorBytes = null;
+        Unsigned sizeInBytes = Word.unsigned(length).shiftLeft(log2ElementSize);
+        if (supportsUnalignedMemoryAccess) {
+            nonVectorBytes = sizeInBytes.unsignedRemainder(vectorSize);
+            destVectorEnd = destEnd;
+        } else {
+            boolean inPhase = srcOffset.and((int) VECTOR_SIZE - 1).equal(destOffset.and((int) VECTOR_SIZE - 1));
+            boolean hasAtLeastOneVector = sizeInBytes.aboveOrEqual(vectorSize);
+            // We must have at least one full vector, otherwise we must copy each byte separately
+            if (hasAtLeastOneVector && inPhase) { // If in phase, we can vectorize
+                nonVectorBytes = vectorSize.subtract(destStart.unsignedRemainder(vectorSize));
+            } else { // fallback is byte-wise
+                nonVectorBytes = sizeInBytes;
+            }
+            destVectorEnd = destEnd.subtract(destEnd.unsignedRemainder(vectorSize));
+        }
+
         Unsigned destNonVectorEnd = destStart.add(nonVectorBytes);
-
         while (destOffset.belowThan(destNonVectorEnd)) {
             ObjectAccess.writeByte(dest, destOffset, ObjectAccess.readByte(src, srcOffset, ANY_LOCATION), ANY_LOCATION);
             destOffset = destOffset.add(1);
             srcOffset = srcOffset.add(1);
         }
-        while (destOffset.belowThan(destEnd)) {
+        // Unsigned destVectorEnd = destEnd.subtract(destEnd.unsignedRemainder(8));
+        while (destOffset.belowThan(destVectorEnd)) {
             ObjectAccess.writeWord(dest, destOffset, ObjectAccess.readWord(src, srcOffset, ANY_LOCATION), ANY_LOCATION);
             destOffset = destOffset.add(wordSize());
             srcOffset = srcOffset.add(wordSize());
         }
+        // Do the last bytes each when it is required to have absolute alignment.
+        while (!supportsUnalignedMemoryAccess && destOffset.belowThan(destEnd)) {
+            ObjectAccess.writeByte(dest, destOffset, ObjectAccess.readByte(src, srcOffset, ANY_LOCATION), ANY_LOCATION);
+            destOffset = destOffset.add(1);
+            srcOffset = srcOffset.add(1);
+        }
     }
 
     public static class Templates extends AbstractTemplates {
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/jdk/IntegerBits.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/jdk/IntegerBits.java	Mon Aug 25 21:15:59 2014 -0700
@@ -103,4 +103,60 @@
     public void run10() {
         runTest("test4", 0xffffffff);
     }
+
+    @Test
+    public void run11() {
+        runTest("test2", 0xFFFFFFFF);
+    }
+
+    @Test
+    public void run12() {
+        runTest("test2", 0x7FFFFFFF);
+    }
+
+    @Test
+    public void run17() {
+        runTest("test2", 0x80000000);
+    }
+
+    @Test
+    public void run18() {
+        runTest("test2", 0x40000000);
+    }
+
+    @Test
+    public void run13() {
+        runTest("test3", 0x7FFFFFFF);
+    }
+
+    @Test
+    public void run14() {
+        runTest("test3", 0xFFFFFFFF);
+    }
+
+    @Test
+    public void run15() {
+        runTest("test3", 0x80000000);
+    }
+
+    @Test
+    public void run16() {
+        runTest("test3", 0x40000000);
+    }
+
+    @Test
+    public void run19() {
+        runTest("test4", 0x80000000);
+    }
+
+    @Test
+    public void run20() {
+        runTest("test4", 0x40000000);
+    }
+
+    @Test
+    public void run21() {
+        runTest("test4", 0x00000001);
+    }
+
 }
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/micro/BigMixedParams04.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/micro/BigMixedParams04.java	Mon Aug 25 21:15:59 2014 -0700
@@ -53,6 +53,212 @@
         return 42;
     }
 
+    /**
+     * Test SPARC mixed params with double/single float register overlapping
+     *
+     * @param f1
+     * @param d2
+     * @param f3
+     * @return Must always return the argument d2
+     */
+    @SuppressWarnings("all")
+    public static double test2(int i1, float f1, double d2, float f3,
+    // @formatter:off
+                    double ad1 ,
+                    double ad2 ,
+                    double ad3 ,
+                    double ad4 ,
+                    double ad5 ,
+                    double ad6 ,
+                    double ad7 ,
+                    double ad8 ,
+                    double ad9 ,
+                    double ad10,
+                    double ad11,
+                    double ad12,
+                    double ad13,
+                    double ad14,
+                    double ad15,
+                    double ad16,
+                    float  af1 ,
+                    float  af2 ,
+                    float  af3 ,
+                    float  af4 ,
+                    float  af5 ,
+                    float  af6 ,
+                    float  af7 ,
+                    float  af8 ,
+                    float  af9 ,
+                    float  af10,
+                    float  af11,
+                    float  af12,
+                    float  af13,
+                    float  af14,
+                    float  af15,
+                    float  af16
+    // @formatter:on
+    ) {
+
+        // now do something with the locals to make sure the locals don't get optimized away.
+        for (int i = 0; i < i1; i++) {
+            af1 += f1;
+            af2 += f1;
+            af3 += f1;
+            af4 += f1;
+            af5 += f1;
+            af6 += f1;
+            af7 += f1;
+            af8 += f1;
+            af9 += f1;
+            af10 += f1;
+            af11 += f1;
+            af12 += f1;
+            af13 += f1;
+            af14 += f1;
+            af15 += f1;
+            af16 += f1;
+            ad1 += f1;
+            ad2 += f1;
+            ad3 += f1;
+            ad4 += f1;
+            ad5 += f1;
+            ad6 += f1;
+            ad7 += f1;
+            ad8 += f1;
+            ad9 += f1;
+            ad10 += f1;
+            ad11 += f1;
+            ad12 += f1;
+            ad13 += f1;
+            ad14 += f1;
+            ad15 += f1;
+            ad16 += f1;
+        }
+        // @formatter:off
+        boolean orderFloat =
+                        af1  < af2  &&
+                        af2  < af3  &&
+                        af3  < af4  &&
+                        af4  < af5  &&
+                        af5  < af6  &&
+                        af6  < af7  &&
+                        af7  < af8  &&
+                        af8  < af9  &&
+                        af9  < af10 &&
+                        af10 < af11 &&
+                        af11 < af12 &&
+                        af12 < af13 &&
+                        af13 < af14 &&
+                        af14 < af15 &&
+                        af15 < af16;
+        boolean orderDouble =
+                        ad1  < ad2  &&
+                        ad2  < ad3  &&
+                        ad3  < ad4  &&
+                        ad4  < ad5  &&
+                        ad5  < ad6  &&
+                        ad6  < ad7  &&
+                        ad7  < ad8  &&
+                        ad8  < ad9  &&
+                        ad9  < ad10 &&
+                        ad10 < ad11 &&
+                        ad11 < ad12 &&
+                        ad12 < ad13 &&
+                        ad13 < ad14 &&
+                        ad14 < ad15 &&
+                        ad15 < ad16;
+        // @formatter:on
+        if (orderDouble && orderFloat) {
+            return f1 + d2 + f3; // this should not be destroyed
+        }
+        Assert.fail();
+        return 0.0;
+    }
+
+    /**
+     * Test SPARC mixed params with double/single float register overlapping
+     *
+     * @param f1
+     * @param d2
+     * @param f3
+     * @return Must always return the argument d2
+     */
+    @SuppressWarnings("all")
+    public static double test3(boolean f, int idx,
+    // @formatter:off
+                    double ad1 ,
+                    double ad2 ,
+                    double ad3 ,
+                    double ad4 ,
+                    double ad5 ,
+                    double ad6 ,
+                    double ad7 ,
+                    double ad8 ,
+                    double ad9 ,
+                    double ad10,
+                    double ad11,
+                    double ad12,
+                    double ad13,
+                    double ad14,
+                    double ad15,
+                    double ad16,
+                    float  af1 ,
+                    float  af2 ,
+                    float  af3 ,
+                    float  af4 ,
+                    float  af5 ,
+                    float  af6 ,
+                    float  af7 ,
+                    float  af8 ,
+                    float  af9 ,
+                    float  af10,
+                    float  af11,
+                    float  af12,
+                    float  af13,
+                    float  af14,
+                    float  af15,
+                    float  af16
+    ) {
+        switch(f ? idx + 16 : idx) {
+            case 1 : return ad1 ;
+            case 2 : return ad2 ;
+            case 3 : return ad3 ;
+            case 4 : return ad4 ;
+            case 5 : return ad5 ;
+            case 6 : return ad6 ;
+            case 7 : return ad7 ;
+            case 8 : return ad8 ;
+            case 9 : return ad9 ;
+            case 10: return ad10;
+            case 11: return ad11;
+            case 12: return ad12;
+            case 13: return ad13;
+            case 14: return ad14;
+            case 15: return ad15;
+            case 16: return ad16;
+            case 1  + 16: return af1 ;
+            case 2  + 16: return af2 ;
+            case 3  + 16: return af3 ;
+            case 4  + 16: return af4 ;
+            case 5  + 16: return af5 ;
+            case 6  + 16: return af6 ;
+            case 7  + 16: return af7 ;
+            case 8  + 16: return af8 ;
+            case 9  + 16: return af9 ;
+            case 10 + 16: return af10;
+            case 11 + 16: return af11;
+            case 12 + 16: return af12;
+            case 13 + 16: return af13;
+            case 14 + 16: return af14;
+            case 15 + 16: return af15;
+            case 16 + 16: return af16;
+        }
+        Assert.fail(); // should not reach here
+        return 0;
+
+    }
+    // @formatter:on
+
     @Test
     public void run0() throws Throwable {
         runTest("test", 0, -1, -1, -1, -1, 1d, 2d, true, false, (byte) -128, (short) -0x7FFF, (char) 0xFFFF, -0x7FFFFFF);
@@ -82,4 +288,86 @@
     public void run5() throws Throwable {
         runTest("test", 5, -1, -1, -1, -1, 1d, 2d, true, false, (byte) -128, (short) -0x7FFF, (char) 0xFFFF, -0x7FFFFFF);
     }
+
+    @Test
+    public void run6() throws Throwable {
+        // @formatter:off
+        runTest("test2", 20, 1.0f, -3.2912948246387967943231233d, 3.0f,
+                        1d,
+                        2d,
+                        3d,
+                        4d,
+                        5d,
+                        6d,
+                        7d,
+                        8d,
+                        9d,
+                        10d,
+                        11d,
+                        12d,
+                        13d,
+                        14d,
+                        15d,
+                        16d,
+                        1f,
+                        2f,
+                        3f,
+                        4f,
+                        5f,
+                        6f,
+                        7f,
+                        8f,
+                        9f,
+                        10f,
+                        11f,
+                        12f,
+                        13f,
+                        14f,
+                        15f,
+                        16f
+                        );
+        // @formatter:on
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        // @formatter:off
+        for(int i =0; i<32*2; i++)
+        runTest("test3", i%2==0, i/2,
+                        1d,
+                        2d,
+                        3d,
+                        4d,
+                        5d,
+                        6d,
+                        7d,
+                        8d,
+                        9d,
+                        10d,
+                        11d,
+                        12d,
+                        13d,
+                        14d,
+                        15d,
+                        16d,
+                        1f,
+                        2f,
+                        3f,
+                        4f,
+                        5f,
+                        6f,
+                        7f,
+                        8f,
+                        9f,
+                        10f,
+                        11f,
+                        12f,
+                        13f,
+                        14f,
+                        15f,
+                        16f
+                        );
+        // @formatter:on
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/SignExtendShort.java	Mon Aug 25 21:15:59 2014 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.jtt.optimize;
+
+import org.junit.*;
+
+import com.oracle.graal.jtt.*;
+
+/*
+ */
+public class SignExtendShort extends JTTTest {
+
+    public static int val;
+
+    public static boolean test(short[] b) {
+        val = b[2];
+        int x = 0;
+        return val >= x;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        runTest("test", new short[]{0, 0, 0});
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        runTest("test", new short[]{0, 0, 1});
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        runTest("test", new short[]{0, 0, -1});
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        runTest("test", new short[]{0, 0, Short.MAX_VALUE});
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        runTest("test", new short[]{0, 0, Short.MIN_VALUE});
+    }
+}
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/Switch02.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/Switch02.java	Mon Aug 25 21:15:59 2014 -0700
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.jtt.optimize;
 
+import java.util.*;
+
 import org.junit.*;
 
 import com.oracle.graal.jtt.*;
@@ -30,6 +32,9 @@
  * Tests optimization of switches.
  */
 public class Switch02 extends JTTTest {
+    private static char staticCharVal = 0;
+    private static short staticShortVal = 0;
+    private static byte staticByteVal = 0;
 
     public static int test(int arg) {
         switch (arg) {
@@ -40,6 +45,168 @@
         }
     }
 
+    public static int test2char(char arg) {
+        int result = 392123;
+        Object x = null;
+        char val = staticCharVal != 0 ? staticCharVal : arg;
+        switch (val) {
+            case (char) 0xFFFF:
+                result = 23212 / val;
+                break;
+            case (char) 0xFFFF - 3:
+                result = 932991439 / val;
+                break;
+            case (char) 0xFFFF - 6:
+                result = 47329561 / val;
+                break;
+            case (char) 0xFFFF - 9:
+                result = 1950976984 / val;
+                break;
+            case (char) 0xFFFF - 10:
+                result = 97105581 / val;
+                switch (result) {
+                    case 1:
+                        result = 321;
+                        break;
+                    default:
+                        result = 2391;
+                        break;
+                }
+                break;
+            case (char) 0xFFFF - 12:
+                result = 99757362 / val;
+                break;
+            case (char) 0xFFFF - 15:
+                result = 912573 / val;
+                x = new LinkedList<>();
+                break;
+            case (char) 0xFFFF - 18:
+                x = new HashSet<>();
+                result = 876765 / val;
+                break;
+            case (char) 0xFFFF - 19:
+                result = 75442917 / val;
+                break;
+            case (char) 0xFFFF - 21:
+                result = 858112498 / val;
+                x = new Hashtable<>();
+                break;
+            default:
+                result = 34324341 / val;
+        }
+        result = result + (x == null ? 0 : x.hashCode());
+        return result;
+    }
+
+    public static int test2short(short arg) {
+        int result = 392123;
+        Object x = null;
+        short val = staticShortVal != 0 ? staticShortVal : arg;
+        switch (val) {
+            case (short) -0x7FFF:
+                result = 23212 / val;
+                break;
+            case (short) -0x7FFF + 3:
+                result = 932991439 / val;
+                break;
+            case (short) -0x7FFF + 6:
+                result = 47329561 / val;
+                break;
+            case (short) -0x7FFF + 9:
+                result = 1950976984 / val;
+                break;
+            case (short) -0x7FFF + 10:
+                result = 97105581 / val;
+                switch (result) {
+                    case 1:
+                        result = 321;
+                        break;
+                    default:
+                        result = 2391;
+                        break;
+                }
+                break;
+            case (short) -0x7FFF + 12:
+                result = 99757362 / val;
+                break;
+            case (short) -0x7FFF + 15:
+                result = 912573 / val;
+                x = new LinkedList<>();
+                break;
+            case (short) -0x7FFF + 18:
+                x = new HashSet<>();
+                result = 876765 / val;
+                break;
+            case (short) -0x7FFF + 19:
+                result = 75442917 / val;
+                break;
+            case (short) -0x7FFF + 21:
+                result = 858112498 / val;
+                x = new Hashtable<>();
+                break;
+            default:
+                result = 34324341 / val;
+        }
+        result = result + (x == null ? 0 : x.hashCode());
+        return result;
+    }
+
+    public static int test2byte(byte arg) {
+        int result = 392123;
+        Object x = null;
+        byte val = staticByteVal != 0 ? staticByteVal : arg;
+        switch (val) {
+            case (byte) -0x7F:
+                result = 23212 / val;
+                break;
+            case (byte) -0x7F + 3:
+                result = 932991439 / val;
+                break;
+            case (byte) -0x7F + 6:
+                result = 47329561 / val;
+                break;
+            case (byte) -0x7F + 9:
+                result = 1950976984 / val;
+                break;
+            case (byte) -0x7F + 10:
+                result = 97105581 / val;
+                switch (result) {
+                    case 1:
+                        result = 321;
+                        break;
+                    default:
+                        result = 2391;
+                        break;
+                }
+                break;
+            case (byte) -0x7F + 12:
+                result = 99757362 / val;
+                break;
+            case (byte) -0x7F + 15:
+                result = 912573 / val;
+                x = new LinkedList<>();
+                break;
+            case (byte) -0x7F + 18:
+                x = new HashSet<>();
+                result = 876765 / val;
+                break;
+            case (byte) -0x7F + 19:
+                result = 75442917 / val;
+                break;
+            case (byte) -0x7F + 20:
+                result = 856261268 / val;
+                break;
+            case (byte) -0x7F + 21:
+                result = 858112498 / val;
+                x = new Hashtable<>();
+                break;
+            default:
+                result = 34324341 / val;
+        }
+        result = result + (x == null ? 0 : x.hashCode());
+        return result;
+    }
+
     @Test
     public void run0() throws Throwable {
         runTest("test", 0);
@@ -50,4 +217,63 @@
         runTest("test", 1);
     }
 
+    @Test
+    public void run2() throws Throwable {
+        runTest("test2char", (char) (0x0));
+        runTest("test2char", (char) (0xFFFF));
+        runTest("test2char", (char) (0xFFFF - 21)); // miss
+        runTest("test2char", (char) (0xFFFF - 22)); // hit
+        runTest("test2char", (char) (0xFFFF - 23)); // miss (out of bound)
+
+        staticCharVal = (char) 0xFFFF;
+        runTest("test2char", (char) 0);
+        staticCharVal = (char) (0xFFFF - 21);
+        runTest("test2char", (char) 0xFFFF);
+        staticCharVal = (char) (0xFFFF - 22);
+        runTest("test2char", (char) 0xFFFF);
+        staticCharVal = (char) (0xFFFF - 23);
+        runTest("test2char", (char) 0xFFFF);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        runTest("test2short", (short) 0x0);
+        runTest("test2short", (short) -0x7FFF);
+        runTest("test2short", (short) (-0x7FFF + 21)); // Miss
+        runTest("test2short", (short) (-0x7FFF + 22)); // hit
+        runTest("test2short", (short) (-0x7FFF + 23)); // miss (out of bound)
+        runTest("test2short", (short) 0x7FFF);         // miss (out of bound)
+
+        staticShortVal = (short) -0x7FFF;
+        runTest("test2short", (short) 0);
+        staticShortVal = (short) (-0x7FFF + 21);
+        runTest("test2short", (short) 0);
+        staticShortVal = (short) (-0x7FFF + 22);
+        runTest("test2short", (short) 0);
+        staticShortVal = (short) (-0x7FFF + 23);
+        runTest("test2short", (short) 0);
+        staticShortVal = (short) 0x7FFF;
+        runTest("test2short", (short) 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        runTest("test2byte", (byte) 0);
+        runTest("test2byte", (byte) -0x7F);
+        runTest("test2byte", (byte) (-0x7F + 21)); // Miss
+        runTest("test2byte", (byte) (-0x7F + 22)); // hit
+        runTest("test2byte", (byte) (-0x7F + 23)); // miss (out of bound)
+        runTest("test2byte", (byte) 0x7F);         // miss (out of bound)
+
+        staticByteVal = (byte) -0x7F;
+        runTest("test2short", (short) 0);
+        staticByteVal = (byte) (-0x7F + 21);
+        runTest("test2short", (short) 0);
+        staticByteVal = (byte) (-0x7F + 22);
+        runTest("test2short", (short) 0);
+        staticByteVal = (byte) (-0x7F + 23);
+        runTest("test2short", (short) 0);
+        staticByteVal = (byte) 0x7F;
+        runTest("test2short", (short) 0);
+    }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Mon Aug 25 21:15:59 2014 -0700
@@ -27,6 +27,7 @@
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
 import com.oracle.graal.compiler.common.*;
@@ -37,8 +38,8 @@
 
 public enum SPARCArithmetic {
     // @formatter:off
-    IADD, ISUB, IMUL, IDIV, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR,
-    LADD, LSUB, LMUL, LDIV, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR,
+    IADD, ISUB, IMUL, IUMUL, IDIV, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR,
+    LADD, LSUB, LMUL, LUMUL, LDIV, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR,
     FADD, FSUB, FMUL, FDIV, FREM, FAND, FOR, FXOR,
     DADD, DSUB, DMUL, DDIV, DREM, DAND, DOR, DXOR,
     INEG, LNEG, FNEG, DNEG, INOT, LNOT,
@@ -161,6 +162,10 @@
         @State protected LIRFrameState state;
         protected Constant y;
 
+        public BinaryRegConst(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x, Constant y) {
+            this(opcode, result, x, y, null);
+        }
+
         public BinaryRegConst(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x, Constant y, LIRFrameState state) {
             this.opcode = opcode;
             this.result = result;
@@ -248,7 +253,7 @@
 
         @Opcode private final SPARCArithmetic opcode;
         @Def({REG}) protected Value result;
-        @Use({REG, CONST}) protected Value x;
+        @Alive({REG, CONST}) protected Value x;
         @Alive({REG, CONST}) protected Value y;
         @Temp({REG}) protected Value scratch1;
         @Temp({REG}) protected Value scratch2;
@@ -282,9 +287,16 @@
             switch (opcode) {
                 case ISUB:
                     assert isSimm13(crb.asIntConst(src1));
-                    new Sub(SPARC.g0, asIntReg(src2), asIntReg(src2)).emit(masm);
-                    new Add(asIntReg(src2), crb.asIntConst(src1), asIntReg(dst)).emit(masm);
+                    new Sub(SPARC.g0, asIntReg(src2), asIntReg(dst)).emit(masm);
+                    new Add(asIntReg(dst), crb.asIntConst(src1), asIntReg(dst)).emit(masm);
                     break;
+                case LSUB: {
+                    long c = crb.asLongConst(src1);
+                    assert isSimm13(c);
+                    new Sub(SPARC.g0, asLongReg(src2), asLongReg(dst)).emit(masm);
+                    new Add(asLongReg(dst), (int) c, asLongReg(dst)).emit(masm);
+                    break;
+                }
                 case IAND:
                     throw GraalInternalError.unimplemented();
                 case IDIV:
@@ -292,13 +304,14 @@
                     exceptionOffset = masm.position();
                     new Sdivx(asIntReg(dst), asIntReg(src2), asIntReg(dst)).emit(masm);
                     break;
-                case LDIV:
+                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:
@@ -410,6 +423,7 @@
                     break;
                 case DAND:
                     SPARCAddress addr = (SPARCAddress) crb.recordDataReferenceInCode(asConstant(src2), 4);
+                    addr = SPARCMove.guaranueeLoadable(addr, masm);
                     new Lddf(addr, asDoubleReg(dst)).emit(masm);
                     new Fandd(asDoubleReg(src1), asDoubleReg(dst), asDoubleReg(dst)).emit(masm);
                     break;
@@ -440,7 +454,6 @@
                     new Sdivx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
                     break;
                 case IUDIV:
-                    new Srl(asIntReg(src1), 0, asIntReg(src1)).emit(masm);
                     exceptionOffset = masm.position();
                     new Udivx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
                     break;
@@ -506,7 +519,11 @@
                     new Fsubs(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm);
                     break;
                 case FMUL:
-                    new Fmuls(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm);
+                    if (dst.getPlatformKind() == Kind.Double) {
+                        new Fsmuld(asFloatReg(src1), asFloatReg(src2), asDoubleReg(dst)).emit(masm);
+                    } else if (dst.getPlatformKind() == Kind.Float) {
+                        new Fmuls(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm);
+                    }
                     break;
                 case FDIV:
                     new Fdivs(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm);
@@ -569,22 +586,25 @@
         } else if (isConstant(src2)) {
             switch (opcode) {
                 case IREM:
+                    assert !src1.equals(scratch1);
+                    assert !src1.equals(scratch2);
+                    assert !src2.equals(scratch1);
+                    // But src2 can be scratch2
                     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 IUREM:
-                    new Sra(asIntReg(src1), 0, asIntReg(scratch1)).emit(masm);
-                    exceptionOffset = masm.position();
-                    new Udivx(asIntReg(scratch1), crb.asIntConst(src2), asIntReg(scratch1)).emit(masm);
-                    new Mulx(asIntReg(scratch1), crb.asIntConst(src2), asIntReg(scratch1)).emit(masm);
-                    new Sub(asIntReg(src1), asIntReg(scratch1), asIntReg(dst)).emit(masm);
+                    GraalInternalError.unimplemented();
                     break;
                 case LREM:
                     assert isSimm13(crb.asIntConst(src2));
+                    assert !src1.equals(scratch1);
+                    assert !src1.equals(scratch2);
+                    assert !src2.equals(scratch1);
+                    // But src2 can be scratch2
                     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);
@@ -592,6 +612,10 @@
                     break;
                 case LUREM:
                     assert isSimm13(crb.asIntConst(src2));
+                    assert !src1.equals(scratch1);
+                    assert !src1.equals(scratch2);
+                    assert !src2.equals(scratch1);
+                    // But src2 can be scratch2
                     exceptionOffset = masm.position();
                     new Udivx(asLongReg(src1), crb.asIntConst(src2), asLongReg(scratch1)).emit(masm);
                     new Mulx(asLongReg(scratch1), crb.asIntConst(src2), asLongReg(scratch2)).emit(masm);
@@ -608,6 +632,9 @@
                         new Setx(crb.asLongConst(src1), asLongReg(scratch2), false).emit(masm);
                         srcLeft = scratch2;
                     }
+                    assert !asLongReg(srcLeft).equals(asLongReg(scratch1));
+                    assert !asLongReg(src2).equals(asLongReg(scratch1));
+                    // But src2 can be scratch2
                     exceptionOffset = masm.position();
                     new Sdivx(asLongReg(srcLeft), asLongReg(src2), asLongReg(scratch1)).emit(masm);
                     new Mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch1)).emit(masm);
@@ -618,6 +645,8 @@
                         new Setx(crb.asLongConst(src1), asLongReg(scratch2), false).emit(masm);
                         srcLeft = scratch2;
                     }
+                    assert !asLongReg(srcLeft).equals(asLongReg(scratch1));
+                    assert !asLongReg(src2).equals(asLongReg(scratch1));
                     exceptionOffset = masm.position();
                     new Udivx(asLongReg(srcLeft), asLongReg(src2), asLongReg(scratch1)).emit(masm);
                     new Mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch1)).emit(masm);
@@ -628,17 +657,22 @@
                         new Setx(crb.asIntConst(src1), asIntReg(scratch2), false).emit(masm);
                         srcLeft = scratch2;
                     }
+                    assert !asIntReg(srcLeft).equals(asIntReg(scratch1));
+                    assert !asIntReg(src2).equals(asIntReg(scratch1));
                     exceptionOffset = masm.position();
                     new Sdivx(asIntReg(srcLeft), asIntReg(src2), asIntReg(scratch1)).emit(masm);
                     new Mulx(asIntReg(scratch1), asIntReg(src2), asIntReg(scratch1)).emit(masm);
                     new Sub(asIntReg(srcLeft), asIntReg(scratch1), asIntReg(dst)).emit(masm);
                     break;
                 case IUREM:
-                    new Sra(asIntReg(src1), 0, asIntReg(scratch1)).emit(masm);
+                    assert !asIntReg(dst).equals(asIntReg(scratch1));
+                    assert !asIntReg(dst).equals(asIntReg(scratch2));
+                    new Srl(asIntReg(src1), 0, asIntReg(scratch1)).emit(masm);
+                    new Srl(asIntReg(src2), 0, asIntReg(dst)).emit(masm);
                     exceptionOffset = masm.position();
-                    new Udivx(asIntReg(scratch1), asIntReg(src2), asIntReg(scratch1)).emit(masm);
-                    new Mulx(asIntReg(scratch1), asIntReg(src2), asIntReg(scratch1)).emit(masm);
-                    new Sub(asIntReg(src1), asIntReg(scratch1), asIntReg(dst)).emit(masm);
+                    new Udivx(asIntReg(scratch1), asIntReg(dst), asIntReg(scratch2)).emit(masm);
+                    new Mulx(asIntReg(scratch2), asIntReg(dst), asIntReg(dst)).emit(masm);
+                    new Sub(asIntReg(scratch1), asIntReg(dst), asIntReg(dst)).emit(masm);
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
@@ -653,6 +687,7 @@
 
     public static void emit(CompilationResultBuilder crb, SPARCAssembler masm, SPARCArithmetic opcode, Value dst, Value src, LIRFrameState info) {
         int exceptionOffset = -1;
+        Label notOrdered = new Label();
         if (isRegister(src)) {
             switch (opcode) {
                 case INEG:
@@ -716,18 +751,20 @@
                     new Fstod(asFloatReg(src), asDoubleReg(dst)).emit(masm);
                     break;
                 case F2L:
-                    new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(dst), asFloatReg(dst)).emit(masm);
-                    new Fbe(false, 4 * 4).emit(masm);
+                    new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(src), asFloatReg(src)).emit(masm);
+                    new Fbo(false, notOrdered).emit(masm);
                     new Fstox(asFloatReg(src), asFloatReg(dst)).emit(masm);
                     new Fitos(asFloatReg(dst), asFloatReg(dst)).emit(masm);
                     new Fsubs(asFloatReg(dst), asFloatReg(dst), asFloatReg(dst)).emit(masm);
+                    masm.bind(notOrdered);
                     break;
                 case F2I:
-                    new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(dst), asFloatReg(dst)).emit(masm);
-                    new Fbo(false, 4 * 4).emit(masm);
+                    new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(src), asFloatReg(src)).emit(masm);
+                    new Fbo(false, notOrdered).emit(masm);
                     new Fstoi(asFloatReg(src), asFloatReg(dst)).emit(masm);
                     new Fitos(asFloatReg(dst), asFloatReg(dst)).emit(masm);
                     new Fsubs(asFloatReg(dst), asFloatReg(dst), asFloatReg(dst)).emit(masm);
+                    masm.bind(notOrdered);
                     break;
                 case MOV_D2L:
                     new Movdtox(asDoubleReg(src), asLongReg(dst)).emit(masm);
@@ -742,18 +779,20 @@
                     new Movwtos(asIntReg(src), asFloatReg(dst)).emit(masm);
                     break;
                 case D2L:
-                    new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(dst), asDoubleReg(dst)).emit(masm);
-                    new Fbo(false, 4 * 4).emit(masm);
+                    new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(src), asDoubleReg(src)).emit(masm);
+                    new Fbo(false, notOrdered).emit(masm);
                     new Fdtox(asDoubleReg(src), asDoubleReg(dst)).emit(masm);
                     new Fxtod(asDoubleReg(dst), asDoubleReg(dst)).emit(masm);
                     new Fsubd(asDoubleReg(dst), asDoubleReg(dst), asDoubleReg(dst)).emit(masm);
+                    masm.bind(notOrdered);
                     break;
                 case D2I:
-                    new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(dst), asDoubleReg(dst)).emit(masm);
-                    new Fbo(false, 4 * 4).emit(masm);
+                    new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(src), asDoubleReg(src)).emit(masm);
+                    new Fbo(false, notOrdered).emit(masm);
                     new Fdtoi(asDoubleReg(src), asDoubleReg(dst)).emit(masm);
                     new Fitod(asDoubleReg(dst), asDoubleReg(dst)).emit(masm);
                     new Fsubd(asDoubleReg(dst), asDoubleReg(dst), asDoubleReg(dst)).emit(masm);
+                    masm.bind(notOrdered);
                     break;
                 case FNEG:
                     new Fnegs(asFloatReg(src), asFloatReg(dst)).emit(masm);
@@ -803,10 +842,14 @@
             case IUSHR:
             case IUDIV:
             case IUREM:
-                rk = result.getKind();
+                rk = result.getKind().getStackKind();
                 xsk = x.getKind().getStackKind();
                 ysk = y.getKind().getStackKind();
-                assert rk == Kind.Int && xsk == Kind.Int && ysk == Kind.Int;
+                boolean valid = false;
+                for (Kind k : new Kind[]{Kind.Int, Kind.Short, Kind.Byte, Kind.Char}) {
+                    valid |= rk == k && xsk == k && ysk == k;
+                }
+                assert valid : "rk: " + rk + " xsk: " + xsk + " ysk: " + ysk;
                 break;
             case LADD:
             case LSUB:
@@ -839,7 +882,7 @@
                 rk = result.getKind();
                 xk = x.getKind();
                 yk = y.getKind();
-                assert rk == Kind.Float && xk == Kind.Float && yk == Kind.Float;
+                assert (rk == Kind.Float || rk == Kind.Double) && xk == Kind.Float && yk == Kind.Float;
                 break;
             case DAND:
             case DADD:
@@ -856,4 +899,56 @@
                 throw GraalInternalError.shouldNotReachHere("missing: " + opcode);
         }
     }
+
+    public static class MulHighOp extends SPARCLIRInstruction {
+
+        @Opcode private final SPARCArithmetic opcode;
+        @Def({REG}) public AllocatableValue result;
+        @Alive({REG}) public AllocatableValue x;
+        @Alive({REG}) public AllocatableValue y;
+        @Temp({REG}) public AllocatableValue scratch;
+
+        public MulHighOp(SPARCArithmetic opcode, AllocatableValue x, AllocatableValue y, AllocatableValue result, AllocatableValue scratch) {
+            this.opcode = opcode;
+            this.x = x;
+            this.y = y;
+            this.scratch = scratch;
+            this.result = result;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            assert isRegister(x) && isRegister(y) && isRegister(result) && isRegister(scratch);
+            switch (opcode) {
+                case IMUL:
+                    new Mulx(asIntReg(x), asIntReg(y), asIntReg(result)).emit(masm);
+                    new Srax(asIntReg(result), 32, asIntReg(result)).emit(masm);
+                    break;
+                case IUMUL:
+                    assert !asIntReg(scratch).equals(asIntReg(result));
+                    new Srl(asIntReg(x), 0, asIntReg(scratch)).emit(masm);
+                    new Srl(asIntReg(y), 0, asIntReg(result)).emit(masm);
+                    new Mulx(asIntReg(result), asIntReg(scratch), asIntReg(result)).emit(masm);
+                    new Srlx(asIntReg(result), 32, asIntReg(result)).emit(masm);
+                    break;
+                case LMUL:
+                    assert !asLongReg(scratch).equals(asLongReg(result));
+                    new Umulxhi(asLongReg(x), asLongReg(y), asLongReg(result)).emit(masm);
+
+                    new Srlx(asLongReg(x), 63, asLongReg(scratch)).emit(masm);
+                    new Mulx(asLongReg(scratch), asLongReg(y), asLongReg(scratch)).emit(masm);
+                    new Sub(asLongReg(result), asLongReg(scratch), asLongReg(result)).emit(masm);
+
+                    new Srlx(asLongReg(y), 63, asLongReg(scratch)).emit(masm);
+                    new Mulx(asLongReg(scratch), asLongReg(x), asLongReg(scratch)).emit(masm);
+                    new Sub(asLongReg(result), asLongReg(scratch), asLongReg(result)).emit(masm);
+                    break;
+                case LUMUL:
+                    new Umulxhi(asLongReg(x), asLongReg(y), asLongReg(result)).emit(masm);
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+    }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Mon Aug 25 21:15:59 2014 -0700
@@ -96,9 +96,10 @@
                     Kind ikind = input.getKind();
                     assert ikind == Kind.Int;
                     Register tmp = asRegister(scratch);
+                    assert !tmp.equals(dst);
                     new Srl(src, 1, tmp).emit(masm);
                     new Srl(src, 0, dst).emit(masm);
-                    new Or(src, tmp, dst).emit(masm);
+                    new Or(dst, tmp, dst).emit(masm);
                     new Srl(dst, 2, tmp).emit(masm);
                     new Or(dst, tmp, dst).emit(masm);
                     new Srl(dst, 4, tmp).emit(masm);
@@ -115,6 +116,7 @@
                     Kind lkind = input.getKind();
                     assert lkind == Kind.Long;
                     Register tmp = asRegister(scratch);
+                    assert !tmp.equals(dst);
                     new Srlx(src, 1, tmp).emit(masm);
                     new Or(src, tmp, dst).emit(masm);
                     new Srlx(dst, 2, tmp).emit(masm);
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Mon Aug 25 21:15:59 2014 -0700
@@ -25,12 +25,12 @@
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 import static com.oracle.graal.sparc.SPARC.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.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.compiler.common.calc.*;
@@ -62,30 +62,44 @@
     }
 
     public static class BranchOp extends SPARCLIRInstruction implements StandardOp.BranchOp {
-
+        // TODO: Conditioncode/flag handling needs to be improved;
         protected final Condition condition;
+        protected final ConditionFlag conditionFlag;
         protected final LabelRef trueDestination;
         protected final LabelRef falseDestination;
         protected final Kind kind;
 
+        public BranchOp(ConditionFlag condition, LabelRef trueDestination, LabelRef falseDestination, Kind kind) {
+            this.conditionFlag = condition;
+            this.trueDestination = trueDestination;
+            this.falseDestination = falseDestination;
+            this.kind = kind;
+            this.condition = null;
+        }
+
         public BranchOp(Condition condition, LabelRef trueDestination, LabelRef falseDestination, Kind kind) {
             this.condition = condition;
             this.trueDestination = trueDestination;
             this.falseDestination = falseDestination;
             this.kind = kind;
+            this.conditionFlag = null;
         }
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
+            assert condition == null && conditionFlag != null || condition != null && conditionFlag == null;
             Label actualTarget;
             Condition actualCondition;
+            ConditionFlag actualConditionFlag;
             boolean needJump;
             if (crb.isSuccessorEdge(trueDestination)) {
-                actualCondition = condition.negate();
+                actualCondition = condition != null ? condition.negate() : null;
+                actualConditionFlag = conditionFlag != null ? conditionFlag.negate() : null;
                 actualTarget = falseDestination.label();
                 needJump = false;
             } else {
                 actualCondition = condition;
+                actualConditionFlag = conditionFlag;
                 actualTarget = trueDestination.label();
                 needJump = !crb.isSuccessorEdge(falseDestination);
             }
@@ -94,7 +108,13 @@
                 emitFloatCompare(masm, actualTarget, actualCondition);
             } else {
                 CC cc = kind == Kind.Int ? CC.Icc : CC.Xcc;
-                emitCompare(masm, actualTarget, actualCondition, cc);
+                if (actualCondition != null) {
+                    emitCompare(masm, actualTarget, actualCondition, cc);
+                } else if (actualConditionFlag != null) {
+                    emitCompare(masm, actualTarget, actualConditionFlag);
+                } else {
+                    GraalInternalError.shouldNotReachHere();
+                }
                 new Nop().emit(masm);  // delay slot
             }
             if (needJump) {
@@ -104,7 +124,7 @@
     }
 
     private static void emitFloatCompare(SPARCMacroAssembler masm, Label target, Condition actualCondition) {
-        switch (actualCondition.mirror()) {
+        switch (actualCondition) {
             case EQ:
                 new Fbe(false, target).emit(masm);
                 break;
@@ -134,6 +154,10 @@
         new Nop().emit(masm);
     }
 
+    private static void emitCompare(SPARCMacroAssembler masm, Label target, ConditionFlag actualCondition) {
+        new Fmt00b(false, actualCondition, Op2s.Br, target).emit(masm);
+    }
+
     private static void emitCompare(SPARCMacroAssembler masm, Label target, Condition actualCondition, CC cc) {
         switch (actualCondition) {
             case EQ:
@@ -176,7 +200,7 @@
         private final LabelRef[] keyTargets;
         private LabelRef defaultTarget;
         @Alive({REG}) protected Value key;
-        @Temp({REG, ILLEGAL}) protected Value scratch;
+        @Temp({REG}) protected Value scratch;
         private final SwitchStrategy strategy;
 
         public StrategySwitchOp(SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget, Value key, Value scratch) {
@@ -188,7 +212,6 @@
             this.scratch = scratch;
             assert keyConstants.length == keyTargets.length;
             assert keyConstants.length == strategy.keyProbabilities.length;
-            assert (scratch.getKind() == Kind.Illegal) == (key.getKind() == Kind.Int);
         }
 
         @Override
@@ -204,8 +227,13 @@
                                 crb.recordInlineDataInCode(keyConstants[index]);
                             }
                             long lc = keyConstants[index].asLong();
-                            assert NumUtil.isInt(lc);
-                            new Cmp(keyRegister, (int) lc).emit(masm);
+                            if (SPARCAssembler.isSimm13(lc)) {
+                                assert NumUtil.isInt(lc);
+                                new Cmp(keyRegister, (int) lc).emit(masm);
+                            } else {
+                                new Setx(lc, asIntReg(scratch)).emit(masm);
+                                new Cmp(keyRegister, asIntReg(scratch)).emit(masm);
+                            }
                             emitCompare(masm, target, condition, CC.Icc);
                             break;
                         case Long: {
@@ -253,12 +281,20 @@
 
             // Compare index against jump table bounds
             int highKey = lowKey + targets.length - 1;
-            if (lowKey != 0) {
-                // subtract the low value from the switch value
-                new Sub(value, lowKey, value).emit(masm);
-                new Cmp(value, highKey - lowKey).emit(masm);
+
+            // subtract the low value from the switch value
+            if (isSimm13(lowKey)) {
+                new Sub(value, lowKey, scratchReg).emit(masm);
             } else {
-                new Cmp(value, highKey).emit(masm);
+                new Setx(lowKey, g3).emit(masm);
+                new Sub(value, g3, scratchReg).emit(masm);
+            }
+            int upperLimit = highKey - lowKey;
+            if (isSimm13(upperLimit)) {
+                new Cmp(scratchReg, upperLimit).emit(masm);
+            } else {
+                new Setx(upperLimit, g3).emit(masm);
+                new Cmp(scratchReg, upperLimit).emit(masm);
             }
 
             // Jump to default target if index is not within the jump table
@@ -268,19 +304,20 @@
             }
 
             // Load jump table entry into scratch and jump to it
-            new Sll(value, 3, value).emit(masm); // Multiply by 8
-            new Rdpc(scratchReg).emit(masm);
+            new Sll(scratchReg, 3, scratchReg).emit(masm); // Multiply by 8
+            // Zero the left bits sll with shcnt>0 does not mask upper 32 bits
+            new Srl(scratchReg, 0, scratchReg).emit(masm);
+            new Rdpc(g3).emit(masm);
 
             // The jump table follows four instructions after rdpc
             new Add(scratchReg, 4 * 4, scratchReg).emit(masm);
-            new Jmpl(value, scratchReg, g0).emit(masm);
-            new Sra(value, 3, value).emit(masm); // delay slot, correct the value (division by 8)
+            new Jmpl(g3, scratchReg, g0).emit(masm);
+            new Nop().emit(masm);
+            // new Sra(value, 3, value).emit(masm); // delay slot, correct the value (division by 8)
 
             // Emit jump table entries
             for (LabelRef target : targets) {
-                Label label = target.label();
-                label.addPatchAt(masm.position());
-                new Bpa(0).emit(masm);
+                new Bpa(target.label()).emit(masm);
                 new Nop().emit(masm); // delay slot
             }
         }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Mon Aug 25 21:15:59 2014 -0700
@@ -25,16 +25,18 @@
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 import static com.oracle.graal.sparc.SPARC.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.*;
 
 import com.oracle.graal.api.code.CompilationResult.RawData;
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.*;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.*;
+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.asm.*;
 
 public class SPARCMove {
@@ -135,7 +137,7 @@
 
         @Override
         public void emitMemAccess(SPARCMacroAssembler masm) {
-            final SPARCAddress addr = address.toAddress();
+            final SPARCAddress addr = guaranueeLoadable(address.toAddress(), masm);
             final Register dst = asRegister(result);
             switch (kind) {
                 case Boolean:
@@ -172,21 +174,17 @@
     public static class LoadAddressOp extends SPARCLIRInstruction {
 
         @Def({REG}) protected AllocatableValue result;
-        @Use({COMPOSITE, UNINITIALIZED}) protected SPARCAddressValue address;
+        @Use({COMPOSITE, UNINITIALIZED}) protected SPARCAddressValue addressValue;
 
         public LoadAddressOp(AllocatableValue result, SPARCAddressValue address) {
             this.result = result;
-            this.address = address;
+            this.addressValue = address;
         }
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            SPARCAddress addr = address.toAddress();
-            if (addr.hasIndex()) {
-                new Add(addr.getBase(), addr.getIndex(), asLongReg(result)).emit(masm);
-            } else {
-                new Add(addr.getBase(), addr.getDisplacement(), asLongReg(result)).emit(masm);
-            }
+            SPARCAddress address = addressValue.toAddress();
+            loadEffectiveAddress(address, asLongReg(result), masm);
         }
     }
 
@@ -283,7 +281,21 @@
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
             SPARCAddress address = (SPARCAddress) crb.asAddress(slot);
-            new Add(address.getBase(), address.getDisplacement(), asLongReg(result)).emit(masm);
+            loadEffectiveAddress(address, asLongReg(result), masm);
+        }
+    }
+
+    private static void loadEffectiveAddress(SPARCAddress address, Register result, SPARCMacroAssembler masm) {
+        if (address.getIndex().equals(Register.None)) {
+            if (isSimm13(address.getDisplacement())) {
+                new Add(address.getBase(), address.getDisplacement(), result).emit(masm);
+            } else {
+                assert result.encoding() != address.getBase().encoding();
+                new Setx(address.getDisplacement(), result).emit(masm);
+                new Add(address.getBase(), result, result).emit(masm);
+            }
+        } else {
+            new Add(address.getBase(), address.getIndex(), result).emit(masm);
         }
     }
 
@@ -299,7 +311,7 @@
         @Override
         public void emitMemAccess(SPARCMacroAssembler masm) {
             assert isRegister(input);
-            SPARCAddress addr = address.toAddress();
+            SPARCAddress addr = guaranueeLoadable(address.toAddress(), masm);
             switch (kind) {
                 case Boolean:
                 case Byte:
@@ -344,21 +356,22 @@
 
         @Override
         public void emitMemAccess(SPARCMacroAssembler masm) {
+            SPARCAddress addr = guaranueeLoadable(address.toAddress(), masm);
             switch (kind) {
                 case Boolean:
                 case Byte:
-                    new Stb(g0, address.toAddress()).emit(masm);
+                    new Stb(g0, addr).emit(masm);
                     break;
                 case Short:
                 case Char:
-                    new Sth(g0, address.toAddress()).emit(masm);
+                    new Sth(g0, addr).emit(masm);
                     break;
                 case Int:
-                    new Stw(g0, address.toAddress()).emit(masm);
+                    new Stw(g0, addr).emit(masm);
                     break;
                 case Long:
                 case Object:
-                    new Stx(g0, address.toAddress()).emit(masm);
+                    new Stx(g0, addr).emit(masm);
                     break;
                 case Float:
                 case Double:
@@ -451,8 +464,29 @@
         }
     }
 
+    /**
+     * Guarantees that the given SPARCAddress given before is loadable by subsequent call. If the
+     * displacement exceeds the imm13 value, the value is put into a scratch register o7, which must
+     * be used as soon as possible.
+     *
+     * @param addr Address to modify
+     * @param masm assembler to output the prior stx command
+     * @return a loadable SPARCAddress
+     */
+    public static SPARCAddress guaranueeLoadable(SPARCAddress addr, SPARCMacroAssembler masm) {
+        boolean displacementOutOfBound = addr.getIndex().equals(Register.None) && !SPARCAssembler.isSimm13(addr.getDisplacement());
+        if (displacementOutOfBound) {
+            Register scratch = g3;
+            new Setx(addr.getDisplacement(), scratch, false).emit(masm);
+            return new SPARCAddress(addr.getBase(), scratch);
+        } else {
+            return addr;
+        }
+    }
+
     private static void reg2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input) {
         SPARCAddress dst = (SPARCAddress) crb.asAddress(result);
+        dst = guaranueeLoadable(dst, masm);
         Register src = asRegister(input);
         switch (input.getKind()) {
             case Byte:
@@ -483,6 +517,7 @@
 
     private static void stack2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input) {
         SPARCAddress src = (SPARCAddress) crb.asAddress(input);
+        src = guaranueeLoadable(src, masm);
         Register dst = asRegister(result);
         switch (input.getKind()) {
             case Boolean:
@@ -517,28 +552,10 @@
         Register scratch = g5;
         switch (input.getKind().getStackKind()) {
             case Int:
-                if (crb.codeCache.needsDataPatch(input)) {
-                    crb.recordInlineDataInCode(input);
-                    new Setuw(input.asInt(), asRegister(result)).emit(masm);
-                } else {
-                    if (input.isDefaultForKind()) {
-                        new Clr(asRegister(result)).emit(masm);
-                    } else {
-                        new Setuw(input.asInt(), asRegister(result)).emit(masm);
-                    }
-                }
+                new Setx(input.asLong(), asIntReg(result)).emit(masm);
                 break;
             case Long:
-                if (crb.codeCache.needsDataPatch(input)) {
-                    crb.recordInlineDataInCode(input);
-                    new Setx(input.asLong(), asRegister(result), true).emit(masm);
-                } else {
-                    if (input.isDefaultForKind()) {
-                        new Clr(asRegister(result)).emit(masm);
-                    } else {
-                        new Setx(input.asLong(), asRegister(result)).emit(masm);
-                    }
-                }
+                new Setx(input.asLong(), asLongReg(result)).emit(masm);
                 break;
             case Float:
                 // TODO: Handle it the same way, as in the double case with Movwtos
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java	Mon Aug 25 21:15:59 2014 -0700
@@ -27,10 +27,12 @@
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Movxtod;
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.SaveRegistersOp;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.sparc.*;
 
 /**
  * Saves registers to stack slots.
@@ -78,6 +80,7 @@
                 saveRegister(crb, masm, slots[i], savedRegisters[i]);
             }
         }
+        new Movxtod(SPARC.i0, SPARC.f31).emit(masm);
     }
 
     public StackSlot[] getSlots() {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Mon Aug 25 21:15:59 2014 -0700
@@ -204,7 +204,8 @@
         // @formatter:off
         assert (!slot.getRawAddFrameSize() && slot.getRawOffset() <  outgoingSize) ||
                ( slot.getRawAddFrameSize() && slot.getRawOffset() <  0 && -slot.getRawOffset() <= spillSize) ||
-               ( slot.getRawAddFrameSize() && slot.getRawOffset() >= 0);
+               ( slot.getRawAddFrameSize() && slot.getRawOffset() >= 0) :
+                   String.format("RawAddFrameSize: %b RawOffset: 0x%x spillSize: 0x%x outgoingSize: 0x%x", slot.getRawAddFrameSize(), slot.getRawOffset(), spillSize, outgoingSize);
         // @formatter:on
         if (slot.isInCallerFrame()) {
             accessesCallerFrame = true;
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MonitorTest.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MonitorTest.java	Mon Aug 25 21:15:59 2014 -0700
@@ -108,7 +108,7 @@
     public void test7() {
         char[] src = "1234567890".toCharArray();
         char[] dst = new char[src.length];
-        int n = Runtime.getRuntime().availableProcessors();
+        int n = Math.min(32, Runtime.getRuntime().availableProcessors());
         testN(n, "copyArr", src, dst, 100);
     }
 
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ExactMathTest.java	Mon Aug 25 23:22:05 2014 +0200
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ExactMathTest.java	Mon Aug 25 21:15:59 2014 -0700
@@ -72,7 +72,11 @@
     public void testMulHighUnsigned() {
         test("mulHighUnsigned", 7, 15);
         test("mulHighUnsigned", Integer.MAX_VALUE, 15);
+        test("mulHighUnsigned", 15, Integer.MAX_VALUE);
+        test("mulHighUnsigned", Integer.MAX_VALUE, Integer.MAX_VALUE);
+        test("mulHighUnsigned", 15, Integer.MIN_VALUE);
         test("mulHighUnsigned", Integer.MIN_VALUE, 15);
+        test("mulHighUnsigned", Integer.MIN_VALUE, Integer.MIN_VALUE);
     }
 
     @Test
@@ -98,7 +102,11 @@
     public void testLongMulHigh() {
         test("longMulHigh", 7L, 15L);
         test("longMulHigh", Long.MAX_VALUE, 15L);
+        test("longMulHigh", 15L, Long.MAX_VALUE);
+        test("longMulHigh", Long.MAX_VALUE, Long.MAX_VALUE);
         test("longMulHigh", Long.MIN_VALUE, 15L);
+        test("longMulHigh", 15L, Long.MIN_VALUE);
+        test("longMulHigh", Long.MIN_VALUE, Long.MIN_VALUE);
     }
 
     @Test
--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Mon Aug 25 23:22:05 2014 +0200
+++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Mon Aug 25 21:15:59 2014 -0700
@@ -3433,6 +3433,9 @@
   if (UseStackBanging) {
     pad += StackShadowPages*16 + 32;
   }
+#ifdef GRAAL
+  pad += 32; // Increase the buffer size when compiling for GRAAL
+#endif
 #ifdef _LP64
   CodeBuffer buffer("deopt_blob", 2100+pad, 512);
 #else
@@ -3567,6 +3570,33 @@
   // Restore G2_thread
   __ get_thread();
 
+#ifdef GRAAL
+  // load throwing pc from JavaThread and patch it as the return address
+  // of the current frame. Then clear the field in JavaThread
+  __ block_comment("load throwing pc and patch return");
+  Address exception_pc(G2_thread, JavaThread::exception_pc_offset());
+  Label has_no_pc;
+  // TODO: Remove this weird check if we should patch the return pc
+  // This is because when graal decides to deoptimize and the ExceptionHandlerStub.java
+  // jumps back to this code and the I7 register contains the pc pointing to the begin
+  // of this code. If this is the case (PC within a certain range) then we need to patch
+  // the return pc.
+  // THIS NEEDS REWORK! (sa)
+  __ rdpc(L0);
+  __ sub(L0, I7, L0);
+  __ cmp(L0, 0xFFF);
+  __ br(Assembler::greater, false, Assembler::pt, has_no_pc);
+  __ delayed() -> nop();
+  __ cmp(L0, -0xFFF);
+  __ br(Assembler::less, false, Assembler::pt, has_no_pc);
+  __ delayed() -> nop();
+  __ ld_ptr(exception_pc, I7);
+  __ sub(I7, 8, I7);
+  __ st_ptr(G0, exception_pc);
+  __ bind(has_no_pc);
+  __ block_comment("/load throwing pc and patch return");
+#endif // GAAL
+
 #ifdef ASSERT
   {
     // verify that there is really an exception oop in exception_oop
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Mon Aug 25 23:22:05 2014 +0200
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Mon Aug 25 21:15:59 2014 -0700
@@ -199,6 +199,22 @@
 address InterpreterGenerator::generate_deopt_entry_for(TosState state, int step) {
   address entry = __ pc();
   __ get_constant_pool_cache(LcpoolCache); // load LcpoolCache
+#ifdef GRAAL
+  // Check if we need to take lock at entry of synchronized method.
+  {
+    Label L;
+
+    //__ cmp(, 0);
+    Address pending_monitor_enter_addr(G2_thread, Thread::pending_monitorenter_offset());
+    __ ldbool(pending_monitor_enter_addr, Gtemp);  // Load if pending monitor enter
+    __ cmp_and_br_short(Gtemp, G0, Assembler::equal, Assembler::pn, L);
+    // Clear flag.
+    __ stbool(G0, pending_monitor_enter_addr);
+    // Take lock.
+    lock_method();
+    __ bind(L);
+  }
+#endif
   { Label L;
     Address exception_addr(G2_thread, Thread::pending_exception_offset());
     __ ld_ptr(exception_addr, Gtemp);  // Load pending exception.
@@ -1689,8 +1705,13 @@
         // make sure I5_savedSP and the entry frames notion of saved SP
         // agree.  This assertion duplicate a check in entry frame code
         // but catches the failure earlier.
-        assert(*caller->register_addr(Lscratch) == *interpreter_frame->register_addr(I5_savedSP),
+        /*
+         * Sanzinger: This does not make sense to me, since when we call stub_call -> i2c, the i2c may change the
+         * sp, which then is not in sync with Lscratch anymore.
+         */
+        /**assert(*caller->register_addr(Lscratch) == *interpreter_frame->register_addr(I5_savedSP),
                "would change callers SP");
+               */
       }
       if (caller->is_entry_frame()) {
         tty->print("entry ");
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Mon Aug 25 23:22:05 2014 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Mon Aug 25 21:15:59 2014 -0700
@@ -231,6 +231,8 @@
       Location::Type locationType;
       if (type == T_INT) {
         locationType = reference ? Location::narrowoop : Location::int_in_long;
+      } else if(type == T_SHORT || type == T_CHAR || type == T_BYTE || type == T_BOOLEAN) {
+        locationType = Location::int_in_long;
       } else if (type == T_FLOAT) {
         locationType = Location::int_in_long;
       } else if (type == T_LONG) {
@@ -264,7 +266,7 @@
 #ifdef TARGET_ARCH_sparc
       ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, as_FloatRegister(encoding)->as_VMReg()));
       if (type == T_DOUBLE) {
-        second = new ConstantIntValue(0);
+        second = value;
       }
       return value;
 #else
@@ -278,6 +280,8 @@
       locationType = reference ? Location::oop : Location::lng;
     } else if (type == T_INT) {
       locationType = reference ? Location::narrowoop : Location::normal;
+    } else if(type == T_SHORT || type == T_CHAR || type == T_BYTE || type == T_BOOLEAN) {
+      locationType = Location::normal;
     } else if (type == T_FLOAT) {
       assert(!reference, "unexpected type in stack slot");
       locationType = Location::normal;
@@ -289,6 +293,11 @@
       locationType = Location::oop;
     }
     jint offset = StackSlot::offset(value);
+#ifdef TARGET_ARCH_sparc
+    if(offset >= 0) {
+      offset += 128;
+    }
+#endif
     if (StackSlot::addFrameSize(value)) {
       offset += total_frame_size;
     }