diff graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java @ 14000:958c99d0790c

Split convert node into separate nodes for different conversions.
author Roland Schatz <roland.schatz@oracle.com>
date Fri, 21 Feb 2014 11:53:48 +0100
parents faa6fda7ee36
children 0c38906450a0
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Thu Feb 20 14:42:01 2014 +0100
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Fri Feb 21 11:53:48 2014 +0100
@@ -60,7 +60,9 @@
 import com.oracle.graal.lir.sparc.SPARCMove.StackLoadAddressOp;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.calc.FloatConvertNode.FloatConvert;
 import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.util.*;
 
 /**
@@ -153,8 +155,7 @@
                 indexRegister = Value.ILLEGAL;
             } else {
                 if (scale != 1) {
-                    // Variable longIndex = newVariable(Kind.Long);
-                    AllocatableValue longIndex = emitConvert(Kind.Int, Kind.Long, index);
+                    Value longIndex = emitSignExtend(index, 32, 64);
                     if (CodeUtil.isPowerOf2(scale)) {
                         indexRegister = emitShl(longIndex, Constant.forLong(CodeUtil.log2(scale)));
                     } else {
@@ -766,108 +767,98 @@
     }
 
     @Override
-    public AllocatableValue emitConvert(Kind from, Kind to, Value inputVal) {
-        assert inputVal.getKind() == from.getStackKind();
+    public Value emitFloatConvert(FloatConvert op, Value inputVal) {
+        AllocatableValue input = asAllocatable(inputVal);
+        switch (op) {
+            case D2F:
+                return emitConvert2Op(Kind.Float, D2F, input);
+            case D2I:
+                return emitConvert2Op(Kind.Int, D2I, input);
+            case D2L:
+                return emitConvert2Op(Kind.Long, D2L, input);
+            case F2D:
+                return emitConvert2Op(Kind.Double, F2D, input);
+            case F2I:
+                return emitConvert2Op(Kind.Int, F2I, input);
+            case F2L:
+                return emitConvert2Op(Kind.Long, F2L, input);
+            case I2D:
+                return emitConvert2Op(Kind.Double, I2D, input);
+            case I2F:
+                return emitConvert2Op(Kind.Float, I2F, input);
+            case L2D:
+                return emitConvert2Op(Kind.Double, L2D, input);
+            case L2F:
+                return emitConvert2Op(Kind.Float, L2F, input);
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
 
-        AllocatableValue input = asAllocatable(inputVal);
-        if (from == to) {
-            return input;
+    @Override
+    public Value emitNarrow(Value inputVal, int bits) {
+        if (inputVal.getKind() == Kind.Long && bits <= 32) {
+            return emitConvert2Op(Kind.Int, L2I, asAllocatable(inputVal));
+        } else {
+            return inputVal;
         }
-        switch (to) {
-            case Byte:
-                switch (from) {
-                    case Short:
-                    case Char:
-                    case Int:
-                    case Long:
-                        return emitConvert2Op(to, I2B, input);
-                    case Float:
-                    case Double:
-                        AllocatableValue intVal = emitConvert(from, Kind.Int, inputVal);
-                        return emitConvert(Kind.Int, to, intVal);
-                }
-                break;
-            case Char:
-                switch (from) {
-                    case Byte:
-                    case Short:
-                    case Int:
-                    case Long:
-                        return emitConvert2Op(to, I2C, input);
-                    case Float:
-                    case Double:
-                        AllocatableValue intVal = emitConvert(from, Kind.Int, inputVal);
-                        return emitConvert(Kind.Int, to, intVal);
-                }
-                break;
-            case Short:
-                switch (from) {
-                    case Byte:
-                    case Char:
-                    case Int:
-                    case Long:
-                        return emitConvert2Op(to, I2S, input);
-                    case Float:
-                    case Double:
-                        AllocatableValue intVal = emitConvert(from, Kind.Int, inputVal);
-                        return emitConvert(Kind.Int, to, intVal);
-                }
-                break;
-            case Int:
-                switch (from) {
-                    case Byte:
-                    case Short:
-                    case Char:
-                        return emitConvertMove(to, input);
-                    case Long:
-                        return emitConvert2Op(to, L2I, input);
-                    case Float:
-                        return emitConvert2Op(to, F2I, input);
-                    case Double:
-                        return emitConvert2Op(to, D2I, input);
-                }
-                break;
-            case Long:
-                switch (from) {
-                    case Byte:
-                    case Short:
-                    case Char:
-                    case Int:
-                        return emitConvert2Op(to, I2L, input);
-                    case Float:
-                        return emitConvert2Op(to, F2L, input);
-                    case Double:
-                        return emitConvert2Op(to, D2L, input);
-                }
-                break;
-            case Float:
-                switch (from) {
-                    case Byte:
-                    case Short:
-                    case Char:
-                    case Int:
-                        return emitConvert2Op(to, I2F, input);
-                    case Long:
-                        return emitConvert2Op(to, L2F, input);
-                    case Double:
-                        return emitConvert2Op(to, D2F, input);
-                }
-                break;
-            case Double:
-                switch (from) {
-                    case Byte:
-                    case Short:
-                    case Char:
-                    case Int:
-                        return emitConvert2Op(to, I2D, input);
-                    case Long:
-                        return emitConvert2Op(to, L2D, input);
-                    case Float:
-                        return emitConvert2Op(to, F2D, input);
-                }
-                break;
+    }
+
+    @Override
+    public Value emitSignExtend(Value inputVal, int fromBits, int toBits) {
+        assert fromBits <= toBits && toBits <= 64;
+        if (fromBits == toBits) {
+            return inputVal;
+        } else if (toBits > 32) {
+            // sign extend to 64 bits
+            if (fromBits == 32) {
+                return emitConvert2Op(Kind.Long, I2L, asAllocatable(inputVal));
+            } else if (fromBits < 32) {
+                // TODO implement direct x2L sign extension conversions
+                Value intVal = emitSignExtend(inputVal, fromBits, 32);
+                return emitSignExtend(intVal, 32, toBits);
+            } else {
+                throw GraalInternalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
+            }
+        } else {
+            // sign extend to 32 bits (smaller values are internally represented as 32 bit values)
+            switch (fromBits) {
+                case 8:
+                    return emitConvert2Op(Kind.Int, I2B, asAllocatable(inputVal));
+                case 16:
+                    return emitConvert2Op(Kind.Int, I2S, asAllocatable(inputVal));
+                case 32:
+                    return inputVal;
+                default:
+                    throw GraalInternalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
+            }
         }
-        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    @Override
+    public Value emitZeroExtend(Value inputVal, int fromBits, int toBits) {
+        assert fromBits <= toBits && toBits <= 64;
+        if (fromBits == toBits) {
+            return inputVal;
+        } else if (fromBits > 32) {
+            assert inputVal.getKind() == Kind.Long;
+            Variable result = newVariable(Kind.Long);
+            long mask = IntegerStamp.defaultMask(fromBits);
+            append(new BinaryRegConst(SPARCArithmetic.LAND, result, asAllocatable(inputVal), Constant.forLong(mask)));
+            return result;
+        } else {
+            assert inputVal.getKind() == Kind.Int;
+            Variable result = newVariable(Kind.Int);
+            int mask = (int) IntegerStamp.defaultMask(fromBits);
+            append(new BinaryRegConst(SPARCArithmetic.IAND, result, asAllocatable(inputVal), Constant.forInt(mask)));
+            if (toBits > 32) {
+                Variable longResult = newVariable(Kind.Long);
+                emitMove(longResult, result);
+                return longResult;
+            } else {
+                return result;
+            }
+        }
     }
 
     public AllocatableValue emitReinterpret(Kind to, Value inputVal) {