# HG changeset patch # User Tom Rodriguez # Date 1406229774 25200 # Node ID 8084d44c78d3626f2400b251d4a2b6862f44489a # Parent 86eee67947137a429d087987c2878cf514c3c370 don't allow bsr to be used outside of intrinsics diff -r 86eee6794713 -r 8084d44c78d3 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/IntegerSubstitutions.java --- 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 diff -r 86eee6794713 -r 8084d44c78d3 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/LongSubstitutions.java --- 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 diff -r 86eee6794713 -r 8084d44c78d3 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java --- 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) { diff -r 86eee6794713 -r 8084d44c78d3 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java --- 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) {