changeset 16592:8084d44c78d3

don't allow bsr to be used outside of intrinsics
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Thu, 24 Jul 2014 12:22:54 -0700
parents 86eee6794713
children ba48a694e4c1 618d92152d3c
files graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/IntegerSubstitutions.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/LongSubstitutions.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java
diffstat 4 files changed, 77 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/IntegerSubstitutions.java	Wed Jul 23 17:39:26 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/IntegerSubstitutions.java	Thu Jul 24 12:22:54 2014 -0700
@@ -39,7 +39,7 @@
         if (i == 0) {
             return 32;
         }
-        return 31 - BitScanReverseNode.scan(i);
+        return 31 - BitScanReverseNode.unsafeScan(i);
     }
 
     @MethodSubstitution
@@ -47,7 +47,7 @@
         if (i == 0) {
             return 32;
         }
-        return BitScanForwardNode.scan(i);
+        return BitScanForwardNode.unsafeScan(i);
     }
 
     @MethodSubstitution
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/LongSubstitutions.java	Wed Jul 23 17:39:26 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/LongSubstitutions.java	Thu Jul 24 12:22:54 2014 -0700
@@ -39,7 +39,7 @@
         if (i == 0) {
             return 64;
         }
-        return 63 - BitScanReverseNode.scan(i);
+        return 63 - BitScanReverseNode.unsafeScan(i);
     }
 
     @MethodSubstitution
@@ -47,7 +47,7 @@
         if (i == 0) {
             return 64;
         }
-        return BitScanForwardNode.scan(i);
+        return BitScanForwardNode.unsafeScan(i);
     }
 
     @MethodSubstitution
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java	Wed Jul 23 17:39:26 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java	Thu Jul 24 12:22:54 2014 -0700
@@ -63,27 +63,53 @@
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
         if (forValue.isConstant()) {
             Constant c = forValue.asConstant();
-            return ConstantNode.forInt(forValue.getKind() == Kind.Int ? scan(c.asInt()) : scan(c.asLong()));
+            if (c.asLong() != 0) {
+                return ConstantNode.forInt(forValue.getKind() == Kind.Int ? scan(c.asInt()) : scan(c.asLong()));
+            }
         }
         return this;
     }
 
-    @NodeIntrinsic
+    /**
+     * Utility method with defined return value for 0.
+     *
+     * @param v
+     * @return number of trailing zeros or -1 if {@code v} == 0.
+     */
     public static int scan(long v) {
         if (v == 0) {
             return -1;
         }
-        int index = 0;
-        while (((1L << index) & v) == 0) {
-            ++index;
-        }
-        return index;
+        return Long.numberOfTrailingZeros(v);
+    }
+
+    /**
+     * Utility method with defined return value for 0.
+     *
+     * @param v
+     * @return number of trailing zeros or -1 if {@code v} == 0.
+     */
+    public static int scan(int v) {
+        return scan(0xffffffffL & v);
     }
 
+    /**
+     * Raw intrinsic for bsf instruction.
+     *
+     * @param v
+     * @return number of trailing zeros or an undefined value if {@code v} == 0.
+     */
     @NodeIntrinsic
-    public static int scan(int v) {
-        return scan(v & 0xFFFFFFFFL);
-    }
+    public static native int unsafeScan(long v);
+
+    /**
+     * Raw intrinsic for bsf instruction.
+     *
+     * @param v
+     * @return number of trailing zeros or an undefined value if {@code v} == 0.
+     */
+    @NodeIntrinsic
+    public static native int unsafeScan(int v);
 
     @Override
     public void generate(NodeLIRBuilderTool gen) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java	Wed Jul 23 17:39:26 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java	Thu Jul 24 12:22:54 2014 -0700
@@ -61,34 +61,50 @@
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
         if (forValue.isConstant()) {
             Constant c = forValue.asConstant();
-            return ConstantNode.forInt(forValue.getKind() == Kind.Int ? scan(c.asInt()) : scan(c.asLong()));
+            if (c.asLong() != 0) {
+                return ConstantNode.forInt(forValue.getKind() == Kind.Int ? scan(c.asInt()) : scan(c.asLong()));
+            }
         }
         return this;
     }
 
-    @NodeIntrinsic
-    public static int scan(int v) {
-        if (v == 0) {
-            return -1;
-        }
-        int index = 31;
-        while (((1 << index) & v) == 0) {
-            --index;
-        }
-        return index;
+    /**
+     * Utility method with defined return value for 0.
+     *
+     * @param v
+     * @return index of first set bit or -1 if {@code v} == 0.
+     */
+    public static int scan(long v) {
+        return 63 - Long.numberOfLeadingZeros(v);
     }
 
+    /**
+     * Utility method with defined return value for 0.
+     *
+     * @param v
+     * @return index of first set bit or -1 if {@code v} == 0.
+     */
+    public static int scan(int v) {
+        return 31 - Integer.numberOfLeadingZeros(v);
+    }
+
+    /**
+     * Raw intrinsic for bsr instruction.
+     *
+     * @param v
+     * @return index of first set bit or an undefined value if {@code v} == 0.
+     */
     @NodeIntrinsic
-    public static int scan(long v) {
-        if (v == 0) {
-            return -1;
-        }
-        int index = 63;
-        while (((1L << index) & v) == 0) {
-            --index;
-        }
-        return index;
-    }
+    public static native int unsafeScan(int v);
+
+    /**
+     * Raw intrinsic for bsr instruction.
+     *
+     * @param v
+     * @return index of first set bit or an undefined value if {@code v} == 0.
+     */
+    @NodeIntrinsic
+    public static native int unsafeScan(long v);
 
     @Override
     public void generate(NodeLIRBuilderTool gen) {