changeset 16524:a08a58d0736b

[SPARC] Emit compareAndSwap for AtomicInteger and AtomicLong, Removing o7 register from usable ones, as this register is always overwritten, when using Call or JumpAndLink instructions in SPARC, even callee does not overwrite explicitly, implicit exception is defined when doing integer division, parameter constraint narrowed to only register on Unary2Op, Fix SPARCTestOp, as it did a compare instead of an and with condition codes
author Stefan Anzinger <stefan.anzinger@gmail.com>
date Tue, 15 Jul 2014 19:07:29 -0700
parents 2100f2ef49e6
children 072b9501f5f9
files 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/SPARCHotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java
diffstat 5 files changed, 31 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Mon Jul 14 05:15:33 2014 -0700
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue Jul 15 19:07:29 2014 -0700
@@ -230,10 +230,7 @@
             case Object:
                 append(new BranchOp(finalCondition, trueDestination, falseDestination, kind));
                 break;
-            // case Float:
-            // append(new CompareOp(FCMP, x, y));
-            // append(new BranchOp(condition, label));
-            // break;
+            case Float:
             case Double:
                 append(new BranchOp(cond, trueDestination, falseDestination, kind));
                 break;
@@ -294,7 +291,7 @@
      * @param b the right operand of the comparison
      * @return true if the left and right operands were switched, false otherwise
      */
-    private boolean emitCompare(Value a, Value b) {
+    protected boolean emitCompare(Value a, Value b) {
         Variable left;
         Value right;
         boolean mirrored;
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Mon Jul 14 05:15:33 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Tue Jul 15 19:07:29 2014 -0700
@@ -29,7 +29,9 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.compiler.common.calc.*;
 import com.oracle.graal.compiler.sparc.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
@@ -39,10 +41,9 @@
 import com.oracle.graal.lir.StandardOp.SaveRegistersOp;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.lir.sparc.*;
-import com.oracle.graal.lir.sparc.SPARCMove.LoadOp;
-import com.oracle.graal.lir.sparc.SPARCMove.NullCheckOp;
-import com.oracle.graal.lir.sparc.SPARCMove.StoreConstantOp;
-import com.oracle.graal.lir.sparc.SPARCMove.StoreOp;
+import com.oracle.graal.lir.sparc.SPARCCompare.CompareOp;
+import com.oracle.graal.lir.sparc.SPARCMove.*;
+import com.sun.nio.file.*;
 
 public class SPARCHotSpotLIRGenerator extends SPARCLIRGenerator implements HotSpotLIRGenerator {
 
@@ -189,8 +190,12 @@
     }
 
     public Value emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) {
-        // TODO Auto-generated method stub
-        throw GraalInternalError.unimplemented();
+        LIRKind kind = newValue.getLIRKind();
+        assert kind.equals(expectedValue.getLIRKind());
+        Kind memKind = (Kind) kind.getPlatformKind();
+        SPARCAddressValue addressValue = asAddressValue(address);
+        append(new CompareAndSwapOp(asAllocatable(addressValue), asAllocatable(expectedValue), asAllocatable(newValue)));
+        return emitConditionalMove(memKind, expectedValue, newValue, Condition.EQ, true, trueValue, falseValue);
     }
 
     public StackSlot getDeoptimizationRescueSlot() {
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Mon Jul 14 05:15:33 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Tue Jul 15 19:07:29 2014 -0700
@@ -110,7 +110,11 @@
             // @formatter:off
             registers = new Register[]{
                         // TODO this is not complete
-                        o0, o1, o2, o3, o4, o5, /*o6,*/ o7,
+                        // o7 cannot be used as register because it is always overwritten on call
+                        // and the current register handler would ignore this fact if the called
+                        // method still does not modify registers, in fact o7 is modified by the Call instruction
+                        // There would be some extra handlin necessary to be able to handle the o7 properly for local usage
+                        o0, o1, o2, o3, o4, o5, /*o6, o7,*/
                         l0, l1, l2, l3, l4, l5, l6, l7,
                         i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/
                         f0, f1, f2, f3, f4, f5, f6, f7
@@ -120,7 +124,7 @@
             // @formatter:off
             registers = new Register[]{
                         // TODO this is not complete
-                        o0, o1, o2, o3, o4, o5, /*o6,*/ o7,
+                        o0, o1, o2, o3, o4, o5, /*o6, o7,*/
                         l0, l1, l2, l3, l4, l5, l6, l7,
                         i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/
                         f0, f1, f2, f3, f4, f5, f6, f7
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Mon Jul 14 05:15:33 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Tue Jul 15 19:07:29 2014 -0700
@@ -56,7 +56,7 @@
 
         @Opcode private final SPARCArithmetic opcode;
         @Def({REG}) protected AllocatableValue result;
-        @Use({REG, STACK}) protected AllocatableValue x;
+        @Use({REG}) protected AllocatableValue x;
 
         public Unary2Op(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x) {
             this.opcode = opcode;
@@ -425,7 +425,7 @@
                     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 IAND:
@@ -712,7 +712,7 @@
         } else {
             switch (opcode) {
                 default:
-                    throw GraalInternalError.shouldNotReachHere("missing: " + opcode);
+                    throw GraalInternalError.shouldNotReachHere("missing: " + opcode + " " + src);
             }
         }
 
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java	Mon Jul 14 05:15:33 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java	Tue Jul 15 19:07:29 2014 -0700
@@ -24,6 +24,8 @@
 
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.*;
+import static com.oracle.graal.sparc.SPARC.*;
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
@@ -32,6 +34,7 @@
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.sparc.*;
 
 public class SPARCTestOp extends SPARCLIRInstruction {
 
@@ -48,10 +51,10 @@
         if (isRegister(y)) {
             switch (x.getKind()) {
                 case Int:
-                    new Cmp(asIntReg(x), asIntReg(y)).emit(masm);
+                    new Andcc(asIntReg(x), asIntReg(y), g0).emit(masm);
                     break;
                 case Long:
-                    new Cmp(asLongReg(x), asLongReg(y)).emit(masm);
+                    new Andcc(asLongReg(x), asLongReg(y), g0).emit(masm);
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
@@ -59,10 +62,10 @@
         } else if (isConstant(y)) {
             switch (x.getKind()) {
                 case Int:
-                    new Cmp(asIntReg(x), crb.asIntConst(y)).emit(masm);
+                    new Andcc(asIntReg(x), crb.asIntConst(y), g0).emit(masm);
                     break;
                 case Long:
-                    new Cmp(asLongReg(x), crb.asIntConst(y)).emit(masm);
+                    new Andcc(asLongReg(x), crb.asIntConst(y), g0).emit(masm);
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
@@ -71,11 +74,11 @@
             switch (x.getKind()) {
                 case Int:
                     new Ldsw((SPARCAddress) crb.asIntAddr(y), asIntReg(y)).emit(masm);
-                    new Cmp(asIntReg(x), 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 Cmp(asLongReg(x), asLongReg(y)).emit(masm);
+                    new Andcc(asLongReg(x), asLongReg(y), g0).emit(masm);
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();