changeset 16662:e7b7a5be4d21

Merge
author Stefan Anzinger <stefan.anzinger@gmail.com>
date Wed, 30 Jul 2014 10:39:39 -0700
parents f1fba319d4e3 (diff) faaea970b951 (current diff)
children 4ccd6b6b6780
files graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectVirtualCallOp.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InfopointOp.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalJavaAccess.hpp
diffstat 27 files changed, 544 insertions(+), 158 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Wed Jul 30 10:39:39 2014 -0700
@@ -63,8 +63,8 @@
         protected static final int OP2_SHIFT = 22;
 
         // @formatter:off
-        protected static final int OP_MASK  = 0b11000000000000000000000000000000;
-        protected static final int OP2_MASK = 0b00000001110000000000000000000000;
+        protected static final int OP_MASK  = 0b1100_0000_0000_0000_0000_0000_0000_0000;
+        protected static final int OP2_MASK = 0b0000_0001_1100_0000_0000_0000_0000_0000;
         // @formatter:off
 
         private int op2;
@@ -1264,31 +1264,31 @@
         Prefetch(0b101101, "prefetch"),
         Prefetcha(0b111101, "prefetcha"),
 
-        Lduw(0b00000, "lduw"),
-        Ldub(0b00001, "ldub"),
-        Lduh(0b00010, "lduh"),
-        Stw(0b000100, "stw"),
-        Stb(0b000101, "stb"),
-        Sth(0b000110, "sth"),
-        Ldsw(0b001000, "ldsw"),
-        Ldsb(0b001001, "ldsb"),
-        Ldsh(0b001010, "ldsh"),
-        Ldx(0b001011, "ldx"),
-        Stx(0b001110, "stx"),
-
-        Ldf(0b100000, "ldf"),
-        Ldfsr(0x21, "ldfsr"),
-        Ldaf(0x22, "ldaf"),
-        Lddf(0b100011, "lddf"),
-        Stf(0b100100, "stf"),
-        Stfsr(0x25, "stfsr"),
-        Staf(0x26, "staf"),
-        Stdf(0b100111, "stdf"),
-
-        Fcmp(0b110101, "fcmp"),
-
-        Ldxa (0b01_1011, "ldxa"),
-        Lduwa(0b01_0000, "lduwa");
+        Lduw  (0b00_0000, "lduw"),
+        Ldub  (0b00_0001, "ldub"),
+        Lduh  (0b00_0010, "lduh"),
+        Stw   (0b00_0100, "stw"),
+        Stb   (0b00_0101, "stb"),
+        Sth   (0b00_0110, "sth"),
+        Ldsw  (0b00_1000, "ldsw"),
+        Ldsb  (0b00_1001, "ldsb"),
+        Ldsh  (0b00_1010, "ldsh"),
+        Ldx   (0b00_1011, "ldx"),
+        Stx   (0b00_1110, "stx"),
+
+        Ldf   (0b10_0000, "ldf"),
+        Ldfsr (0b10_0001, "ldfsr"),
+        Ldaf  (0b10_0010, "ldaf"),
+        Lddf  (0b10_0011, "lddf"),
+        Stf   (0b10_0100, "stf"),
+        Stfsr (0b10_0101, "stfsr"),
+        Staf  (0x10_0110, "staf"),
+        Stdf  (0b10_0111, "stdf"),
+
+        Fcmp  (0b11_0101, "fcmp"),
+
+        Ldxa  (0b01_1011, "ldxa"),
+        Lduwa (0b01_0000, "lduwa");
 
         // @formatter:on
 
@@ -3405,6 +3405,10 @@
         public Jmpl(Register src, int simm13, Register dst) {
             super(Op3s.Jmpl, src, simm13, dst);
         }
+
+        public Jmpl(Register src1, Register src2, Register dst) {
+            super(Op3s.Jmpl, src1, src2, dst);
+        }
     }
 
     public static class Lddf extends Fmt11 {
@@ -3687,6 +3691,8 @@
         public Return(Register src1, Register src2) {
             super(Op3s.Rett, src1, src2, r0);
         }
+
+        public static int PC_RETURN_OFFSET = 8;
     }
 
     public static class Save extends Fmt10 {
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Wed Jul 30 10:39:39 2014 -0700
@@ -653,33 +653,36 @@
     }
 
     @Override
-    public Value emitUDiv(Value a, Value b, LIRFrameState state) {
-        // LIRFrameState state = state(deopting);
+    public Value emitURem(Value a, Value b, LIRFrameState state) {
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind().getStackKind()) {
             case Int:
-                // emitDivRem(IUDIV, a, b, state);
-                // return emitMove(RAX_I);
+                append(new RemOp(IUREM, result, a, loadNonConst(b), state, this));
+                break;
             case Long:
-                // emitDivRem(LUDIV, a, b, state);
-                // return emitMove(RAX_L);
+                append(new RemOp(LUREM, result, a, loadNonConst(b), state, this));
+                break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
+        return result;
+
     }
 
     @Override
-    public Value emitURem(Value a, Value b, LIRFrameState state) {
-        // LIRFrameState state = state(deopting);
+    public Value emitUDiv(Value a, Value b, LIRFrameState state) {
+        SPARCArithmetic op;
         switch (a.getKind().getStackKind()) {
             case Int:
-                // emitDivRem(IUREM, a, b, state);
-                // return emitMove(RDX_I);
+                op = IUDIV;
+                break;
             case Long:
-                // emitDivRem(LUREM, a, b, state);
-                // return emitMove(RDX_L);
+                op = LUDIV;
+                break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
+        return emitBinary(op, false, a, b, state);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Wed Jul 30 10:39:39 2014 -0700
@@ -172,6 +172,7 @@
     public CompilationResultBuilder newCompilationResultBuilder(LIRGenerationResult lirGenRes, CompilationResult compilationResult, CompilationResultBuilderFactory factory) {
         SPARCHotSpotLIRGenerationResult gen = (SPARCHotSpotLIRGenerationResult) lirGenRes;
         FrameMap frameMap = gen.getFrameMap();
+        LIR lir = gen.getLIR();
         assert gen.getDeoptimizationRescueSlot() == null || frameMap.frameNeedsAllocating() : "method that can deoptimize must have a frame";
 
         Stub stub = gen.getStub();
@@ -186,10 +187,10 @@
         }
 
         if (stub != null) {
-            // SPARC stubs always enter a frame which saves the registers.
-            Set<Register> destroyedRegisters = Collections.emptySet();
-            Map<LIRFrameState, SaveRegistersOp> calleeSaveInfo = Collections.emptyMap();
-            updateStub(stub, destroyedRegisters, calleeSaveInfo, frameMap);
+            // Even on sparc we need to save floating point registers
+            Set<Register> definedRegisters = gatherDefinedRegisters(lir);
+            Map<LIRFrameState, SaveRegistersOp> calleeSaveInfo = gen.getCalleeSaveInfo();
+            updateStub(stub, definedRegisters, calleeSaveInfo, frameMap);
         }
 
         return crb;
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java	Wed Jul 30 10:39:39 2014 -0700
@@ -22,13 +22,14 @@
  */
 package com.oracle.graal.hotspot.sparc;
 
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 import static com.oracle.graal.sparc.SPARC.*;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Stw;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Stx;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
@@ -40,19 +41,21 @@
     private final int threadLastJavaPcOffset;
     private final int threadJavaFrameAnchorFlagsOffset;
     private final Register thread;
+    @Use({REG, STACK}) protected Value threadTemp;
 
-    public SPARCHotSpotCRuntimeCallEpilogueOp(int threadLastJavaSpOffset, int threadLastJavaPcOffset, int threadJavaFrameAnchorFlagsOffset, Register thread) {
+    public SPARCHotSpotCRuntimeCallEpilogueOp(int threadLastJavaSpOffset, int threadLastJavaPcOffset, int threadJavaFrameAnchorFlagsOffset, Register thread, Value threadTemp) {
         this.threadLastJavaSpOffset = threadLastJavaSpOffset;
         this.threadLastJavaPcOffset = threadLastJavaPcOffset;
         this.threadJavaFrameAnchorFlagsOffset = threadJavaFrameAnchorFlagsOffset;
         this.thread = thread;
+        this.threadTemp = threadTemp;
     }
 
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
 
         // Restore the thread register when coming back from the runtime.
-        new Mov(l7, thread).emit(masm);
+        SPARCMove.move(crb, masm, thread.asValue(LIRKind.value(Kind.Long)), threadTemp);
 
         // Reset last Java frame, last Java PC and flags.
         new Stx(g0, new SPARCAddress(thread, threadLastJavaSpOffset)).emit(masm);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java	Wed Jul 30 10:39:39 2014 -0700
@@ -22,13 +22,14 @@
  */
 package com.oracle.graal.hotspot.sparc;
 
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 import static com.oracle.graal.sparc.SPARC.*;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Add;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Stx;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
@@ -39,11 +40,13 @@
     private final int threadLastJavaSpOffset;
     private final Register thread;
     private final Register stackPointer;
+    @Def({REG, STACK}) protected Value threadTemp;
 
-    public SPARCHotSpotCRuntimeCallPrologueOp(int threadLastJavaSpOffset, Register thread, Register stackPointer) {
+    public SPARCHotSpotCRuntimeCallPrologueOp(int threadLastJavaSpOffset, Register thread, Register stackPointer, Value threadTemp) {
         this.threadLastJavaSpOffset = threadLastJavaSpOffset;
         this.thread = thread;
         this.stackPointer = stackPointer;
+        this.threadTemp = threadTemp;
     }
 
     @Override
@@ -53,6 +56,6 @@
         new Stx(g4, new SPARCAddress(thread, threadLastJavaSpOffset)).emit(masm);
 
         // Save the thread register when calling out to the runtime.
-        new Mov(thread, l7).emit(masm);
+        SPARCMove.move(crb, masm, threadTemp, thread.asValue(LIRKind.value(Kind.Long)));
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Wed Jul 30 10:39:39 2014 -0700
@@ -27,6 +27,8 @@
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.sparc.SPARC.*;
 
+import java.util.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.*;
@@ -46,6 +48,7 @@
 
     final HotSpotVMConfig config;
     private HotSpotLockStack lockStack;
+    private LIRFrameState currentRuntimeCallInfo;
 
     public SPARCHotSpotLIRGenerator(HotSpotProviders providers, HotSpotVMConfig config, CallingConvention cc, LIRGenerationResult lirGenRes) {
         super(providers, cc, lirGenRes);
@@ -90,6 +93,21 @@
     }
 
     @Override
+    public void beforeRegisterAllocation() {
+        super.beforeRegisterAllocation();
+        boolean hasDebugInfo = getResult().getLIR().hasDebugInfo();
+        if (hasDebugInfo) {
+            ((SPARCHotSpotLIRGenerationResult) getResult()).setDeoptimizationRescueSlot(getResult().getFrameMap().allocateSpillSlot(LIRKind.value(Kind.Long)));
+        }
+    }
+
+    @Override
+    protected void emitForeignCall(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info) {
+        currentRuntimeCallInfo = info;
+        super.emitForeignCall(linkage, result, arguments, temps, info);
+    }
+
+    @Override
     public Variable emitForeignCall(ForeignCallLinkage linkage, LIRFrameState state, Value... args) {
         HotSpotForeignCallLinkage hotspotLinkage = (HotSpotForeignCallLinkage) linkage;
         Variable result;
@@ -103,10 +121,11 @@
         if (hotspotLinkage.needsJavaFrameAnchor()) {
             HotSpotRegistersProvider registers = getProviders().getRegisters();
             Register thread = registers.getThreadRegister();
+            Value threadTemp = newVariable(LIRKind.value(Kind.Long));
             Register stackPointer = registers.getStackPointerRegister();
-            append(new SPARCHotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), thread, stackPointer));
+            append(new SPARCHotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), thread, stackPointer, threadTemp));
             result = super.emitForeignCall(hotspotLinkage, deoptInfo, args);
-            append(new SPARCHotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadJavaFrameAnchorFlagsOffset(), thread));
+            append(new SPARCHotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadJavaFrameAnchorFlagsOffset(), thread, threadTemp));
         } else {
             result = super.emitForeignCall(hotspotLinkage, deoptInfo, args);
         }
@@ -278,10 +297,16 @@
         ForeignCallLinkage linkage = getForeignCalls().lookupForeignCall(UNCOMMON_TRAP);
 
         Register threadRegister = getProviders().getRegisters().getThreadRegister();
+        Value threadTemp = newVariable(LIRKind.value(Kind.Long));
         Register stackPointerRegister = getProviders().getRegisters().getStackPointerRegister();
-        append(new SPARCHotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), threadRegister, stackPointerRegister));
+        append(new SPARCHotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), threadRegister, stackPointerRegister, threadTemp));
         Variable result = super.emitForeignCall(linkage, null, threadRegister.asValue(LIRKind.value(Kind.Long)), trapRequest);
-        append(new SPARCHotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadJavaFrameAnchorFlagsOffset(), threadRegister));
+        append(new SPARCHotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadJavaFrameAnchorFlagsOffset(), threadRegister, threadTemp));
+
+        Map<LIRFrameState, SaveRegistersOp> calleeSaveInfo = ((SPARCHotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo();
+        assert currentRuntimeCallInfo != null;
+        assert !calleeSaveInfo.containsKey(currentRuntimeCallInfo);
+        calleeSaveInfo.put(currentRuntimeCallInfo, saveRegisterOp);
 
         return result;
     }
@@ -291,10 +316,16 @@
         ForeignCallLinkage linkage = getForeignCalls().lookupForeignCall(FETCH_UNROLL_INFO);
 
         Register threadRegister = getProviders().getRegisters().getThreadRegister();
+        Value threadTemp = newVariable(LIRKind.value(Kind.Long));
         Register stackPointerRegister = getProviders().getRegisters().getStackPointerRegister();
-        append(new SPARCHotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), threadRegister, stackPointerRegister));
+        append(new SPARCHotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), threadRegister, stackPointerRegister, threadTemp));
         Variable result = super.emitForeignCall(linkage, null, threadRegister.asValue(LIRKind.value(Kind.Long)));
-        append(new SPARCHotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadJavaFrameAnchorFlagsOffset(), threadRegister));
+        append(new SPARCHotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadJavaFrameAnchorFlagsOffset(), threadRegister, threadTemp));
+
+        Map<LIRFrameState, SaveRegistersOp> calleeSaveInfo = ((SPARCHotSpotLIRGenerationResult) getResult()).getCalleeSaveInfo();
+        assert currentRuntimeCallInfo != null;
+        assert !calleeSaveInfo.containsKey(currentRuntimeCallInfo);
+        calleeSaveInfo.put(currentRuntimeCallInfo, saveRegisterOp);
 
         return result;
     }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Wed Jul 30 10:39:39 2014 -0700
@@ -73,7 +73,8 @@
         Value offset = operand(x.offset());
         Variable cmpValue = (Variable) gen.loadNonConst(operand(x.expectedValue()));
         Variable newValue = gen.load(operand(x.newValue()));
-
+        Variable newValueTemp = gen.newVariable(newValue.getLIRKind());
+        getGen().emitMove(newValueTemp, newValue);
         LIRKind kind = cmpValue.getLIRKind();
         assert kind.equals(newValue.getLIRKind());
 
@@ -88,8 +89,8 @@
             }
         }
 
-        append(new CompareAndSwapOp(address, cmpValue, newValue));
-        setResult(x, gen.emitMove(newValue));
+        append(new CompareAndSwapOp(address, cmpValue, newValueTemp));
+        setResult(x, gen.emitMove(newValueTemp));
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java	Wed Jul 30 10:39:39 2014 -0700
@@ -26,9 +26,9 @@
 import static com.oracle.graal.sparc.SPARC.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
 
+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.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
@@ -48,19 +48,7 @@
 
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-        // FIXME This is non-trivial. On SPARC we need to flush all register windows first before we
-        // can patch the return address (see: frame::patch_pc).
-        new Flushw().emit(masm);
-        // int frameSize = crb.frameMap.frameSize();
-        // new SPARCAssembler.Ldx(new SPARCAddress(o7, 1), g3).emit(masm);
-        // new Setx(8 * 15 - 1, g4, false).emit(masm);
-        new Mov(asLongReg(address), g4).emit(masm);
-        new Save(sp, -2000, sp).emit(masm);
-
-        new Sub(g4, 0, i7).emit(masm);
-        new Stx(i7, new SPARCAddress(fp, 8 * 15)).emit(masm);
-        new Restore(g0, g0, g0).emit(masm);
-        new Flushw().emit(masm);
-        // new Ldx(new SPARCAddress(g0, 0x123), g0).emit(masm);
+        Register addrRegister = asLongReg(address);
+        new Sub(addrRegister, Return.PC_RETURN_OFFSET, i7).emit(masm);
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Wed Jul 30 10:39:39 2014 -0700
@@ -235,8 +235,14 @@
             }
 
             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;
+                }
                 locations[i] = StackSlot.get(target.getLIRKind(kind.getStackKind()), currentStackOffset, !type.out);
-                currentStackOffset += Math.max(target.getSizeInBytes(kind), target.wordSize);
+                currentStackOffset += typeSize;
             }
         }
 
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectVirtualCallOp.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectVirtualCallOp.java	Wed Jul 30 10:39:39 2014 -0700
@@ -24,9 +24,10 @@
 
 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.Setx;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId;
 import com.oracle.graal.lir.*;
@@ -54,7 +55,8 @@
         // The mark for an invocation that uses an inline cache must be placed at the
         // instruction that loads the Klass from the inline cache.
         MarkId.recordMark(crb, invokeKind == InvokeKind.Virtual ? MarkId.INVOKEVIRTUAL : MarkId.INVOKEINTERFACE);
-        new Setx(HotSpotGraalRuntime.runtime().getConfig().nonOopBits, g3, true).emit(masm);
+        Register scratchRegister = g5;
+        new Setx(HotSpotGraalRuntime.runtime().getConfig().nonOopBits, scratchRegister, true).emit(masm);
         super.emitCode(crb, masm);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Wed Jul 30 10:39:39 2014 -0700
@@ -253,7 +253,7 @@
             // assuming both the stack pointer and page_size have their least
             // significant 2 bits cleared and page_size is a power of 2
             final Word alignedMask = Word.unsigned(wordSize() - 1);
-            final Word stackPointer = registerAsWord(stackPointerRegister);
+            final Word stackPointer = registerAsWord(stackPointerRegister).add(config().stackBias);
             if (probability(VERY_SLOW_PATH_PROBABILITY, currentMark.subtract(stackPointer).and(alignedMask.subtract(pageSize())).notEqual(0))) {
                 // Most likely not a recursive lock, go into a slow runtime call
                 traceObject(trace, "+lock{stub:failed-cas}", object, true);
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_irem.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_irem.java	Wed Jul 30 10:39:39 2014 -0700
@@ -34,6 +34,16 @@
         return a % b;
     }
 
+    // Left as constant
+    public static int test2(int b) {
+        return 13 % b;
+    }
+
+    // Right as constant
+    public static int test3(int a) {
+        return a % 13;
+    }
+
     @Test
     public void run0() throws Throwable {
         runTest("test", 1, 2);
@@ -54,4 +64,33 @@
         runTest("test", 135, 7);
     }
 
+    @Test
+    public void run20() throws Throwable {
+        runTest("test2", 2);
+    }
+
+    @Test
+    public void run21() throws Throwable {
+        runTest("test2", 20000000);
+    }
+
+    @Test
+    public void run22() throws Throwable {
+        runTest("test2", -20000000);
+    }
+
+    @Test
+    public void run30() throws Throwable {
+        runTest("test3", 2);
+    }
+
+    @Test
+    public void run31() throws Throwable {
+        runTest("test3", 200000000);
+    }
+
+    @Test
+    public void run32() throws Throwable {
+        runTest("test3", -200000000);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/micro/BigMixedParams04.java	Wed Jul 30 10:39:39 2014 -0700
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2007, 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.
+ */
+/*
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+package com.oracle.graal.jtt.micro;
+
+import org.junit.*;
+
+import com.oracle.graal.jtt.*;
+
+/**
+ * Tests different alignment on the stack with extended parameters (index > 5)
+ */
+public class BigMixedParams04 extends JTTTest {
+
+    @SuppressWarnings("unused")
+    public static long test(int choice, int i0, int i1, int i2, int i3, double d1, double d2, boolean bo1, boolean bo2, byte by, short sh, char ch, int in) {
+        switch (choice) {
+            case 0:
+                return bo1 ? 1l : 2l;
+            case 1:
+                return bo2 ? 1l : 2l;
+            case 2:
+                return by;
+            case 3:
+                return sh;
+            case 4:
+                return ch;
+            case 5:
+                return in;
+        }
+        return 42;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        runTest("test", 0, -1, -1, -1, -1, 1d, 2d, true, false, (byte) -128, (short) -0x7FFF, (char) 0xFFFF, -0x7FFFFFF);
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        runTest("test", 1, -1, -1, -1, -1, 1d, 2d, true, false, (byte) -128, (short) -0x7FFF, (char) 0xFFFF, -0x7FFFFFF);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        runTest("test", 2, -1, -1, -1, -1, 1d, 2d, true, false, (byte) -128, (short) -0x7FFF, (char) 0xFFFF, -0x7FFFFFF);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        runTest("test", 3, -1, -1, -1, -1, 1d, 2d, true, false, (byte) -128, (short) -0x7FFF, (char) 0xFFFF, -0x7FFFFFF);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        runTest("test", 4, -1, -1, -1, -1, 1d, 2d, true, false, (byte) -128, (short) -0x7FFF, (char) 0xFFFF, -0x7FFFFFF);
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        runTest("test", 5, -1, -1, -1, -1, 1d, 2d, true, false, (byte) -128, (short) -0x7FFF, (char) 0xFFFF, -0x7FFFFFF);
+    }
+}
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Wed Jul 30 10:39:39 2014 -0700
@@ -250,8 +250,8 @@
         @Def({REG}) protected Value result;
         @Use({REG, CONST}) protected Value x;
         @Alive({REG, CONST}) protected Value y;
-        @Def({REG}) protected Value scratch1;
-        @Def({REG}) protected Value scratch2;
+        @Temp({REG}) protected Value scratch1;
+        @Temp({REG}) protected Value scratch2;
         @State protected LIRFrameState state;
 
         public RemOp(SPARCArithmetic opcode, Value result, Value x, Value y, LIRFrameState state, LIRGeneratorTool gen) {
@@ -324,6 +324,10 @@
                     assert isSimm13(crb.asIntConst(src2));
                     new Sdivx(asIntReg(src1), crb.asIntConst(src2), asIntReg(dst)).emit(masm);
                     break;
+                case IUDIV:
+                    assert isSimm13(crb.asIntConst(src2));
+                    new Udivx(asIntReg(src1), crb.asIntConst(src2), asIntReg(dst)).emit(masm);
+                    break;
                 case IAND:
                     assert isSimm13(crb.asIntConst(src2)) : src2;
                     new And(asIntReg(src1), crb.asIntConst(src2), asIntReg(dst)).emit(masm);
@@ -360,7 +364,7 @@
                     assert isSimm13(crb.asIntConst(src2));
                     new Mulx(asLongReg(src1), crb.asIntConst(src2), asLongReg(dst)).emit(masm);
                     break;
-                case LDIV:
+                case LDIV: {
                     int c = crb.asIntConst(src2);
                     exceptionOffset = masm.position();
                     if (c == 0) { // Generate div by zero trap
@@ -372,8 +376,14 @@
                         new Sdivx(asLongReg(src1), crb.asIntConst(src2), asLongReg(dst)).emit(masm);
                     }
                     break;
-                case LUDIV:
-                    throw GraalInternalError.unimplemented();
+                }
+                case LUDIV: {
+                    int c = crb.asIntConst(src2);
+                    assert isSimm13(c);
+                    exceptionOffset = masm.position();
+                    new Udivx(asLongReg(src1), c, asLongReg(dst)).emit(masm);
+                    break;
+                }
                 case LAND:
                     assert isSimm13(crb.asIntConst(src2));
                     new And(asLongReg(src1), crb.asIntConst(src2), asLongReg(dst)).emit(masm);
@@ -425,9 +435,15 @@
                     break;
                 case IDIV:
                     new Signx(asIntReg(src1), asIntReg(src1)).emit(masm);
+                    new Signx(asIntReg(src2), asIntReg(src2)).emit(masm);
                     exceptionOffset = masm.position();
                     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;
                 case IAND:
                     new And(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm);
                     break;
@@ -462,7 +478,9 @@
                     new Sdivx(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
                     break;
                 case LUDIV:
-                    throw GraalInternalError.unimplemented();
+                    exceptionOffset = masm.position();
+                    new Udivx(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
+                    break;
                 case LAND:
                     new And(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm);
                     break;
@@ -532,8 +550,8 @@
                     } else {
                         new Setx(a % b, asIntReg(dst), false).emit(masm);
                     }
+                    break;
                 }
-                    break;
                 case LREM: {
                     long a = crb.asLongConst(src1);
                     long b = crb.asLongConst(src2);
@@ -543,16 +561,11 @@
                     } else {
                         new Setx(a % b, asLongReg(dst), false).emit(masm);
                     }
+                    break;
                 }
-                    break;
                 default:
                     throw GraalInternalError.shouldNotReachHere("not implemented");
             }
-        } else if (isConstant(src1)) {
-            switch (opcode) {
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
-            }
         } else if (isConstant(src2)) {
             switch (opcode) {
                 case IREM:
@@ -563,6 +576,13 @@
                     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);
+                    break;
                 case LREM:
                     assert isSimm13(crb.asIntConst(src2));
                     exceptionOffset = masm.position();
@@ -571,26 +591,55 @@
                     new Sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst)).emit(masm);
                     break;
                 case LUREM:
-                    throw GraalInternalError.unimplemented();
+                    assert isSimm13(crb.asIntConst(src2));
+                    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);
+                    new Sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst)).emit(masm);
+                    break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
             }
         } else {
+            Value srcLeft = src1;
             switch (opcode) {
                 case LREM:
+                    if (isConstant(src1)) {
+                        new Setx(crb.asLongConst(src1), asLongReg(scratch2), false).emit(masm);
+                        srcLeft = scratch2;
+                    }
                     exceptionOffset = masm.position();
-                    new Sdivx(asLongReg(src1), asLongReg(src2), asLongReg(scratch1)).emit(masm);
-                    new Mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch2)).emit(masm);
-                    new Sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst)).emit(masm);
+                    new Sdivx(asLongReg(srcLeft), asLongReg(src2), asLongReg(scratch1)).emit(masm);
+                    new Mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch1)).emit(masm);
+                    new Sub(asLongReg(srcLeft), asLongReg(scratch1), asLongReg(dst)).emit(masm);
+                    break;
+                case LUREM:
+                    if (isConstant(src1)) {
+                        new Setx(crb.asLongConst(src1), asLongReg(scratch2), false).emit(masm);
+                        srcLeft = scratch2;
+                    }
+                    exceptionOffset = masm.position();
+                    new Udivx(asLongReg(srcLeft), asLongReg(src2), asLongReg(scratch1)).emit(masm);
+                    new Mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch1)).emit(masm);
+                    new Sub(asLongReg(srcLeft), asLongReg(scratch1), asLongReg(dst)).emit(masm);
                     break;
                 case IREM:
+                    if (isConstant(src1)) {
+                        new Setx(crb.asIntConst(src1), asIntReg(scratch2), false).emit(masm);
+                        srcLeft = scratch2;
+                    }
                     exceptionOffset = masm.position();
-                    new Sdivx(asIntReg(src1), asIntReg(src2), asIntReg(scratch1)).emit(masm);
-                    new Mulx(asIntReg(scratch1), asIntReg(src2), asIntReg(scratch2)).emit(masm);
-                    new Sub(asIntReg(src1), asIntReg(scratch2), asIntReg(dst)).emit(masm);
+                    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 LUREM:
-                    throw GraalInternalError.unimplemented();
+                case IUREM:
+                    new Sra(asIntReg(src1), 0, asIntReg(scratch1)).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);
+                    break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
             }
@@ -668,28 +717,40 @@
                     break;
                 case F2L:
                     new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(dst), asFloatReg(dst)).emit(masm);
-                    new Fbe(false, 4).emit(masm);
+                    new Fbe(false, 4 * 4).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);
                     break;
                 case F2I:
                     new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(dst), asFloatReg(dst)).emit(masm);
-                    new Fbo(false, 4).emit(masm);
+                    new Fbo(false, 4 * 4).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);
                     break;
+                case MOV_D2L:
+                    new Movdtox(asDoubleReg(src), asLongReg(dst)).emit(masm);
+                    break;
+                case MOV_L2D:
+                    new Movxtod(asLongReg(src), asDoubleReg(dst)).emit(masm);
+                    break;
+                case MOV_F2I:
+                    new Movstosw(asFloatReg(src), asIntReg(dst)).emit(masm);
+                    break;
+                case MOV_I2F:
+                    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).emit(masm);
+                    new Fbo(false, 4 * 4).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);
                     break;
                 case D2I:
                     new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(dst), asDoubleReg(dst)).emit(masm);
-                    new Fbo(false, 4).emit(masm);
+                    new Fbo(false, 4 * 4).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);
@@ -740,6 +801,8 @@
             case ISHL:
             case ISHR:
             case IUSHR:
+            case IUDIV:
+            case IUREM:
                 rk = result.getKind();
                 xsk = x.getKind().getStackKind();
                 ysk = y.getKind().getStackKind();
@@ -753,6 +816,8 @@
             case LAND:
             case LOR:
             case LXOR:
+            case LUDIV:
+            case LUREM:
                 rk = result.getKind();
                 xk = x.getKind();
                 yk = y.getKind();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java	Wed Jul 30 10:39:39 2014 -0700
@@ -160,10 +160,10 @@
         } else {
             new Call(0).emit(masm);
         }
+        new Nop().emit(masm);  // delay slot
         int after = masm.position();
         crb.recordDirectCall(before, after, callTarget, info);
         crb.recordExceptionHandlers(after, info);
-        new Nop().emit(masm);  // delay slot
         masm.ensureUniquePC();
     }
 
@@ -171,19 +171,19 @@
         int before = masm.position();
         new Sethix(0L, dst, true).emit(masm);
         new Jmp(new SPARCAddress(dst, 0)).emit(masm);
+        new Nop().emit(masm);  // delay slot
         int after = masm.position();
         crb.recordIndirectCall(before, after, target, null);
-        new Nop().emit(masm);  // delay slot
         masm.ensureUniquePC();
     }
 
     public static void indirectCall(CompilationResultBuilder crb, SPARCMacroAssembler masm, Register dst, InvokeTarget callTarget, LIRFrameState info) {
         int before = masm.position();
         new Jmpl(dst, 0, o7).emit(masm);
+        new Nop().emit(masm);  // delay slot
         int after = masm.position();
         crb.recordIndirectCall(before, after, callTarget, info);
         crb.recordExceptionHandlers(after, info);
-        new Nop().emit(masm);  // delay slot
         masm.ensureUniquePC();
     }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Wed Jul 30 10:39:39 2014 -0700
@@ -24,8 +24,8 @@
 
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+import static com.oracle.graal.sparc.SPARC.*;
 
-import com.oracle.graal.api.code.CompilationResult.JumpTable;
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
@@ -256,9 +256,9 @@
             if (lowKey != 0) {
                 // subtract the low value from the switch value
                 new Sub(value, lowKey, value).emit(masm);
-                // masm.setp_gt_s32(value, highKey - lowKey);
+                new Cmp(value, highKey - lowKey).emit(masm);
             } else {
-                // masm.setp_gt_s32(value, highKey);
+                new Cmp(value, highKey).emit(masm);
             }
 
             // Jump to default target if index is not within the jump table
@@ -268,19 +268,21 @@
             }
 
             // Load jump table entry into scratch and jump to it
-            // masm.movslq(value, new AMD64Address(scratch, value, Scale.Times4, 0));
-            // masm.addq(scratch, value);
-            new Jmp(new SPARCAddress(scratchReg, 0)).emit(masm);
-            new Nop().emit(masm);  // delay slot
+            new Sll(value, 3, value).emit(masm); // Multiply by 8
+            new Rdpc(scratchReg).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)
 
-            // address of jump table
-            int tablePos = masm.position();
-
-            JumpTable jt = new JumpTable(tablePos, lowKey, highKey, 4);
-            crb.compilationResult.addAnnotation(jt);
-
-            // SPARC: unimp: tableswitch extract
-            throw GraalInternalError.unimplemented();
+            // Emit jump table entries
+            for (LabelRef target : targets) {
+                Label label = target.label();
+                label.addPatchAt(masm.position());
+                new Bpa(0).emit(masm);
+                new Nop().emit(masm); // delay slot
+            }
         }
     }
 
@@ -404,20 +406,24 @@
                 return ConditionFlag.Equal;
             case NE:
                 return ConditionFlag.NotEqual;
+            case BT:
+                return ConditionFlag.LessUnsigned;
             case LT:
                 return ConditionFlag.Less;
+            case BE:
+                return ConditionFlag.LessEqualUnsigned;
             case LE:
                 return ConditionFlag.LessEqual;
+            case AE:
+                return ConditionFlag.GreaterEqualUnsigned;
             case GE:
                 return ConditionFlag.GreaterEqual;
+            case AT:
+                return ConditionFlag.GreaterUnsigned;
             case GT:
                 return ConditionFlag.Greater;
-            case BE:
-            case AE:
-            case AT:
-            case BT:
             default:
-                throw GraalInternalError.shouldNotReachHere();
+                throw GraalInternalError.shouldNotReachHere("Unimplemented for: " + cond);
         }
     }
 
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFrameMap.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFrameMap.java	Wed Jul 30 10:39:39 2014 -0700
@@ -26,6 +26,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.lir.*;
+import com.oracle.graal.sparc.*;
 
 /**
  * SPARC specific frame map.
@@ -34,11 +35,15 @@
  *
  * <pre>
  *   Base       Contents
- *
+ * 
  *            :                                :  -----
  *   caller   | incoming overflow argument n   |    ^
  *   frame    :     ...                        :    | positive
  *            | incoming overflow argument 0   |    | offsets
+ *            +--------------------------------+    |
+ *            |                                |    |
+ *            : register save area             :    |
+ *            |                                |    |
  *   ---------+--------------------------------+---------------------------
  *            | spill slot 0                   |    | negative   ^      ^
  *            :     ...                        :    v offsets    |      |
@@ -101,4 +106,29 @@
     protected StackSlot allocateNewSpillSlot(LIRKind kind, int additionalOffset) {
         return StackSlot.get(kind, -spillSize + additionalOffset, true);
     }
+
+    /**
+     * In SPARC we have spill slots word aligned
+     */
+    @Override
+    public int spillSlotSize(LIRKind kind) {
+        return SPARC.spillSlotSize(target, kind.getPlatformKind());
+    }
+
+    /**
+     * We must add the calleSaveAreaSize() when it is a in or out parameter
+     */
+    @Override
+    public int offsetForStackSlot(StackSlot slot) {
+        int offset = super.offsetForStackSlot(slot);
+        if (slot.getRawOffset() >= 0) { // If In or Out parameter
+            offset += calleeSaveAreaSize();
+        }
+        return offset;
+    }
+
+    @Override
+    public boolean frameNeedsAllocating() {
+        return super.frameNeedsAllocating() || spillSize > 0;
+    }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Wed Jul 30 10:39:39 2014 -0700
@@ -387,8 +387,13 @@
         } else if (isConstant(input)) {
             if (isRegister(result)) {
                 const2reg(crb, masm, result, (Constant) input);
+            } else if (isStackSlot(result)) {
+                // Move a Constant to a stack slot (Probably a 7th output parameter)
+                Value scratch = input.getKind() == Kind.Float || input.getKind() == Kind.Double ? f30.asValue(input.getLIRKind()) : g5.asValue(input.getLIRKind());
+                const2reg(crb, masm, scratch, (Constant) input);
+                reg2stack(crb, masm, result, scratch);
             } else {
-                throw GraalInternalError.shouldNotReachHere();
+                throw GraalInternalError.shouldNotReachHere("Result is a: " + result);
             }
         } else {
             throw GraalInternalError.shouldNotReachHere();
@@ -405,6 +410,10 @@
             return;
         }
         switch (input.getKind()) {
+            case Boolean:
+            case Byte:
+            case Short:
+            case Char:
             case Int:
             case Long:
             case Object:
@@ -438,7 +447,7 @@
                 }
                 break;
             default:
-                throw GraalInternalError.shouldNotReachHere();
+                throw GraalInternalError.shouldNotReachHere("Input is a: " + input.getKind());
         }
     }
 
@@ -446,6 +455,14 @@
         SPARCAddress dst = (SPARCAddress) crb.asAddress(result);
         Register src = asRegister(input);
         switch (input.getKind()) {
+            case Byte:
+            case Boolean:
+                new Stb(src, dst).emit(masm);
+                break;
+            case Char:
+            case Short:
+                new Sth(src, dst).emit(masm);
+                break;
             case Int:
                 new Stw(src, dst).emit(masm);
                 break;
@@ -460,7 +477,7 @@
                 new Stdf(src, dst).emit(masm);
                 break;
             default:
-                throw GraalInternalError.shouldNotReachHere();
+                throw GraalInternalError.shouldNotReachHere("Input is a: " + input.getKind() + "(" + input + ")");
         }
     }
 
@@ -468,6 +485,16 @@
         SPARCAddress src = (SPARCAddress) crb.asAddress(input);
         Register dst = asRegister(result);
         switch (input.getKind()) {
+            case Boolean:
+            case Byte:
+                new Ldsb(src, dst).emit(masm);
+                break;
+            case Short:
+                new Ldsh(src, dst).emit(masm);
+                break;
+            case Char:
+                new Lduh(src, dst).emit(masm);
+                break;
             case Int:
                 new Ldsw(src, dst).emit(masm);
                 break;
@@ -476,9 +503,13 @@
                 new Ldx(src, dst).emit(masm);
                 break;
             case Float:
+                new Ldf(src, dst).emit(masm);
+                break;
             case Double:
+                new Lddf(src, dst).emit(masm);
+                break;
             default:
-                throw GraalInternalError.shouldNotReachHere();
+                throw GraalInternalError.shouldNotReachHere("Input is a: " + input.getKind());
         }
     }
 
@@ -510,6 +541,7 @@
                 }
                 break;
             case Float:
+                // TODO: Handle it the same way, as in the double case with Movwtos
                 crb.asFloatConstRef(input);
                 // First load the address into the scratch register
                 new Setx(0, scratch, true).emit(masm);
@@ -517,9 +549,8 @@
                 new Ldf(scratch, asFloatReg(result)).emit(masm);
                 break;
             case Double:
-                // before we load this from memory and do the complicated lookup,
+                // instead loading this from memory and do the complicated lookup,
                 // just load it directly into a scratch register
-                scratch = g5;
                 // First load the address into the scratch register
                 new Setx(Double.doubleToLongBits(input.asDouble()), scratch, true).emit(masm);
                 // Now load the float value
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java	Wed Jul 30 10:39:39 2014 -0700
@@ -29,15 +29,13 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsw;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.asm.*;
 
 public class SPARCTestOp extends SPARCLIRInstruction {
 
     @Use({REG}) protected Value x;
-    @Use({REG, STACK, CONST}) protected Value y;
+    @Use({REG, CONST}) protected Value y;
 
     public SPARCTestOp(Value x, Value y) {
         this.x = x;
@@ -48,6 +46,10 @@
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
         if (isRegister(y)) {
             switch (x.getKind()) {
+                case Short:
+                case Byte:
+                case Char:
+                case Boolean:
                 case Int:
                     new Andcc(asIntReg(x), asIntReg(y), g0).emit(masm);
                     break;
@@ -59,6 +61,10 @@
             }
         } else if (isConstant(y)) {
             switch (x.getKind()) {
+                case Short:
+                case Byte:
+                case Char:
+                case Boolean:
                 case Int:
                     new Andcc(asIntReg(x), crb.asIntConst(y), g0).emit(masm);
                     break;
@@ -69,18 +75,7 @@
                     throw GraalInternalError.shouldNotReachHere();
             }
         } else {
-            switch (x.getKind()) {
-                case Int:
-                    new Ldsw((SPARCAddress) crb.asIntAddr(y), asIntReg(y)).emit(masm);
-                    new Andcc(asIntReg(x), asIntReg(y), g0).emit(masm);
-                    break;
-                case Long:
-                    new Ldx((SPARCAddress) crb.asLongAddr(y), asLongReg(y)).emit(masm);
-                    new Andcc(asLongReg(x), asLongReg(y), g0).emit(masm);
-                    break;
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
-            }
+            throw GraalInternalError.shouldNotReachHere();
         }
     }
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Wed Jul 30 10:39:39 2014 -0700
@@ -201,8 +201,11 @@
      * @return the offset of the stack slot
      */
     public int offsetForStackSlot(StackSlot slot) {
-        assert (!slot.getRawAddFrameSize() && slot.getRawOffset() < outgoingSize) || (slot.getRawAddFrameSize() && slot.getRawOffset() < 0 && -slot.getRawOffset() <= spillSize) ||
-                        (slot.getRawAddFrameSize() && slot.getRawOffset() >= 0);
+        // @formatter:off
+        assert (!slot.getRawAddFrameSize() && slot.getRawOffset() <  outgoingSize) ||
+               ( slot.getRawAddFrameSize() && slot.getRawOffset() <  0 && -slot.getRawOffset() <= spillSize) ||
+               ( slot.getRawAddFrameSize() && slot.getRawOffset() >= 0);
+        // @formatter:on
         if (slot.isInCallerFrame()) {
             accessesCallerFrame = true;
         }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java	Wed Jul 30 10:39:39 2014 -0700
@@ -258,7 +258,12 @@
             } else if (type == double[].class) {
                 return Arrays.toString((double[]) value);
             } else if (type == byte[].class) {
-                return Arrays.toString((byte[]) value);
+                byte[] byteValue = (byte[]) value;
+                if (isPrintableAsciiString(byteValue)) {
+                    return toString(byteValue);
+                } else {
+                    return Arrays.toString(byteValue);
+                }
             } else if (!type.getComponentType().isPrimitive()) {
                 return Arrays.toString((Object[]) value);
             }
@@ -266,4 +271,39 @@
         assert false : "unhandled field type: " + type;
         return "";
     }
+
+    /**
+     * Tests if all values in this string are printable ASCII characters or value \0 (b in
+     * [0x20,0x7F]) or b == 0
+     *
+     * @param array
+     * @return true if there are only printable ASCII characters and \0, false otherwise
+     */
+    private static boolean isPrintableAsciiString(byte[] array) {
+        for (byte b : array) {
+            char c = (char) b;
+            if (c != 0 && c < 0x20 && c > 0x7F) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private static String toString(byte[] bytes) {
+        StringBuilder sb = new StringBuilder();
+        sb.append('"');
+        for (byte b : bytes) {
+            if (b == 0) {
+                sb.append("\\0");
+            } else if (b == '"') {
+                sb.append("\\\"");
+            } else if (b == '\n') {
+                sb.append("\\n");
+            } else {
+                sb.append((char) b);
+            }
+        }
+        sb.append('"');
+        return sb.toString();
+    }
 }
--- a/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java	Wed Jul 30 13:42:10 2014 +0200
+++ b/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java	Wed Jul 30 10:39:39 2014 -0700
@@ -189,9 +189,19 @@
      * Stack bias for stack and frame pointer loads.
      */
     public static final int STACK_BIAS = 0x7ff;
+    /**
+     * In fact there are 64 single floating point registers, 32 of them could be accessed. TODO:
+     * Improve handling of these float registers
+     */
+    public static final int FLOAT_REGISTER_COUNT = 64;
+
+    /**
+     * Alignment for valid memory access
+     */
+    public static final int MEMORY_ACCESS_ALIGN = 4;
 
     public SPARC() {
-        super("SPARC", 8, ByteOrder.BIG_ENDIAN, false, allRegisters, LOAD_STORE | STORE_STORE, 1, r31.encoding + 1, 8);
+        super("SPARC", 8, ByteOrder.BIG_ENDIAN, false, allRegisters, LOAD_STORE | STORE_STORE, 1, r31.encoding + FLOAT_REGISTER_COUNT + 1, 8);
     }
 
     @Override
@@ -232,4 +242,8 @@
             return Kind.Illegal;
         }
     }
+
+    public static int spillSlotSize(TargetDescription td, PlatformKind kind) {
+        return Math.max(td.getSizeInBytes(kind), MEMORY_ACCESS_ALIGN);
+    }
 }
--- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp	Wed Jul 30 13:42:10 2014 +0200
+++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp	Wed Jul 30 10:39:39 2014 -0700
@@ -61,9 +61,11 @@
   address pc = _instructions->start() + pc_offset;
   address const_start = _constants->start();
   jint offset = DataSectionReference::offset(data);
+  address dest = _constants->start() + offset;
 
-  NativeMovRegMem* load = nativeMovRegMem_at(pc);
-  load->add_offset_in_bytes((long)const_start+offset);
+  _instructions->relocate(pc + NativeMovConstReg::sethi_offset, internal_word_Relocation::spec((address) dest));
+  _instructions->relocate(pc + NativeMovConstReg::add_offset, internal_word_Relocation::spec((address) dest));
+  TRACE_graal_3("relocating at %p with destination at %p (%d)", pc, dest, offset);
 }
 
 void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Wed Jul 30 13:42:10 2014 +0200
+++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Wed Jul 30 10:39:39 2014 -0700
@@ -3561,6 +3561,7 @@
   int exception_in_tls_offset = __ offset() - start;
 
   // No need to update oop_map  as each call to save_live_registers will produce identical oopmap
+  // Opens a new stack frame
   (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
 
   // Restore G2_thread
@@ -3592,7 +3593,10 @@
   // Reexecute entry, similar to c2 uncommon trap
   //
   int reexecute_offset = __ offset() - start;
-
+#if defined(COMPILERGRAAL) && !defined(COMPILER1)
+  // Graal does not use this kind of deoptimization
+  __ should_not_reach_here();
+#endif
   // No need to update oop_map  as each call to save_live_registers will produce identical oopmap
   (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
 
--- a/src/share/vm/code/nmethod.hpp	Wed Jul 30 13:42:10 2014 +0200
+++ b/src/share/vm/code/nmethod.hpp	Wed Jul 30 10:39:39 2014 -0700
@@ -643,7 +643,21 @@
 
   // (thomaswue) When using graal, the address might be off by 5 (because this is the size of the call instruction.
   // (thomaswue) TODO: Replace this by a more general mechanism.
-  bool is_deopt_entry   (address pc) { return pc == deopt_handler_begin() GRAAL_ONLY( || pc == deopt_handler_begin() + 5); }
+  // (sanzinger) SPARC has another offset, looked for some variable existing in HotSpot which describes this offset, but i have not
+  // found anything.
+  bool is_deopt_entry   (address pc) {
+    return pc == deopt_handler_begin()
+#ifdef GRAAL
+      || pc == deopt_handler_begin() +
+#ifdef TARGET_ARCH_sparc
+  8
+#endif // sparc
+#ifdef TARGET_ARCH_x86
+  5
+#endif // x86
+#endif // GRAAL
+      ;
+  }
   bool is_deopt_mh_entry(address pc) { return pc == deopt_mh_handler_begin(); }
   // Accessor/mutator for the original pc of a frame before a frame was deopted.
   address get_original_pc(const frame* fr) { return *orig_pc_addr(fr); }
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Wed Jul 30 13:42:10 2014 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Wed Jul 30 10:39:39 2014 -0700
@@ -68,6 +68,11 @@
       return as_XMMRegister(remainder)->as_VMReg();
     }
 #endif
+#ifdef TARGET_ARCH_sparc
+    if (remainder < FloatRegisterImpl::number_of_registers) {
+      return as_FloatRegister(remainder)->as_VMReg();
+    }
+#endif
     ShouldNotReachHere();
     return NULL;
   }
@@ -129,6 +134,13 @@
       }
     }
 #endif
+#ifdef TARGET_ARCH_sparc
+    for (jint i = 0; i < FloatRegisterImpl::number_of_registers; i++) {
+      VMReg reg = as_FloatRegister(i)->as_VMReg();
+      int idx = RegisterImpl::number_of_registers + i;
+      set_vmreg_oops(map, reg, register_map, idx);
+    }
+#endif
   }
 
   for (jint i = 0; i < bitset_size(frame_map) / 3; i++) {
@@ -214,6 +226,7 @@
 
   if (value->is_a(RegisterValue::klass())) {
     jint number = code_Register::number(RegisterValue::reg(value));
+    jint encoding = code_Register::encoding(RegisterValue::reg(value));
     if (number < RegisterImpl::number_of_registers) {
       Location::Type locationType;
       if (type == T_INT) {
@@ -249,9 +262,9 @@
       return value;
 #else
 #ifdef TARGET_ARCH_sparc
-      ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, as_FloatRegister(number)->as_VMReg()));
+      ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, as_FloatRegister(encoding)->as_VMReg()));
       if (type == T_DOUBLE) {
-        second = value;
+        second = new ConstantIntValue(0);
       }
       return value;
 #else
--- a/src/share/vm/graal/graalJavaAccess.hpp	Wed Jul 30 13:42:10 2014 +0200
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Wed Jul 30 10:39:39 2014 -0700
@@ -239,6 +239,7 @@
   end_class                                                                                                                                                    \
   start_class(code_Register)                                                                                                                                   \
     int_field(code_Register, number)                                                                                                                           \
+    int_field(code_Register, encoding)                                                                                                                         \
   end_class                                                                                                                                                    \
   start_class(StackSlot)                                                                                                                                       \
     int_field(StackSlot, offset)                                                                                                                               \