changeset 17021:c2437c80c253

[SPARC] Make scratch register usage safe
author Stefan Anzinger <stefan.anzinger@oracle.com>
date Fri, 29 Aug 2014 21:00:14 -0700
parents 5c1bc769563e
children 9364a47125ef
files graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.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/SPARCControlFlow.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARCScratchRegister.java
diffstat 7 files changed, 306 insertions(+), 217 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Fri Aug 29 16:05:30 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Fri Aug 29 21:00:14 2014 -0700
@@ -54,6 +54,7 @@
 import com.oracle.graal.lir.sparc.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.sparc.*;
 
 /**
  * HotSpot SPARC specific backend.
@@ -113,8 +114,11 @@
                     if (SPARCAssembler.isSimm13(address.getDisplacement())) {
                         new Stx(g0, address).emit(masm);
                     } else {
-                        new Setx(address.getDisplacement(), g3).emit(masm);
-                        new Stx(g0, new SPARCAddress(sp, g3)).emit(masm);
+                        try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+                            Register scratch = sc.getRegister();
+                            new Setx(address.getDisplacement(), scratch).emit(masm);
+                            new Stx(g0, new SPARCAddress(sp, scratch)).emit(masm);
+                        }
                     }
                 }
             }
@@ -145,8 +149,11 @@
             if (SPARCAssembler.isSimm13(stackpoinerChange)) {
                 new Save(sp, stackpoinerChange, sp).emit(masm);
             } else {
-                new Setx(stackpoinerChange, g3).emit(masm);
-                new Save(sp, g3, sp).emit(masm);
+                try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+                    Register scratch = sc.getRegister();
+                    new Setx(stackpoinerChange, scratch).emit(masm);
+                    new Save(sp, scratch, sp).emit(masm);
+                }
             }
 
             if (ZapStackOnMethodEntry.getValue()) {
@@ -213,12 +220,15 @@
             // We need to use JavaCall here because we haven't entered the frame yet.
             CallingConvention cc = regConfig.getCallingConvention(JavaCall, null, new JavaType[]{getProviders().getMetaAccess().lookupJavaType(Object.class)}, getTarget(), false);
             Register inlineCacheKlass = g5; // see MacroAssembler::ic_call
-            Register scratch = g3;
-            Register receiver = asRegister(cc.getArgument(0));
-            SPARCAddress src = new SPARCAddress(receiver, config.hubOffset);
 
-            new Ldx(src, scratch).emit(masm);
-            new Cmp(scratch, inlineCacheKlass).emit(masm);
+            try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+                Register scratch = sc.getRegister();
+                Register receiver = asRegister(cc.getArgument(0));
+                SPARCAddress src = new SPARCAddress(receiver, config.hubOffset);
+
+                new Ldx(src, scratch).emit(masm);
+                new Cmp(scratch, inlineCacheKlass).emit(masm);
+            }
             new Bpne(CC.Xcc, unverifiedStub).emit(masm);
             new Nop().emit(masm);  // delay slot
         }
@@ -244,8 +254,10 @@
 
         if (unverifiedStub != null) {
             masm.bind(unverifiedStub);
-            Register scratch = g3;
-            SPARCCall.indirectJmp(crb, masm, scratch, foreignCalls.lookupForeignCall(IC_MISS_HANDLER));
+            try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+                Register scratch = sc.getRegister();
+                SPARCCall.indirectJmp(crb, masm, scratch, foreignCalls.lookupForeignCall(IC_MISS_HANDLER));
+            }
         }
     }
 
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java	Fri Aug 29 16:05:30 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java	Fri Aug 29 21:00:14 2014 -0700
@@ -23,13 +23,13 @@
 package com.oracle.graal.hotspot.sparc;
 
 import static com.oracle.graal.hotspot.HotSpotHostBackend.*;
-import static com.oracle.graal.sparc.SPARC.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
+import com.oracle.graal.sparc.*;
 
 /**
  * Removes the current frame and tail calls the uncommon trap routine.
@@ -46,8 +46,11 @@
         // final boolean isStub = true;
         // HotSpotFrameContext frameContext = backend.new HotSpotFrameContext(isStub);
         // frameContext.enter(crb);
-        Register scratch = g3;
-        SPARCCall.indirectJmp(crb, masm, scratch, crb.foreignCalls.lookupForeignCall(UNCOMMON_TRAP_HANDLER));
+
+        try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+            Register scratch = sc.getRegister();
+            SPARCCall.indirectJmp(crb, masm, scratch, crb.foreignCalls.lookupForeignCall(UNCOMMON_TRAP_HANDLER));
+        }
 
         // frameContext.leave(crb);
     }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Fri Aug 29 16:05:30 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Fri Aug 29 21:00:14 2014 -0700
@@ -110,7 +110,8 @@
     protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
         AllocatableValue metaspaceMethod = g5.asValue();
         gen.emitMove(metaspaceMethod, operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod()));
-        AllocatableValue targetAddress = g3.asValue();
+
+        AllocatableValue targetAddress = o7.asValue();
         gen.emitMove(targetAddress, operand(callTarget.computedAddress()));
         append(new SPARCIndirectCallOp(callTarget.targetMethod(), result, parameters, temps, metaspaceMethod, targetAddress, callState));
     }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Fri Aug 29 16:05:30 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Fri Aug 29 21:00:14 2014 -0700
@@ -26,6 +26,7 @@
 import static com.oracle.graal.asm.sparc.SPARCAssembler.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.sparc.*;
@@ -423,8 +424,11 @@
                     break;
                 case DAND:
                     SPARCAddress addr = (SPARCAddress) crb.recordDataReferenceInCode(asConstant(src2), 4);
-                    addr = SPARCMove.guaranueeLoadable(addr, masm);
-                    new Lddf(addr, asDoubleReg(dst)).emit(masm);
+                    try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+                        Register scratch = sc.getRegister();
+                        addr = SPARCMove.guaranueeLoadable(addr, masm, scratch);
+                        new Lddf(addr, asDoubleReg(dst)).emit(masm);
+                    }
                     new Fandd(asDoubleReg(src1), asDoubleReg(dst), asDoubleReg(dst)).emit(masm);
                     break;
                 case FADD:
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Fri Aug 29 16:05:30 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Fri Aug 29 21:00:14 2014 -0700
@@ -38,6 +38,7 @@
 import com.oracle.graal.lir.StandardOp.BlockEndOp;
 import com.oracle.graal.lir.SwitchStrategy.BaseSwitchClosure;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.sparc.*;
 
 public class SPARCControlFlow {
 
@@ -321,32 +322,38 @@
             if (isSimm13(lowKey)) {
                 new Sub(value, lowKey, scratchReg).emit(masm);
             } else {
-                new Setx(lowKey, g3).emit(masm);
-                new Sub(value, g3, scratchReg).emit(masm);
+                try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+                    Register scratch2 = sc.getRegister();
+                    new Setx(lowKey, scratch2).emit(masm);
+                    new Sub(value, scratch2, scratchReg).emit(masm);
+                }
             }
             int upperLimit = highKey - lowKey;
-            if (isSimm13(upperLimit)) {
-                new Cmp(scratchReg, upperLimit).emit(masm);
-            } else {
-                new Setx(upperLimit, g3).emit(masm);
-                new Cmp(scratchReg, upperLimit).emit(masm);
-            }
+            try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+                Register scratch2 = sc.getRegister();
+                if (isSimm13(upperLimit)) {
+                    new Cmp(scratchReg, upperLimit).emit(masm);
+                } else {
+                    new Setx(upperLimit, scratch2).emit(masm);
+                    new Cmp(scratchReg, upperLimit).emit(masm);
+                }
 
-            // Jump to default target if index is not within the jump table
-            if (defaultTarget != null) {
-                new Bpgu(CC.Icc, defaultTarget.label()).emit(masm);
-                new Nop().emit(masm);  // delay slot
-            }
+                // Jump to default target if index is not within the jump table
+                if (defaultTarget != null) {
+                    new Bpgu(CC.Icc, defaultTarget.label()).emit(masm);
+                    new Nop().emit(masm);  // delay slot
+                }
 
-            // Load jump table entry into scratch and jump to it
-            new Sll(scratchReg, 3, scratchReg).emit(masm); // Multiply by 8
-            // Zero the left bits sll with shcnt>0 does not mask upper 32 bits
-            new Srl(scratchReg, 0, scratchReg).emit(masm);
-            new Rdpc(g3).emit(masm);
+                // Load jump table entry into scratch and jump to it
+                new Sll(scratchReg, 3, scratchReg).emit(masm); // Multiply by 8
+                // Zero the left bits sll with shcnt>0 does not mask upper 32 bits
+                new Srl(scratchReg, 0, scratchReg).emit(masm);
+                new Rdpc(scratch2).emit(masm);
 
-            // The jump table follows four instructions after rdpc
-            new Add(scratchReg, 4 * 4, scratchReg).emit(masm);
-            new Jmpl(g3, scratchReg, g0).emit(masm);
+                // The jump table follows four instructions after rdpc
+                new Add(scratchReg, 4 * 4, scratchReg).emit(masm);
+                new Jmpl(scratch2, scratchReg, g0).emit(masm);
+            }
             new Nop().emit(masm);
             // new Sra(value, 3, value).emit(masm); // delay slot, correct the value (division by 8)
 
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Fri Aug 29 16:05:30 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Fri Aug 29 21:00:14 2014 -0700
@@ -38,6 +38,7 @@
 import com.oracle.graal.lir.StandardOp.MoveOp;
 import com.oracle.graal.lir.StandardOp.NullCheck;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.sparc.*;
 
 public class SPARCMove {
 
@@ -137,36 +138,39 @@
 
         @Override
         public void emitMemAccess(SPARCMacroAssembler masm) {
-            final SPARCAddress addr = guaranueeLoadable(address.toAddress(), masm);
-            final Register dst = asRegister(result);
-            switch (kind) {
-                case Boolean:
-                case Byte:
-                    new Ldsb(addr, dst).emit(masm);
-                    break;
-                case Short:
-                    new Ldsh(addr, dst).emit(masm);
-                    break;
-                case Char:
-                    new Lduh(addr, dst).emit(masm);
-                    break;
-                case Int:
-                    new Ldsw(addr, dst).emit(masm);
-                    break;
-                case Long:
-                    new Ldx(addr, dst).emit(masm);
-                    break;
-                case Float:
-                    new Ldf(addr, dst).emit(masm);
-                    break;
-                case Double:
-                    new Lddf(addr, dst).emit(masm);
-                    break;
-                case Object:
-                    new Ldx(addr, dst).emit(masm);
-                    break;
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
+            try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+                Register scratch = sc.getRegister();
+                final SPARCAddress addr = guaranueeLoadable(address.toAddress(), masm, scratch);
+                final Register dst = asRegister(result);
+                switch (kind) {
+                    case Boolean:
+                    case Byte:
+                        new Ldsb(addr, dst).emit(masm);
+                        break;
+                    case Short:
+                        new Ldsh(addr, dst).emit(masm);
+                        break;
+                    case Char:
+                        new Lduh(addr, dst).emit(masm);
+                        break;
+                    case Int:
+                        new Ldsw(addr, dst).emit(masm);
+                        break;
+                    case Long:
+                        new Ldx(addr, dst).emit(masm);
+                        break;
+                    case Float:
+                        new Ldf(addr, dst).emit(masm);
+                        break;
+                    case Double:
+                        new Lddf(addr, dst).emit(masm);
+                        break;
+                    case Object:
+                        new Ldx(addr, dst).emit(masm);
+                        break;
+                    default:
+                        throw GraalInternalError.shouldNotReachHere();
+                }
             }
         }
     }
@@ -311,33 +315,36 @@
         @Override
         public void emitMemAccess(SPARCMacroAssembler masm) {
             assert isRegister(input);
-            SPARCAddress addr = guaranueeLoadable(address.toAddress(), masm);
-            switch (kind) {
-                case Boolean:
-                case Byte:
-                    new Stb(asRegister(input), addr).emit(masm);
-                    break;
-                case Short:
-                case Char:
-                    new Sth(asRegister(input), addr).emit(masm);
-                    break;
-                case Int:
-                    new Stw(asRegister(input), addr).emit(masm);
-                    break;
-                case Long:
-                    new Stx(asRegister(input), addr).emit(masm);
-                    break;
-                case Object:
-                    new Stx(asRegister(input), addr).emit(masm);
-                    break;
-                case Float:
-                    new Stf(asRegister(input), addr).emit(masm);
-                    break;
-                case Double:
-                    new Stdf(asRegister(input), addr).emit(masm);
-                    break;
-                default:
-                    throw GraalInternalError.shouldNotReachHere("missing: " + kind);
+            try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+                Register scratch = sc.getRegister();
+                SPARCAddress addr = guaranueeLoadable(address.toAddress(), masm, scratch);
+                switch (kind) {
+                    case Boolean:
+                    case Byte:
+                        new Stb(asRegister(input), addr).emit(masm);
+                        break;
+                    case Short:
+                    case Char:
+                        new Sth(asRegister(input), addr).emit(masm);
+                        break;
+                    case Int:
+                        new Stw(asRegister(input), addr).emit(masm);
+                        break;
+                    case Long:
+                        new Stx(asRegister(input), addr).emit(masm);
+                        break;
+                    case Object:
+                        new Stx(asRegister(input), addr).emit(masm);
+                        break;
+                    case Float:
+                        new Stf(asRegister(input), addr).emit(masm);
+                        break;
+                    case Double:
+                        new Stdf(asRegister(input), addr).emit(masm);
+                        break;
+                    default:
+                        throw GraalInternalError.shouldNotReachHere("missing: " + kind);
+                }
             }
         }
     }
@@ -356,28 +363,31 @@
 
         @Override
         public void emitMemAccess(SPARCMacroAssembler masm) {
-            SPARCAddress addr = guaranueeLoadable(address.toAddress(), masm);
-            switch (kind) {
-                case Boolean:
-                case Byte:
-                    new Stb(g0, addr).emit(masm);
-                    break;
-                case Short:
-                case Char:
-                    new Sth(g0, addr).emit(masm);
-                    break;
-                case Int:
-                    new Stw(g0, addr).emit(masm);
-                    break;
-                case Long:
-                case Object:
-                    new Stx(g0, addr).emit(masm);
-                    break;
-                case Float:
-                case Double:
-                    throw GraalInternalError.shouldNotReachHere("Cannot store float constants to memory");
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
+            try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+                Register scratch = sc.getRegister();
+                SPARCAddress addr = guaranueeLoadable(address.toAddress(), masm, scratch);
+                switch (kind) {
+                    case Boolean:
+                    case Byte:
+                        new Stb(g0, addr).emit(masm);
+                        break;
+                    case Short:
+                    case Char:
+                        new Sth(g0, addr).emit(masm);
+                        break;
+                    case Int:
+                        new Stw(g0, addr).emit(masm);
+                        break;
+                    case Long:
+                    case Object:
+                        new Stx(g0, addr).emit(masm);
+                        break;
+                    case Float:
+                    case Double:
+                        throw GraalInternalError.shouldNotReachHere("Cannot store float constants to memory");
+                    default:
+                        throw GraalInternalError.shouldNotReachHere();
+                }
             }
         }
     }
@@ -401,10 +411,14 @@
             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);
+                Register scratch = g1;
+                Constant constant = asConstant(input);
+                if (constant.isNull()) {
+                    new Clr(scratch).emit(masm);
+                } else {
+                    new Setx(constant.asLong(), scratch).emit(masm);
+                }
+                reg2stack(crb, masm, result, scratch.asValue(LIRKind.derive(input)));
             } else {
                 throw GraalInternalError.shouldNotReachHere("Result is a: " + result);
             }
@@ -473,10 +487,9 @@
      * @param masm assembler to output the prior stx command
      * @return a loadable SPARCAddress
      */
-    public static SPARCAddress guaranueeLoadable(SPARCAddress addr, SPARCMacroAssembler masm) {
+    public static SPARCAddress guaranueeLoadable(SPARCAddress addr, SPARCMacroAssembler masm, Register scratch) {
         boolean displacementOutOfBound = addr.getIndex().equals(Register.None) && !SPARCAssembler.isSimm13(addr.getDisplacement());
         if (displacementOutOfBound) {
-            Register scratch = g3;
             new Setx(addr.getDisplacement(), scratch, false).emit(masm);
             return new SPARCAddress(addr.getBase(), scratch);
         } else {
@@ -486,109 +499,117 @@
 
     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:
-            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;
-            case Long:
-            case Object:
-                new Stx(src, dst).emit(masm);
-                break;
-            case Float:
-                new Stf(src, dst).emit(masm);
-                break;
-            case Double:
-                new Stdf(src, dst).emit(masm);
-                break;
-            default:
-                throw GraalInternalError.shouldNotReachHere("Input is a: " + input.getKind() + "(" + input + ")");
+        try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+            Register scratch = sc.getRegister();
+            dst = guaranueeLoadable(dst, masm, scratch);
+            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;
+                case Long:
+                case Object:
+                    new Stx(src, dst).emit(masm);
+                    break;
+                case Float:
+                    new Stf(src, dst).emit(masm);
+                    break;
+                case Double:
+                    new Stdf(src, dst).emit(masm);
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere("Input is a: " + input.getKind() + "(" + input + ")");
+            }
         }
     }
 
     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:
-            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;
-            case Long:
-            case Object:
-                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("Input is a: " + input.getKind());
+        try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+            Register scratch = sc.getRegister();
+            src = guaranueeLoadable(src, masm, scratch);
+            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;
+                case Long:
+                case Object:
+                    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("Input is a: " + input.getKind());
+            }
         }
     }
 
     private static void const2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Constant input) {
-        Register scratch = g5;
-        switch (input.getKind().getStackKind()) {
-            case Int:
-                new Setx(input.asLong(), asIntReg(result)).emit(masm);
-                break;
-            case Long:
-                new Setx(input.asLong(), asLongReg(result)).emit(masm);
-                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);
-                // Now load the float value
-                new Ldf(scratch, asFloatReg(result)).emit(masm);
-                break;
-            case Double:
-                // instead loading this from memory and do the complicated lookup,
-                // just load it directly into a scratch register
-                // First load the address into the scratch register
-                new Setx(Double.doubleToLongBits(input.asDouble()), scratch, true).emit(masm);
-                // Now load the float value
-                new Movxtod(scratch, asDoubleReg(result)).emit(masm);
-                break;
-            case Object:
-                if (input.isNull()) {
-                    new Clr(asRegister(result)).emit(masm);
-                } else if (crb.target.inlineObjects) {
-                    crb.recordInlineDataInCode(input);
-                    new Setx(0xDEADDEADDEADDEADL, asRegister(result), true).emit(masm);
-                } else {
-                    Register dst = asRegister(result);
-                    new Rdpc(dst).emit(masm);
-                    crb.asObjectConstRef(input);
-                    new Ldx(new SPARCAddress(dst, 0), dst).emit(masm);
-                    throw GraalInternalError.shouldNotReachHere("the patched offset might be too big for the load");
-                }
-                break;
-            default:
-                throw GraalInternalError.shouldNotReachHere("missing: " + input.getKind());
+        try (SPARCScratchRegister sc = SPARCScratchRegister.get()) {
+            Register scratch = sc.getRegister();
+            switch (input.getKind().getStackKind()) {
+                case Int:
+                    new Setx(input.asLong(), asIntReg(result)).emit(masm);
+                    break;
+                case Long:
+                    new Setx(input.asLong(), asLongReg(result)).emit(masm);
+                    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);
+                    // Now load the float value
+                    new Ldf(scratch, asFloatReg(result)).emit(masm);
+                    break;
+                case Double:
+                    // instead loading this from memory and do the complicated lookup,
+                    // just load it directly into a scratch register
+                    // First load the address into the scratch register
+                    new Setx(Double.doubleToLongBits(input.asDouble()), scratch, true).emit(masm);
+                    // Now load the float value
+                    new Movxtod(scratch, asDoubleReg(result)).emit(masm);
+                    break;
+                case Object:
+                    if (input.isNull()) {
+                        new Clr(asRegister(result)).emit(masm);
+                    } else if (crb.target.inlineObjects) {
+                        crb.recordInlineDataInCode(input);
+                        new Setx(0xDEADDEADDEADDEADL, asRegister(result), true).emit(masm);
+                    } else {
+                        Register dst = asRegister(result);
+                        new Rdpc(dst).emit(masm);
+                        crb.asObjectConstRef(input);
+                        new Ldx(new SPARCAddress(dst, 0), dst).emit(masm);
+                        throw GraalInternalError.shouldNotReachHere("the patched offset might be too big for the load");
+                    }
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere("missing: " + input.getKind());
+            }
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARCScratchRegister.java	Fri Aug 29 21:00:14 2014 -0700
@@ -0,0 +1,41 @@
+package com.oracle.graal.sparc;
+
+import com.oracle.graal.api.code.*;
+
+public class SPARCScratchRegister implements AutoCloseable {
+    private final ThreadLocal<Boolean> locked = new ThreadLocal<>();
+    private final Register register;
+    private static final SPARCScratchRegister scratch = new SPARCScratchRegister(SPARC.g3);
+
+    private SPARCScratchRegister(Register register) {
+        super();
+        this.register = register;
+    }
+
+    public Register getRegister() {
+        if (locked.get() == null) {
+            locked.set(false);
+        }
+        boolean isLocked = locked.get();
+        if (isLocked) {
+            throw new RuntimeException("Temp Register is already taken!");
+        } else {
+            locked.set(true);
+            return register;
+        }
+    }
+
+    public void close() {
+        boolean isLocked = locked.get();
+        if (isLocked) {
+            locked.set(false);
+        } else {
+            throw new RuntimeException("Temp Register is not taken!");
+        }
+    }
+
+    public static SPARCScratchRegister get() {
+        return scratch;
+    }
+
+}