changeset 13134:6217f601e65d

Allow addresses with an arbitrary scale value; fix handling of unsigned int-to-long conversion
author Christian Wimmer <christian.wimmer@oracle.com>
date Fri, 22 Nov 2013 12:19:16 -0800
parents dfb8de11d1bf
children c7ce697ddb9a
files graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java
diffstat 4 files changed, 36 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java	Fri Nov 22 12:18:36 2013 -0800
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java	Fri Nov 22 12:19:16 2013 -0800
@@ -70,6 +70,8 @@
         this.index = index;
         this.scale = scale;
         this.displacement = displacement;
+
+        assert scale != null;
     }
 
     /**
@@ -104,7 +106,7 @@
                 case 8:
                     return Times8;
                 default:
-                    throw new IllegalArgumentException(String.valueOf(scale));
+                    return null;
             }
         }
     }
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Fri Nov 22 12:18:36 2013 -0800
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Fri Nov 22 12:19:16 2013 -0800
@@ -164,6 +164,17 @@
             if (isConstant(index)) {
                 finalDisp += asConstant(index).asLong() * scale;
                 indexRegister = Value.ILLEGAL;
+
+            } else if (scaleEnum == null) {
+                /* Scale value that architecture cannot handle, so scale manually. */
+                Value longIndex = index.getKind().getStackKind() == Kind.Int ? emitConvert(Kind.Int, Kind.Long, index) : index;
+                if (CodeUtil.isPowerOf2(scale)) {
+                    indexRegister = emitShl(longIndex, Constant.forLong(CodeUtil.log2(scale)));
+                } else {
+                    indexRegister = emitMul(longIndex, Constant.forLong(scale));
+                }
+                scaleEnum = Scale.Times1;
+
             } else {
                 indexRegister = asAllocatable(index);
             }
@@ -812,7 +823,10 @@
         Kind from = inputVal.getKind();
         AllocatableValue input = asAllocatable(inputVal);
 
-        // These cases require a move between CPU and FPU registers:
+        /*
+         * Conversions between integer to floating point types require moves between CPU and FPU
+         * registers.
+         */
         switch (to) {
             case Int:
                 switch (from) {
@@ -826,6 +840,19 @@
                     case Float:
                     case Double:
                         return emitConvert2Op(to, MOV_D2L, input);
+                    case Int:
+                        /*
+                         * Unsigned int-to-long conversion: In theory, instructions that move or
+                         * generate 32-bit register values also set the upper 32 bits of the
+                         * register to zero. However, we cannot rely that the value was really
+                         * generated by an instruction, it could come from an untrusted source such
+                         * as native code. Therefore, make sure the high bits are really cleared.
+                         */
+                        Variable temp = newVariable(Kind.Int);
+                        Variable result = newVariable(Kind.Long);
+                        append(new BinaryRegConst(AMD64Arithmetic.IAND, temp, input, Constant.forInt(0xFFFFFFFF)));
+                        emitMove(result, temp);
+                        return result;
                 }
                 break;
             case Float:
@@ -843,12 +870,7 @@
                 }
                 break;
         }
-
-        // Otherwise, just emit an ordinary move instruction.
-        // 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.
-        return emitConvertMove(to, input);
+        throw GraalInternalError.shouldNotReachHere();
     }
 
     @Override
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java	Fri Nov 22 12:18:36 2013 -0800
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java	Fri Nov 22 12:19:16 2013 -0800
@@ -51,6 +51,8 @@
         this.index = index;
         this.scale = scale;
         this.displacement = displacement;
+
+        assert scale != null;
     }
 
     private static Register toRegister(AllocatableValue value) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Fri Nov 22 12:18:36 2013 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Fri Nov 22 12:19:16 2013 -0800
@@ -57,6 +57,8 @@
         this.negated = negated;
         this.condition = condition;
         this.reason = deoptReason;
+
+        assert action != null && reason != null;
     }
 
     public DeoptimizationReason getReason() {