changeset 10871:c3b09d69dfde

SPARC: fixes and more implementation; can now allocate objects
author twisti
date Wed, 24 Jul 2013 17:57:52 -0700
parents 886c2df7a7e4
children 33a2ca7c3bc8 de55425d3cf5
files graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCSafepointOp.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/SPARCCall.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp
diffstat 15 files changed, 234 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java	Wed Jul 24 16:19:17 2013 -0700
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java	Wed Jul 24 17:57:52 2013 -0700
@@ -26,6 +26,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.sparc.*;
 
 public class SPARCAddress extends AbstractAddress {
 
@@ -103,6 +104,9 @@
     }
 
     /**
+     * This method adds the stack-bias to the displacement if the base register is either
+     * {@link SPARC#sp} or {@link SPARC#fp}.
+     * 
      * @return Optional additive displacement.
      */
     public int getDisplacement() {
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Wed Jul 24 16:19:17 2013 -0700
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Wed Jul 24 17:57:52 2013 -0700
@@ -81,7 +81,7 @@
         }
 
         public Fmt00a(Op2s op2, int imm22, Register rd) {
-            this(rd.encoding(), op2.getValue(), hi22(imm22));
+            this(rd.encoding(), op2.getValue(), imm22);
         }
 
         private int getInstructionBits() {
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Wed Jul 24 16:19:17 2013 -0700
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Wed Jul 24 17:57:52 2013 -0700
@@ -353,13 +353,13 @@
             final int startPc = masm.codeBuffer.position();
 
             if (hi == 0 && lo >= 0) {
-                new Sethi(lo, dst).emit(masm);
+                new Sethi(hi22(lo), dst).emit(masm);
             } else if (hi == -1) {
-                new Sethi(~lo, dst).emit(masm);
+                new Sethi(hi22(~lo), dst).emit(masm);
                 new Xor(dst, ~lo10(~0), dst).emit(masm);
             } else {
                 int shiftcnt = 0;
-                new Sethi(hi, dst).emit(masm);
+                new Sethi(hi22(hi), dst).emit(masm);
                 if ((hi & 0x3ff) != 0) {                                       // Any bits?
                     new Or(dst, hi & 0x3ff, dst).emit(masm);                   // msb 32-bits are now in lsb 32
                 }
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Wed Jul 24 16:19:17 2013 -0700
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Wed Jul 24 17:57:52 2013 -0700
@@ -376,7 +376,7 @@
         if (SPARCAssembler.isWordDisp30(maxOffset)) {
             append(new SPARCCall.DirectNearForeignCallOp(linkage, result, arguments, temps, info));
         } else {
-            append(new SPARCCall.DirectFarForeignCallOp(this, linkage, result, arguments, temps, info));
+            append(new SPARCCall.DirectFarForeignCallOp(linkage, result, arguments, temps, info));
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java	Wed Jul 24 17:57:52 2013 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.sparc;
+
+import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
+import static com.oracle.graal.hotspot.HotSpotBackend.*;
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+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.hotspot.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.sparc.*;
+import com.oracle.graal.lir.asm.*;
+
+@Opcode("DEOPT")
+final class SPARCDeoptimizeOp extends SPARCLIRInstruction {
+
+    private DeoptimizationAction action;
+    private DeoptimizationReason reason;
+    @State private LIRFrameState info;
+
+    SPARCDeoptimizeOp(DeoptimizationAction action, DeoptimizationReason reason, LIRFrameState info) {
+        this.action = action;
+        this.reason = reason;
+        this.info = info;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+        HotSpotGraalRuntime runtime = graalRuntime();
+        Register thread = runtime.getRuntime().threadRegister();
+        Register scratch = g3;
+        new Mov(tasm.runtime.encodeDeoptActionAndReason(action, reason), scratch).emit(masm);
+        new Stw(scratch, new SPARCAddress(thread, runtime.getConfig().pendingDeoptimizationOffset)).emit(masm);
+        // TODO the patched call address looks odd (and is invalid) compared to other runtime calls:
+// 0xffffffff749bb5fc: call 0xffffffff415a720c ; {runtime_call}
+// [Exception Handler]
+// 0xffffffff749bb604: call 0xffffffff749bb220 ; {runtime_call}
+// 0xffffffff749bb608: nop
+// [Deopt Handler Code]
+// 0xffffffff749bb60c: call 0xffffffff748da540 ; {runtime_call}
+// 0xffffffff749bb610: nop
+        SPARCCall.directCall(tasm, masm, tasm.runtime.lookupForeignCall(UNCOMMON_TRAP), null, false, info);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java	Wed Jul 24 17:57:52 2013 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.sparc;
+
+import static com.oracle.graal.sparc.SPARC.*;
+import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.sparc.*;
+import com.oracle.graal.lir.asm.*;
+
+@Opcode("CRUNTIME_CALL_EPILOGUE")
+final class SPARCHotSpotCRuntimeCallEpilogueOp extends SPARCLIRInstruction {
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+        Register thread = graalRuntime().getRuntime().threadRegister();
+
+        // Restore the thread register when coming back from the runtime.
+        new Mov(l7, thread).emit(masm);
+
+        // Reset last Java frame.
+        new Stx(g0, new SPARCAddress(thread, graalRuntime().getConfig().threadLastJavaSpOffset)).emit(masm);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java	Wed Jul 24 17:57:52 2013 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.sparc;
+
+import static com.oracle.graal.sparc.SPARC.*;
+import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.sparc.*;
+import com.oracle.graal.lir.asm.*;
+
+@Opcode("CRUNTIME_CALL_PROLOGUE")
+final class SPARCHotSpotCRuntimeCallPrologueOp extends SPARCLIRInstruction {
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+        HotSpotRuntime runtime = graalRuntime().getRuntime();
+        Register thread = runtime.threadRegister();
+        Register stackPointer = runtime.stackPointerRegister();
+
+        // Save last Java frame.
+        new Add(stackPointer, new SPARCAddress(stackPointer, 0).getDisplacement(), g4).emit(masm);
+        new Stx(g4, new SPARCAddress(thread, graalRuntime().getConfig().threadLastJavaSpOffset)).emit(masm);
+
+        // Save the thread register when calling out to the runtime.
+        new Mov(thread, l7).emit(masm);
+    }
+}
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Wed Jul 24 16:19:17 2013 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Wed Jul 24 17:57:52 2013 -0700
@@ -86,6 +86,22 @@
     }
 
     @Override
+    public Variable emitForeignCall(ForeignCallLinkage linkage, DeoptimizingNode info, Value... args) {
+        Variable result;
+
+        if (linkage.canDeoptimize()) {
+            assert info != null;
+            append(new SPARCHotSpotCRuntimeCallPrologueOp());
+            result = super.emitForeignCall(linkage, info, args);
+            append(new SPARCHotSpotCRuntimeCallEpilogueOp());
+        } else {
+            result = super.emitForeignCall(linkage, null, args);
+        }
+
+        return result;
+    }
+
+    @Override
     public void visitSafepointNode(SafepointNode i) {
         LIRFrameState info = state(i);
         append(new SPARCSafepointOp(info, runtime().config, this));
@@ -159,13 +175,11 @@
         RegisterValue exceptionParameter = (RegisterValue) linkageCc.getArgument(0);
         emitMove(exceptionParameter, exception);
         append(new SPARCHotSpotUnwindOp(exceptionParameter));
-        throw GraalInternalError.unimplemented();
     }
 
     @Override
     public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) {
-// append(new AMD64DeoptimizeOp(action, deopting.getDeoptimizationReason(), state(deopting)));
-        throw GraalInternalError.unimplemented();
+        append(new SPARCDeoptimizeOp(action, deopting.getDeoptimizationReason(), state(deopting)));
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java	Wed Jul 24 16:19:17 2013 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPatchReturnAddressOp.java	Wed Jul 24 17:57:52 2013 -0700
@@ -50,6 +50,6 @@
         // can patch the return address (see: frame::patch_pc).
         // int frameSize = tasm.frameMap.frameSize();
         // new Stx(asRegister(address), new SPARCAddress(sp, frameSize));
-        new Ldx(new SPARCAddress(g0, g0), g0).emit(masm);
+        new Ldx(new SPARCAddress(g0, 0x123), g0).emit(masm);
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Wed Jul 24 16:19:17 2013 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Wed Jul 24 17:57:52 2013 -0700
@@ -77,7 +77,9 @@
     private final Register[] fpuParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7};
 
     private final Register[] callerSaveRegisters = {g1, g3, g4, g5, o0, o1, o2, o3, o4, o5, o7};
-    private final Register[] calleeSaveRegisters = {l0, l1, l2, l3, l4, l5, l6, l7, i0, i1, i2, i3, i4, i5, i6, i7};
+// private final Register[] calleeSaveRegisters = {l0, l1, l2, l3, l4, l5, l6, l7, i0, i1, i2, i3,
+// i4, i5, i6, i7};
+    private final Register[] calleeSaveRegisters = {l0, l1, l2, l3, l4, l5, l6, l7};
 
     private final CalleeSaveLayout csl;
 
@@ -202,12 +204,16 @@
         }
 
         Kind returnKind = returnType == null ? Kind.Void : returnType.getKind();
-        AllocatableValue returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(returnKind);
+        AllocatableValue returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : getReturnRegister(returnKind, type).asValue(returnKind);
         return new CallingConvention(currentStackOffset, returnLocation, locations);
     }
 
     @Override
     public Register getReturnRegister(Kind kind) {
+        return getReturnRegister(kind, Type.JavaCallee);
+    }
+
+    private static Register getReturnRegister(Kind kind, Type type) {
         switch (kind) {
             case Boolean:
             case Byte:
@@ -216,7 +222,7 @@
             case Int:
             case Long:
             case Object:
-                return i0;
+                return type == Type.JavaCallee ? i0 : o0;
             case Float:
             case Double:
                 return f0;
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCSafepointOp.java	Wed Jul 24 16:19:17 2013 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCSafepointOp.java	Wed Jul 24 17:57:52 2013 -0700
@@ -31,7 +31,6 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.sparc.*;
 import com.oracle.graal.lir.asm.*;
@@ -62,7 +61,6 @@
         final int offset = SafepointPollOffset.getValue() % unsafe.pageSize();
         Register scratch = ((RegisterValue) temp).getRegister();
         new Setx(config.safepointPollingAddress + offset, scratch).emit(masm);
-        tasm.recordMark(config.isPollingPageFar ? Marks.MARK_POLL_FAR : Marks.MARK_POLL_NEAR);
         tasm.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
         new Ldx(new SPARCAddress(scratch, 0), g0).emit(masm);
     }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Wed Jul 24 16:19:17 2013 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Wed Jul 24 17:57:52 2013 -0700
@@ -23,36 +23,11 @@
 package com.oracle.graal.lir.sparc;
 
 import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.*;
+import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Add;
-import com.oracle.graal.asm.sparc.SPARCAssembler.And;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Faddd;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fadds;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fdivd;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fdivs;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fdtoi;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fmuld;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fmuls;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fnegd;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fnegs;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fstoi;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fsubd;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Fsubs;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Mulx;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Or;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Sdivx;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Sll;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Sllx;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Sra;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Srax;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Srl;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Srlx;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Sub;
-import com.oracle.graal.asm.sparc.SPARCAssembler.Xor;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
@@ -323,9 +298,17 @@
                     assert isSimm13(tasm.asIntConst(src2));
                     new Mulx(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm);
                     break;
+                case LAND:
+                    assert isSimm13(tasm.asIntConst(src2));
+                    new And(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm);
+                    break;
+                case LOR:
+                    assert isSimm13(tasm.asIntConst(src2));
+                    new Or(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm);
+                    break;
                 case LXOR:
                     assert isSimm13(tasm.asIntConst(src2));
-                    new Add(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm);
+                    new Xor(asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)).emit(masm);
                     break;
                 case LSHL:
                     assert isSimm13(tasm.asIntConst(src2));
@@ -457,6 +440,9 @@
         int exceptionOffset = -1;
         if (isRegister(src)) {
             switch (opcode) {
+                case INEG:
+                    new Neg(asIntReg(src), asIntReg(dst)).emit(masm);
+                    break;
                 case I2L:
                     new Sra(asIntReg(src), 0, asLongReg(dst)).emit(masm);
                     break;
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java	Wed Jul 24 16:19:17 2013 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java	Wed Jul 24 17:57:52 2013 -0700
@@ -32,7 +32,6 @@
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
-import com.oracle.graal.nodes.spi.*;
 
 public class SPARCCall {
 
@@ -53,7 +52,9 @@
 
         @Override
         public boolean destroysCallerSavedRegisters() {
-            return true;
+            // On SPARC we never destroy caller saved registers since they are automatically saved
+            // in the register window.
+            return false;
         }
     }
 
@@ -114,7 +115,9 @@
 
         @Override
         public boolean destroysCallerSavedRegisters() {
-            return callTarget.destroysRegisters();
+            // On SPARC we never destroy caller saved registers since they are automatically saved
+            // in the register window.
+            return false;
         }
     }
 
@@ -134,16 +137,13 @@
     @Opcode("FAR_FOREIGN_CALL")
     public static class DirectFarForeignCallOp extends ForeignCallOp {
 
-        @Temp({REG}) protected AllocatableValue callTemp;
-
-        public DirectFarForeignCallOp(LIRGeneratorTool gen, ForeignCallLinkage callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) {
+        public DirectFarForeignCallOp(ForeignCallLinkage callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) {
             super(callTarget, result, parameters, temps, state);
-            callTemp = gen.newVariable(Kind.Long);
         }
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-            directCall(tasm, masm, callTarget, ((RegisterValue) callTemp).getRegister(), false, state);
+            directCall(tasm, masm, callTarget, o7, false, state);
         }
     }
 
@@ -156,14 +156,13 @@
             // offset might not fit a 30-bit displacement, generate an
             // indirect call with a 64-bit immediate
             new Sethix(0L, scratch, true).emit(masm);
-            new Jmpl(scratch, 0, r15).emit(masm);
+            new Jmpl(scratch, 0, o7).emit(masm);
         } else {
             new Call(0).emit(masm);
         }
         int after = masm.codeBuffer.position();
         tasm.recordDirectCall(before, after, callTarget, info);
         tasm.recordExceptionHandlers(after, info);
-// masm.ensureUniquePC();
         new Nop().emit(masm);  // delay slot
     }
 
@@ -173,17 +172,15 @@
         new Jmp(new SPARCAddress(dst, 0)).emit(masm);
         int after = masm.codeBuffer.position();
         tasm.recordIndirectCall(before, after, target, null);
-// masm.ensureUniquePC();
         new Nop().emit(masm);  // delay slot
     }
 
     public static void indirectCall(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Register dst, InvokeTarget callTarget, LIRFrameState info) {
         int before = masm.codeBuffer.position();
-        new Jmpl(dst, 0, r15).emit(masm);
+        new Jmpl(dst, 0, o7).emit(masm);
         int after = masm.codeBuffer.position();
         tasm.recordIndirectCall(before, after, callTarget, info);
         tasm.recordExceptionHandlers(after, info);
-// masm.ensureUniquePC();
         new Nop().emit(masm);  // delay slot
     }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Wed Jul 24 16:19:17 2013 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Wed Jul 24 17:57:52 2013 -0700
@@ -61,6 +61,9 @@
                 case NE:
                     new Bpne(CC.Xcc, destination.label()).emit(masm);
                     break;
+                case LT:
+                    new Bpl(CC.Xcc, destination.label()).emit(masm);
+                    break;
                 case BE:
                     new Bpleu(CC.Xcc, destination.label()).emit(masm);
                     break;
--- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp	Wed Jul 24 16:19:17 2013 -0700
+++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp	Wed Jul 24 17:57:52 2013 -0700
@@ -119,14 +119,11 @@
     call->set_destination((address) foreign_call_destination);
     _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec());
   } else if (inst->is_sethi()) {
-    NativeFarCall* call = nativeFarCall_at(pc);
-    call->set_destination((address) foreign_call_destination);
-    _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec());
+    NativeJump* jump = nativeJump_at(pc);
+    jump->set_jump_destination((address) foreign_call_destination);
+    _instructions->relocate(jump->instruction_address(), runtime_call_Relocation::spec());
   } else {
-    NativeJump* jump = nativeJump_at((address) (inst));
-    jump->set_jump_destination((address) foreign_call_destination);
-    _instructions->relocate((address)inst, runtime_call_Relocation::spec());
-    fatal("CodeInstaller::pd_relocate_ForeignCall - verify me!");
+    fatal(err_msg("unknown call or jump instruction at %p", pc));
   }
   TRACE_graal_3("relocating (foreign call) at %p", inst);
 }