Mercurial > hg > truffle
diff graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java @ 17344:98e60bdf6d05
Use ArithmeticOpTable for primitive convert operations.
author | Roland Schatz <roland.schatz@oracle.com> |
---|---|
date | Mon, 06 Oct 2014 11:51:32 +0200 |
parents | fa3637e235b1 |
children | 83c3dd41ca64 |
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java Mon Oct 06 10:40:55 2014 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java Mon Oct 06 11:51:32 2014 +0200 @@ -22,6 +22,9 @@ */ package com.oracle.graal.compiler.common.type; +import static com.oracle.graal.compiler.common.calc.FloatConvert.*; +import static com.oracle.graal.compiler.common.type.ArithmeticOpTable.IntegerConvertOp.*; + import java.util.*; import com.oracle.graal.api.code.*; @@ -29,6 +32,8 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.spi.*; import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.FloatConvertOp; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.IntegerConvertOp; import com.oracle.graal.compiler.common.type.ArithmeticOpTable.UnaryOp; /** @@ -350,6 +355,20 @@ return (x + y) ^ x ^ y; } + private static long saturate(long v, int bits) { + if (bits < 64) { + long max = CodeUtil.maxValue(bits); + if (v > max) { + return max; + } + long min = CodeUtil.minValue(bits); + if (v < min) { + return min; + } + } + return v; + } + public static final ArithmeticOpTable OPS = ArithmeticOpTable.create( new UnaryOp('-') { @@ -633,5 +652,153 @@ IntegerStamp stamp = (IntegerStamp) s; return Constant.forPrimitiveInt(stamp.getBits(), 0); } + }, + + new IntegerConvertOp(ZERO_EXTEND) { + + @Override + public Constant foldConstant(int inputBits, int resultBits, Constant value) { + return Constant.forPrimitiveInt(resultBits, CodeUtil.zeroExtend(value.asLong(), inputBits)); + } + + @Override + public Stamp foldStamp(int resultBits, Stamp input) { + IntegerStamp stamp = (IntegerStamp) input; + int inputBits = stamp.getBits(); + assert inputBits <= resultBits; + + long downMask = CodeUtil.zeroExtend(stamp.downMask(), inputBits); + long upMask = CodeUtil.zeroExtend(stamp.upMask(), inputBits); + + if (stamp.lowerBound() < 0 && stamp.upperBound() >= 0) { + // signed range including 0 and -1 + // after sign extension, the whole range from 0 to MAX_INT is possible + return IntegerStamp.stampForMask(resultBits, downMask, upMask); + } + + long lowerBound = CodeUtil.zeroExtend(stamp.lowerBound(), inputBits); + long upperBound = CodeUtil.zeroExtend(stamp.upperBound(), inputBits); + + return new IntegerStamp(resultBits, lowerBound, upperBound, downMask, upMask); + } + }, + + new IntegerConvertOp(SIGN_EXTEND) { + + @Override + public Constant foldConstant(int inputBits, int resultBits, Constant value) { + return Constant.forPrimitiveInt(resultBits, CodeUtil.signExtend(value.asLong(), inputBits)); + } + + @Override + public Stamp foldStamp(int resultBits, Stamp input) { + IntegerStamp stamp = (IntegerStamp) input; + int inputBits = stamp.getBits(); + assert inputBits <= resultBits; + + long defaultMask = CodeUtil.mask(resultBits); + long downMask = CodeUtil.signExtend(stamp.downMask(), inputBits) & defaultMask; + long upMask = CodeUtil.signExtend(stamp.upMask(), inputBits) & defaultMask; + + return new IntegerStamp(resultBits, stamp.lowerBound(), stamp.upperBound(), downMask, upMask); + } + }, + + new IntegerConvertOp(NARROW) { + + @Override + public Constant foldConstant(int inputBits, int resultBits, Constant value) { + return Constant.forPrimitiveInt(resultBits, CodeUtil.narrow(value.asLong(), resultBits)); + } + + @Override + public Stamp foldStamp(int resultBits, Stamp input) { + IntegerStamp stamp = (IntegerStamp) input; + int inputBits = stamp.getBits(); + assert resultBits <= inputBits; + if (resultBits == inputBits) { + return stamp; + } + + final long upperBound; + if (stamp.lowerBound() < CodeUtil.minValue(resultBits)) { + upperBound = CodeUtil.maxValue(resultBits); + } else { + upperBound = saturate(stamp.upperBound(), resultBits); + } + final long lowerBound; + if (stamp.upperBound() > CodeUtil.maxValue(resultBits)) { + lowerBound = CodeUtil.minValue(resultBits); + } else { + lowerBound = saturate(stamp.lowerBound(), resultBits); + } + + long defaultMask = CodeUtil.mask(resultBits); + long newDownMask = stamp.downMask() & defaultMask; + long newUpMask = stamp.upMask() & defaultMask; + long newLowerBound = CodeUtil.signExtend((lowerBound | newDownMask) & newUpMask, resultBits); + long newUpperBound = CodeUtil.signExtend((upperBound | newDownMask) & newUpMask, resultBits); + return new IntegerStamp(resultBits, newLowerBound, newUpperBound, newDownMask, newUpMask); + } + }, + + new FloatConvertOp(I2F) { + + @Override + public Constant foldConstant(Constant value) { + return Constant.forFloat(value.asInt()); + } + + @Override + public Stamp foldStamp(Stamp input) { + IntegerStamp stamp = (IntegerStamp) input; + assert stamp.getBits() == 32; + return StampFactory.forFloat(Kind.Float, stamp.lowerBound(), stamp.upperBound(), true); + } + }, + + new FloatConvertOp(L2F) { + + @Override + public Constant foldConstant(Constant value) { + return Constant.forFloat(value.asLong()); + } + + @Override + public Stamp foldStamp(Stamp input) { + IntegerStamp stamp = (IntegerStamp) input; + assert stamp.getBits() == 64; + return StampFactory.forFloat(Kind.Float, stamp.lowerBound(), stamp.upperBound(), true); + } + }, + + new FloatConvertOp(I2D) { + + @Override + public Constant foldConstant(Constant value) { + return Constant.forDouble(value.asInt()); + } + + @Override + public Stamp foldStamp(Stamp input) { + IntegerStamp stamp = (IntegerStamp) input; + assert stamp.getBits() == 32; + return StampFactory.forFloat(Kind.Double, stamp.lowerBound(), stamp.upperBound(), true); + } + }, + + new FloatConvertOp(L2D) { + + @Override + public Constant foldConstant(Constant value) { + return Constant.forDouble(value.asLong()); + } + + @Override + public Stamp foldStamp(Stamp input) { + IntegerStamp stamp = (IntegerStamp) input; + assert stamp.getBits() == 64; + return StampFactory.forFloat(Kind.Double, stamp.lowerBound(), stamp.upperBound(), true); + } }); }