changeset 21136:8722ffa310d0

[SPARC] Fix comparebranch with sub-int types
author Stefan Anzinger <stefan.anzinger@oracle.com>
date Tue, 28 Apr 2015 18:07:08 +0200
parents 48bfffd96d94
children fb2b27418347
files graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_ifeq.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java
diffstat 3 files changed, 128 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue Apr 28 18:04:28 2015 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue Apr 28 18:07:08 2015 +0200
@@ -90,6 +90,10 @@
     @Override
     public boolean canInlineConstant(JavaConstant c) {
         switch (c.getKind()) {
+            case Boolean:
+            case Byte:
+            case Char:
+            case Short:
             case Int:
                 return SPARCAssembler.isSimm13(c.asInt()) && !getCodeCache().needsDataPatch(c);
             case Long:
@@ -217,7 +221,7 @@
     @Override
     public void emitCompareBranch(PlatformKind cmpKind, Value x, Value y, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination,
                     double trueDestinationProbability) {
-        Variable left;
+        Value left;
         Value right;
         Condition actualCondition;
         if (isConstant(x)) {
@@ -230,8 +234,20 @@
             actualCondition = cond;
         }
         SPARCCompare opcode;
-        Kind kind = left.getKind().getStackKind();
-        switch (kind) {
+        Kind actualCmpKind = (Kind) cmpKind;
+        switch (actualCmpKind) {
+            case Byte:
+                left = emitSignExtend(left, 8, 32);
+                right = emitSignExtend(right, 8, 32);
+                actualCmpKind = Kind.Int;
+                opcode = ICMP;
+                break;
+            case Short:
+                left = emitSignExtend(left, 16, 32);
+                right = emitSignExtend(right, 16, 32);
+                actualCmpKind = Kind.Int;
+                opcode = ICMP;
+                break;
             case Object:
                 opcode = ACMP;
                 break;
@@ -239,9 +255,6 @@
                 opcode = LCMP;
                 break;
             case Int:
-            case Short:
-            case Char:
-            case Byte:
                 opcode = ICMP;
                 break;
             case Float:
@@ -251,9 +264,9 @@
                 opcode = DCMP;
                 break;
             default:
-                throw GraalInternalError.shouldNotReachHere(kind.toString());
+                throw GraalInternalError.shouldNotReachHere(actualCmpKind.toString());
         }
-        append(new SPARCControlFlow.CompareBranchOp(opcode, left, right, actualCondition, trueDestination, falseDestination, kind, unorderedIsTrue, trueDestinationProbability));
+        append(new SPARCControlFlow.CompareBranchOp(opcode, left, right, actualCondition, trueDestination, falseDestination, actualCmpKind, unorderedIsTrue, trueDestinationProbability));
     }
 
     @Override
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_ifeq.java	Tue Apr 28 18:04:28 2015 +0200
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_ifeq.java	Tue Apr 28 18:07:08 2015 +0200
@@ -55,4 +55,101 @@
         runTest("test", 1);
     }
 
+    @Test
+    public void run3() {
+        runTest("testb", 0xff);
+    }
+
+    /**
+     * Tests if the if does work properly on byte stamp.
+     */
+    public static int testb(int b) {
+        byte x = (byte) b;
+        int y = x & 0xff;
+        if (y == 0xff) {
+            // Just do anything else to force jump instead of conditional move
+            y = (int) (System.currentTimeMillis() >> 32);
+        }
+        return y;
+    }
+
+    @Test
+    public void run4() {
+        runTest("tests", 0xffff);
+    }
+
+    /**
+     * Tests if the if does work properly on short stamp.
+     */
+    public static int tests(int b) {
+        short x = (short) b;
+        int y = x & 0xffff;
+        if (y == 0xffff) {
+            // Just do anything else to force jump instead of conditional move
+            y = (int) (System.currentTimeMillis() >> 32);
+        }
+        return y;
+    }
+
+    @Test
+    public void run5() {
+        runTest("testc", 0xffff);
+    }
+
+    /**
+     * Tests if the if does work properly on char stamp (boils down to short, just to cover all the
+     * java types).
+     */
+    public static int testc(int b) {
+        char x = (char) b;
+        int y = x & 0xffff;
+        if (y == 0xffff) {
+            // Just do anything else to force jump instead of conditional move
+            y = (int) (System.currentTimeMillis() >> 32);
+        }
+        return y;
+    }
+
+    // the same with conditional move
+    @Test
+    public void run6() {
+        runTest("testCondb", 0xff);
+    }
+
+    /**
+     * Tests if the if does work properly on byte stamp.
+     */
+    public static boolean testCondb(int b) {
+        byte x = (byte) b;
+        int y = x & 0xff;
+        return y == 0xff;
+    }
+
+    @Test
+    public void run7() {
+        runTest("testConds", 0xffff);
+    }
+
+    /**
+     * Tests if the if does work properly on short stamp.
+     */
+    public static boolean testConds(int b) {
+        short x = (short) b;
+        int y = x & 0xffff;
+        return y == 0xffff;
+    }
+
+    @Test
+    public void run8() {
+        runTest("testCondc", 0xffff);
+    }
+
+    /**
+     * Tests if the if does work properly on char type.
+     */
+    public static boolean testCondc(int b) {
+        char x = (char) b;
+        int y = x & 0xffff;
+        return y == 0xffff;
+    }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Tue Apr 28 18:04:28 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Tue Apr 28 18:07:08 2015 +0200
@@ -31,6 +31,8 @@
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 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.asm.*;
@@ -75,6 +77,7 @@
 
     public static final class CompareBranchOp extends SPARCLIRInstruction implements BlockEndOp, SPARCDelayedControlTransfer {
         public static final LIRInstructionClass<CompareBranchOp> TYPE = LIRInstructionClass.create(CompareBranchOp.class);
+        private static final EnumSet<Kind> SUPPORTED_KINDS = EnumSet.of(Kind.Long, Kind.Int, Kind.Object, Kind.Float, Kind.Double);
 
         private final SPARCCompare opcode;
         @Use({REG}) protected Value x;
@@ -231,9 +234,6 @@
 
         private static void emitCBCond(SPARCMacroAssembler masm, Value actualX, Value actualY, Label actualTrueTarget, ConditionFlag conditionFlag) {
             switch ((Kind) actualX.getLIRKind().getPlatformKind()) {
-                case Byte:
-                case Char:
-                case Short:
                 case Int:
                     if (isConstant(actualY)) {
                         int constantY = asConstant(actualY).asInt();
@@ -269,9 +269,6 @@
                 return false;
             }
             switch ((Kind) x.getPlatformKind()) {
-                case Byte:
-                case Char:
-                case Short:
                 case Int:
                 case Long:
                 case Object:
@@ -319,6 +316,13 @@
             emitted = false;
             delaySlotPosition = -1;
         }
+
+        @Override
+        public void verify() {
+            super.verify();
+            assert SUPPORTED_KINDS.contains(kind) : kind;
+            assert x.getKind().equals(kind) && y.getKind().equals(kind) : x + " " + y;
+        }
     }
 
     public static final class BranchOp extends SPARCLIRInstruction implements StandardOp.BranchOp {