Mercurial > hg > truffle
diff graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.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 | f2b300c6e621 |
children | c7c9624f8ca2 |
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java Thu Feb 20 14:42:01 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java Fri Feb 21 11:53:48 2014 +0100 @@ -25,6 +25,7 @@ import java.util.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.calc.*; /** * Helper class that is used to keep all stamp-related operations in one place. @@ -178,15 +179,15 @@ lowerBound = (stamp1.lowerBound() + stamp2.lowerBound()) & defaultMask; upperBound = (stamp1.upperBound() + stamp2.upperBound()) & defaultMask; if (!unsigned) { - lowerBound = signExtend(lowerBound, bits); - upperBound = signExtend(upperBound, bits); + lowerBound = SignExtendNode.signExtend(lowerBound, bits); + upperBound = SignExtendNode.signExtend(upperBound, bits); } } IntegerStamp limit = StampFactory.forInteger(bits, unsigned, lowerBound, upperBound); newUpMask &= limit.upMask(); upperBound &= newUpMask; if (!unsigned) { - upperBound = signExtend(upperBound, bits); + upperBound = SignExtendNode.signExtend(upperBound, bits); } newDownMask |= limit.downMask(); lowerBound |= newDownMask; @@ -213,6 +214,8 @@ lowerBound = downMask | (-1L << (bits - 1)); upperBound = IntegerStamp.defaultMaxValue(bits, false) & upMask; } + lowerBound = IntegerConvertNode.convert(lowerBound, bits, false); + upperBound = IntegerConvertNode.convert(upperBound, bits, false); return new IntegerStamp(bits, false, lowerBound, upperBound, downMask, upMask); } @@ -316,16 +319,85 @@ return value.unrestricted(); } + public static Stamp signExtend(Stamp input, int resultBits) { + if (input instanceof IntegerStamp) { + IntegerStamp inputStamp = (IntegerStamp) input; + int inputBits = inputStamp.getBits(); + assert inputBits <= resultBits; + + long defaultMask = IntegerStamp.defaultMask(resultBits); + long downMask = SignExtendNode.signExtend(inputStamp.downMask(), inputBits) & defaultMask; + long upMask = SignExtendNode.signExtend(inputStamp.upMask(), inputBits) & defaultMask; + + return new IntegerStamp(resultBits, inputStamp.isUnsigned(), inputStamp.lowerBound(), inputStamp.upperBound(), downMask, upMask); + } else { + return input.illegal(); + } + } + + public static Stamp zeroExtend(Stamp input, int resultBits) { + if (input instanceof IntegerStamp) { + IntegerStamp inputStamp = (IntegerStamp) input; + int inputBits = inputStamp.getBits(); + assert inputBits <= resultBits; + + long downMask = ZeroExtendNode.zeroExtend(inputStamp.downMask(), inputBits); + long upMask = ZeroExtendNode.zeroExtend(inputStamp.upMask(), inputBits); + + return new IntegerStamp(resultBits, inputStamp.isUnsigned(), inputStamp.lowerBound(), inputStamp.upperBound(), downMask, upMask); + } else { + return input.illegal(); + } + } + public static Stamp intToLong(IntegerStamp intStamp) { long downMask = intStamp.downMask(); long upMask = intStamp.upMask(); if (!intStamp.isUnsigned()) { - downMask = signExtend(downMask, intStamp.getBits()); - upMask = signExtend(upMask, intStamp.getBits()); + downMask = SignExtendNode.signExtend(downMask, intStamp.getBits()); + upMask = SignExtendNode.signExtend(upMask, intStamp.getBits()); } return new IntegerStamp(64, intStamp.isUnsigned(), intStamp.lowerBound(), intStamp.upperBound(), downMask, upMask); } + public static Stamp narrowingConversion(Stamp input, int resultBits) { + if (input instanceof IntegerStamp) { + IntegerStamp inputStamp = (IntegerStamp) input; + boolean unsigned = inputStamp.isUnsigned(); + int inputBits = inputStamp.getBits(); + assert resultBits <= inputBits; + if (resultBits == inputBits) { + return inputStamp; + } + + final long upperBound; + if (inputStamp.lowerBound() < IntegerStamp.defaultMinValue(resultBits, unsigned)) { + upperBound = IntegerStamp.defaultMaxValue(resultBits, unsigned); + } else { + upperBound = saturate(inputStamp.upperBound(), resultBits, unsigned); + } + final long lowerBound; + if (inputStamp.upperBound() > IntegerStamp.defaultMaxValue(resultBits, unsigned)) { + lowerBound = IntegerStamp.defaultMinValue(resultBits, unsigned); + } else { + lowerBound = saturate(inputStamp.lowerBound(), resultBits, unsigned); + } + + long defaultMask = IntegerStamp.defaultMask(resultBits); + long newDownMask = inputStamp.downMask() & defaultMask; + long newUpMask = inputStamp.upMask() & defaultMask; + long newLowerBound = (lowerBound | newDownMask) & newUpMask; + long newUpperBound = (upperBound | newDownMask) & newUpMask; + if (!unsigned) { + newLowerBound = SignExtendNode.signExtend(newLowerBound, resultBits); + newUpperBound = SignExtendNode.signExtend(newUpperBound, resultBits); + } + return new IntegerStamp(resultBits, unsigned, newLowerBound, newUpperBound, newDownMask, newUpMask); + } else { + return input.illegal(); + } + } + public static IntegerStamp narrowingKindConversion(IntegerStamp fromStamp, Kind toKind) { assert toKind == Kind.Byte || toKind == Kind.Char || toKind == Kind.Short || toKind == Kind.Int; final long upperBound; @@ -348,14 +420,6 @@ return new IntegerStamp(toKind.getStackKind().getBitCount(), false, (int) ((lowerBound | newDownMask) & newUpMask), (int) ((upperBound | newDownMask) & newUpMask), newDownMask, newUpMask); } - private static long signExtend(long value, int bits) { - if (bits < 64 && (value >>> (bits - 1) & 1) == 1) { - return value | (-1L << bits); - } else { - return value; - } - } - private static long signExtend(long value, Kind valueKind) { if (valueKind != Kind.Char && valueKind != Kind.Long && (value >>> (valueKind.getBitCount() - 1) & 1) == 1) { return value | (-1L << valueKind.getBitCount()); @@ -364,7 +428,21 @@ } } - public static long saturate(long v, Kind kind) { + private static long saturate(long v, int bits, boolean unsigned) { + if (bits < 64) { + long max = IntegerStamp.defaultMaxValue(bits, unsigned); + if (v > max) { + return max; + } + long min = IntegerStamp.defaultMinValue(bits, unsigned); + if (v < min) { + return min; + } + } + return v; + } + + private static long saturate(long v, Kind kind) { long max = kind.getMaxValue(); if (v > max) { return max;