37 */ 38 @NodeInfo 39 public class BitScanForwardNode extends UnaryNode implements LIRLowerable { 40 41 public static BitScanForwardNode create(ValueNode value) { 42 return new BitScanForwardNode(value); 43 } 44 45 protected BitScanForwardNode(ValueNode value) { 46 super(StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value); 47 assert value.getKind() == Kind.Int || value.getKind() == Kind.Long; 48 } 49 50 @Override 51 public boolean inferStamp() { 52 IntegerStamp valueStamp = (IntegerStamp) getValue().stamp(); 53 int min; 54 int max; 55 long mask = CodeUtil.mask(valueStamp.getBits()); 56 int firstAlwaysSetBit = scan(valueStamp.downMask() & mask); 57 if (firstAlwaysSetBit == -1) { 58 int lastMaybeSetBit = BitScanReverseNode.scan(valueStamp.upMask() & mask); 59 min = -1; 60 max = lastMaybeSetBit; 61 } else { 62 int firstMaybeSetBit = scan(valueStamp.upMask() & mask); 63 min = firstMaybeSetBit; 64 max = firstAlwaysSetBit; 65 } 66 return updateStamp(StampFactory.forInteger(Kind.Int, min, max)); 67 } 68 69 @Override 70 public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { 71 if (forValue.isConstant()) { 72 JavaConstant c = forValue.asJavaConstant(); 73 if (c.asLong() != 0) { 74 return ConstantNode.forInt(forValue.getKind() == Kind.Int ? scan(c.asInt()) : scan(c.asLong())); 75 } 76 } 77 return this; 78 } 79 80 /** 81 * Utility method with defined return value for 0. 82 * | 37 */ 38 @NodeInfo 39 public class BitScanForwardNode extends UnaryNode implements LIRLowerable { 40 41 public static BitScanForwardNode create(ValueNode value) { 42 return new BitScanForwardNode(value); 43 } 44 45 protected BitScanForwardNode(ValueNode value) { 46 super(StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value); 47 assert value.getKind() == Kind.Int || value.getKind() == Kind.Long; 48 } 49 50 @Override 51 public boolean inferStamp() { 52 IntegerStamp valueStamp = (IntegerStamp) getValue().stamp(); 53 int min; 54 int max; 55 long mask = CodeUtil.mask(valueStamp.getBits()); 56 int firstAlwaysSetBit = scan(valueStamp.downMask() & mask); 57 int firstMaybeSetBit = scan(valueStamp.upMask() & mask); 58 if (firstAlwaysSetBit == -1) { 59 int lastMaybeSetBit = BitScanReverseNode.scan(valueStamp.upMask() & mask); 60 min = firstMaybeSetBit; 61 max = lastMaybeSetBit; 62 } else { 63 min = firstMaybeSetBit; 64 max = firstAlwaysSetBit; 65 } 66 return updateStamp(StampFactory.forInteger(Kind.Int, min, max)); 67 } 68 69 @Override 70 public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { 71 if (forValue.isConstant()) { 72 JavaConstant c = forValue.asJavaConstant(); 73 if (c.asLong() != 0) { 74 return ConstantNode.forInt(forValue.getKind() == Kind.Int ? scan(c.asInt()) : scan(c.asLong())); 75 } 76 } 77 return this; 78 } 79 80 /** 81 * Utility method with defined return value for 0. 82 * |