changeset 16932:4d77f938aa02

[SPARC] Exclude AMD64 tests from SPARC testrun, always use tmp register when using StrategySwitch, using registerSaver in EnterUnpackStackFrame, LeaveCurrentStackframe, adding guarantee to load offsets when doing load reg+imm13 when the imm value does not fit in 13 bit, assertions for scratch register usage (tmp/def)
author Stefan Anzinger <stefan.anzinger@gmail.com>
date Tue, 19 Aug 2014 09:21:29 -0700
parents 71ec66af2e12
children f011bf910f34
files graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java graal/com.oracle.graal.compiler.amd64.test/src/com/oracle/graal/compiler/amd64/test/AMD64AllocatorTest.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/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.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java
diffstat 13 files changed, 135 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java	Tue Aug 12 08:58:38 2014 -0700
+++ b/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java	Tue Aug 19 09:21:29 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.compiler.amd64.test/src/com/oracle/graal/compiler/amd64/test/AMD64AllocatorTest.java	Tue Aug 12 08:58:38 2014 -0700
+++ b/graal/com.oracle.graal.compiler.amd64.test/src/com/oracle/graal/compiler/amd64/test/AMD64AllocatorTest.java	Tue Aug 19 09:21:29 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/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue Aug 12 08:58:38 2014 -0700
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue Aug 19 09:21:29 2014 -0700
@@ -357,9 +357,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
@@ -938,7 +936,7 @@
             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.forInt((int) mask);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEnterUnpackFramesStackFrameOp.java	Tue Aug 12 08:58:38 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEnterUnpackFramesStackFrameOp.java	Tue Aug 19 09:21:29 2014 -0700
@@ -30,9 +30,11 @@
 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.hotspot.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.sparc.*;
+import com.oracle.graal.lir.StandardOp.*;
 import com.oracle.graal.lir.asm.*;
 
 /**
@@ -48,14 +50,17 @@
     @Alive(REG) AllocatableValue framePc;
     @Alive(REG) AllocatableValue senderSp;
     @Temp(REG) AllocatableValue scratch;
+    private SaveRegistersOp saveRegisterOp;
 
-    SPARCHotSpotEnterUnpackFramesStackFrameOp(Register thread, int threadLastJavaSpOffset, int threadLastJavaPcOffset, AllocatableValue framePc, AllocatableValue senderSp, AllocatableValue scratch) {
+    SPARCHotSpotEnterUnpackFramesStackFrameOp(Register thread, int threadLastJavaSpOffset, int threadLastJavaPcOffset, AllocatableValue framePc, AllocatableValue senderSp, AllocatableValue scratch,
+                    SaveRegistersOp saveRegisterOp) {
         this.thread = thread;
         this.threadLastJavaSpOffset = threadLastJavaSpOffset;
         this.threadLastJavaPcOffset = threadLastJavaPcOffset;
         this.framePc = framePc;
         this.senderSp = senderSp;
         this.scratch = scratch;
+        this.saveRegisterOp = saveRegisterOp;
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Tue Aug 12 08:58:38 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Tue Aug 19 09:21:29 2014 -0700
@@ -268,7 +268,7 @@
     }
 
     public void emitLeaveCurrentStackFrame(SaveRegistersOp saveRegisterOp) {
-        append(new SPARCHotSpotLeaveCurrentStackFrameOp());
+        append(new SPARCHotSpotLeaveCurrentStackFrameOp(saveRegisterOp));
     }
 
     public void emitLeaveDeoptimizedStackFrame(Value frameSize, Value initialInfo) {
@@ -280,12 +280,13 @@
         Variable framePcVariable = load(framePc);
         Variable senderSpVariable = load(senderSp);
         Variable scratchVariable = newVariable(LIRKind.value(getHostWordKind()));
-        append(new SPARCHotSpotEnterUnpackFramesStackFrameOp(thread, config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), framePcVariable, senderSpVariable, scratchVariable));
+        append(new SPARCHotSpotEnterUnpackFramesStackFrameOp(thread, config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), framePcVariable, senderSpVariable, scratchVariable,
+                        saveRegisterOp));
     }
 
     public void emitLeaveUnpackFramesStackFrame(SaveRegistersOp saveRegisterOp) {
         Register thread = getProviders().getRegisters().getThreadRegister();
-        append(new SPARCHotSpotLeaveUnpackFramesStackFrameOp(thread, config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadJavaFrameAnchorFlagsOffset()));
+        append(new SPARCHotSpotLeaveUnpackFramesStackFrameOp(thread, config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadJavaFrameAnchorFlagsOffset(), saveRegisterOp));
     }
 
     public void emitPushInterpreterFrame(Value frameSize, Value framePc, Value senderSp, Value initialInfo) {
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java	Tue Aug 12 08:58:38 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java	Tue Aug 19 09:21:29 2014 -0700
@@ -24,11 +24,16 @@
 
 import static com.oracle.graal.sparc.SPARC.*;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Lddf;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov;
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.StandardOp.SaveRegistersOp;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
+import com.oracle.graal.sparc.*;
 
 /**
  * Pops the current frame off the stack.
@@ -36,6 +41,12 @@
 @Opcode("LEAVE_CURRENT_STACK_FRAME")
 final class SPARCHotSpotLeaveCurrentStackFrameOp extends SPARCLIRInstruction {
 
+    private final SaveRegistersOp saveRegisterOp;
+
+    public SPARCHotSpotLeaveCurrentStackFrameOp(SaveRegistersOp saveRegisterOp) {
+        this.saveRegisterOp = saveRegisterOp;
+    }
+
     @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	Tue Aug 12 08:58:38 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveUnpackFramesStackFrameOp.java	Tue Aug 19 09:21:29 2014 -0700
@@ -24,13 +24,18 @@
 
 import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
 import static com.oracle.graal.sparc.SPARC.*;
+import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.sparc.*;
+import com.oracle.graal.lir.StandardOp.*;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.sparc.*;
 
 /**
  * Emits code that leaves a stack frame which is tailored to call the C++ method
@@ -44,11 +49,14 @@
     private final int threadLastJavaPcOffset;
     private final int threadJavaFrameAnchorFlagsOffset;
 
-    SPARCHotSpotLeaveUnpackFramesStackFrameOp(Register thread, int threadLastJavaSpOffset, int threadLastJavaPcOffset, int threadJavaFrameAnchorFlagsOffset) {
+    private final SaveRegistersOp saveRegisterOp;
+
+    SPARCHotSpotLeaveUnpackFramesStackFrameOp(Register thread, int threadLastJavaSpOffset, int threadLastJavaPcOffset, int threadJavaFrameAnchorFlagsOffset, SaveRegistersOp saveRegisterOp) {
         this.thread = thread;
         this.threadLastJavaSpOffset = threadLastJavaSpOffset;
         this.threadLastJavaPcOffset = threadLastJavaPcOffset;
         this.threadJavaFrameAnchorFlagsOffset = threadJavaFrameAnchorFlagsOffset;
+        this.saveRegisterOp = saveRegisterOp;
     }
 
     @Override
@@ -63,5 +71,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	Tue Aug 12 08:58:38 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Tue Aug 19 09:21:29 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.*;
@@ -244,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.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Tue Aug 12 08:58:38 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Tue Aug 19 09:21:29 2014 -0700
@@ -32,7 +32,6 @@
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.sparc.*;
@@ -254,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;
@@ -424,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;
@@ -582,6 +582,10 @@
         } 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));
                     exceptionOffset = masm.position();
                     new Sdivx(asIntReg(src1), crb.asIntConst(src2), asIntReg(scratch1)).emit(masm);
@@ -593,6 +597,10 @@
                     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);
@@ -600,6 +608,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);
@@ -616,6 +628,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);
@@ -626,6 +641,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);
@@ -636,12 +653,16 @@
                         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:
+                    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();
@@ -817,7 +838,7 @@
             case IUSHR:
             case IUDIV:
             case IUREM:
-                rk = result.getKind();
+                rk = result.getKind().getStackKind();
                 xsk = x.getKind().getStackKind();
                 ysk = y.getKind().getStackKind();
                 boolean valid = false;
@@ -900,12 +921,14 @@
                     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);
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Tue Aug 12 08:58:38 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Tue Aug 19 09:21:29 2014 -0700
@@ -96,6 +96,7 @@
                     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);
@@ -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	Tue Aug 12 08:58:38 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Tue Aug 19 09:21:29 2014 -0700
@@ -200,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) {
@@ -212,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
@@ -228,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: {
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Tue Aug 12 08:58:38 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Tue Aug 19 09:21:29 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,20 @@
         @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() == Register.None) {
+            if (isSimm13(address.getDisplacement())) {
+                new Add(address.getBase(), address.getDisplacement(), result).emit(masm);
+            } else {
+                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 +310,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 +355,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 +463,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() == 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 +516,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:
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java	Tue Aug 12 08:58:38 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java	Tue Aug 19 09:21:29 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() {