changeset 12604:7328f7def427

Support more convert operations.
author Roland Schatz <roland.schatz@oracle.com>
date Fri, 25 Oct 2013 15:44:35 +0200
parents 2520c78e4c28
children b81405d42861
files graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java
diffstat 2 files changed, 110 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Fri Oct 25 14:45:01 2013 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Fri Oct 25 15:44:35 2013 +0200
@@ -690,19 +690,33 @@
         Variable input = load(inputVal);
         Variable result = newVariable(opcode.to);
         switch (opcode) {
+            case B2L:
+            case S2L:
+            case C2L:
+                // x2L == x2I . I2L
+                // since byte, short and char are stored as int in registers, x2I is a nop
             case I2L:
                 append(new Unary2Op(I2L, result, input));
                 break;
             case L2I:
                 append(new Unary1Op(L2I, result, input));
                 break;
+            case C2B:
+            case S2B:
             case I2B:
+            case L2B:
                 append(new Unary2Op(I2B, result, input));
                 break;
+            case B2C:
+            case S2C:
             case I2C:
+            case L2C:
                 append(new Unary1Op(I2C, result, input));
                 break;
+            case B2S:
+            case C2S:
             case I2S:
+            case L2S:
                 append(new Unary2Op(I2S, result, input));
                 break;
             case F2D:
@@ -751,6 +765,9 @@
                 // Instructions that move or generate 32-bit register values also set the upper 32
                 // bits of the register to zero.
                 // Consequently, there is no need for a special zero-extension move.
+            case B2I:
+            case C2I:
+            case S2I:
                 emitMove(result, input);
                 break;
             default:
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java	Fri Oct 25 14:45:01 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java	Fri Oct 25 15:44:35 2013 +0200
@@ -37,11 +37,27 @@
 public class ConvertNode extends FloatingNode implements Canonicalizable, Lowerable, ArithmeticLIRLowerable {
 
     public static enum Op {
+        // formatter:off
+        B2S(Byte, Short, true),
+        B2C(Byte, Char, true),
+        B2I(Byte, Int, true),
+        B2L(Byte, Long, true),
+        S2B(Short, Byte, false),
+        S2C(Short, Char, true),
+        S2I(Short, Int, true),
+        S2L(Short, Long, true),
+        C2B(Char, Byte, false),
+        C2S(Char, Short, true),
+        C2I(Char, Int, true),
+        C2L(Char, Long, true),
         I2L(Int, Long, true),
         L2I(Long, Int, false),
         I2B(Int, Byte, false),
         I2C(Int, Char, false),
         I2S(Int, Short, false),
+        L2B(Long, Byte, false),
+        L2C(Long, Char, false),
+        L2S(Long, Short, false),
         F2D(Float, Double, true),
         D2F(Double, Float, false),
         I2F(Int, Float, false),
@@ -57,6 +73,7 @@
         MOV_L2D(Long, Double, false),
         MOV_F2I(Float, Int, false),
         MOV_D2L(Double, Long, false);
+        // formatter:on
 
         public final Kind from;
         public final Kind to;
@@ -74,6 +91,45 @@
 
         public static Op getOp(Kind from, Kind to) {
             switch (from) {
+                case Byte:
+                    switch (to) {
+                        case Char:
+                            return B2C;
+                        case Short:
+                            return B2S;
+                        case Int:
+                            return B2I;
+                        case Long:
+                            return B2L;
+                        default:
+                            throw GraalInternalError.shouldNotReachHere();
+                    }
+                case Char:
+                    switch (to) {
+                        case Byte:
+                            return C2B;
+                        case Short:
+                            return C2S;
+                        case Int:
+                            return C2I;
+                        case Long:
+                            return C2L;
+                        default:
+                            throw GraalInternalError.shouldNotReachHere();
+                    }
+                case Short:
+                    switch (to) {
+                        case Byte:
+                            return S2B;
+                        case Char:
+                            return S2C;
+                        case Int:
+                            return S2I;
+                        case Long:
+                            return S2L;
+                        default:
+                            throw GraalInternalError.shouldNotReachHere();
+                    }
                 case Int:
                     switch (to) {
                         case Byte:
@@ -93,6 +149,12 @@
                     }
                 case Long:
                     switch (to) {
+                        case Byte:
+                            return L2B;
+                        case Char:
+                            return L2C;
+                        case Short:
+                            return L2S;
                         case Int:
                             return L2I;
                         case Float:
@@ -146,7 +208,7 @@
      */
     public ConvertNode(Op opcode, ValueNode value) {
         super(StampFactory.forKind(opcode.to.getStackKind()));
-        assert value.kind() == opcode.from : opcode + " : " + value.kind() + " != " + opcode.from;
+        assert value.kind() == opcode.from.getStackKind() : opcode + " : " + value.kind() + " != " + opcode.from;
         this.opcode = opcode;
         this.value = value;
     }
@@ -155,6 +217,30 @@
         assert inputs.length == 1;
         Constant c = inputs[0];
         switch (opcode) {
+            case B2C:
+                return Constant.forChar((char) (byte) c.asInt());
+            case B2S:
+                return Constant.forShort((byte) c.asInt());
+            case B2I:
+                return Constant.forInt((byte) c.asInt());
+            case B2L:
+                return Constant.forLong((byte) c.asInt());
+            case C2B:
+                return Constant.forByte((byte) (char) c.asInt());
+            case C2S:
+                return Constant.forShort((short) (char) c.asInt());
+            case C2I:
+                return Constant.forInt((char) c.asInt());
+            case C2L:
+                return Constant.forLong((char) c.asInt());
+            case S2B:
+                return Constant.forByte((byte) (short) c.asInt());
+            case S2C:
+                return Constant.forChar((char) (short) c.asInt());
+            case S2I:
+                return Constant.forInt((short) c.asInt());
+            case S2L:
+                return Constant.forLong((short) c.asInt());
             case I2L:
                 return Constant.forLong(c.asInt());
             case L2I:
@@ -165,6 +251,12 @@
                 return Constant.forChar((char) c.asInt());
             case I2S:
                 return Constant.forShort((short) c.asInt());
+            case L2B:
+                return Constant.forByte((byte) c.asLong());
+            case L2C:
+                return Constant.forChar((char) c.asLong());
+            case L2S:
+                return Constant.forShort((short) c.asLong());
             case F2D:
                 return Constant.forDouble(c.asFloat());
             case D2F: