107 * finite, non-zero and/or not NaN.
108 */
109 private static IntegerStamp floatToInt(FloatStamp stamp) {
110 int bits = stamp.getBits();
111
112 long signBit = 1L << (bits - 1);
113 long exponentMask;
114 if (bits == 64) {
115 exponentMask = Double.doubleToRawLongBits(Double.POSITIVE_INFINITY);
116 } else {
117 assert bits == 32;
118 exponentMask = Float.floatToRawIntBits(Float.POSITIVE_INFINITY);
119 }
120
121 long positiveInfinity = exponentMask;
122 long negativeInfinity = CodeUtil.signExtend(signBit | positiveInfinity, bits);
123 long negativeZero = CodeUtil.signExtend(signBit | 0, bits);
124
125 if (stamp.isNaN()) {
126 // special case: in addition to the range, we know NaN has all exponent bits set
127 return new IntegerStamp(bits, negativeInfinity + 1, CodeUtil.maxValue(bits), exponentMask, CodeUtil.mask(bits));
128 }
129
130 long upperBound;
131 if (stamp.isNonNaN()) {
132 if (stamp.upperBound() < 0.0) {
133 if (stamp.lowerBound() > Double.NEGATIVE_INFINITY) {
134 upperBound = negativeInfinity - 1;
135 } else {
136 upperBound = negativeInfinity;
137 }
138 } else if (stamp.upperBound() == 0.0) {
139 upperBound = 0;
140 } else if (stamp.upperBound() < Double.POSITIVE_INFINITY) {
141 upperBound = positiveInfinity - 1;
142 } else {
143 upperBound = positiveInfinity;
144 }
145 } else {
146 upperBound = CodeUtil.maxValue(bits);
147 }
264 return intToFloat((IntegerStamp) fromStamp);
265 } else {
266 return toStamp;
267 }
268 }
269
270 @Override
271 public boolean inferStamp() {
272 return updateStamp(getReinterpretStamp(stamp(), getValue().stamp()));
273 }
274
275 @Override
276 public void generate(NodeLIRBuilderTool builder, ArithmeticLIRGeneratorTool gen) {
277 LIRKind kind = builder.getLIRGeneratorTool().getLIRKind(stamp());
278 builder.setResult(this, gen.emitReinterpret(kind, builder.operand(getValue())));
279 }
280
281 public static ValueNode reinterpret(JavaKind toKind, ValueNode value) {
282 return value.graph().unique(new ReinterpretNode(toKind, value));
283 }
284
285 @NodeIntrinsic
286 public static native float reinterpret(@ConstantNodeParameter JavaKind kind, int value);
287
288 @NodeIntrinsic
289 public static native int reinterpret(@ConstantNodeParameter JavaKind kind, float value);
290
291 @NodeIntrinsic
292 public static native double reinterpret(@ConstantNodeParameter JavaKind kind, long value);
293
294 @NodeIntrinsic
295 public static native long reinterpret(@ConstantNodeParameter JavaKind kind, double value);
296 }
|
107 * finite, non-zero and/or not NaN.
108 */
109 private static IntegerStamp floatToInt(FloatStamp stamp) {
110 int bits = stamp.getBits();
111
112 long signBit = 1L << (bits - 1);
113 long exponentMask;
114 if (bits == 64) {
115 exponentMask = Double.doubleToRawLongBits(Double.POSITIVE_INFINITY);
116 } else {
117 assert bits == 32;
118 exponentMask = Float.floatToRawIntBits(Float.POSITIVE_INFINITY);
119 }
120
121 long positiveInfinity = exponentMask;
122 long negativeInfinity = CodeUtil.signExtend(signBit | positiveInfinity, bits);
123 long negativeZero = CodeUtil.signExtend(signBit | 0, bits);
124
125 if (stamp.isNaN()) {
126 // special case: in addition to the range, we know NaN has all exponent bits set
127 return IntegerStamp.create(bits, negativeInfinity + 1, CodeUtil.maxValue(bits), exponentMask, CodeUtil.mask(bits));
128 }
129
130 long upperBound;
131 if (stamp.isNonNaN()) {
132 if (stamp.upperBound() < 0.0) {
133 if (stamp.lowerBound() > Double.NEGATIVE_INFINITY) {
134 upperBound = negativeInfinity - 1;
135 } else {
136 upperBound = negativeInfinity;
137 }
138 } else if (stamp.upperBound() == 0.0) {
139 upperBound = 0;
140 } else if (stamp.upperBound() < Double.POSITIVE_INFINITY) {
141 upperBound = positiveInfinity - 1;
142 } else {
143 upperBound = positiveInfinity;
144 }
145 } else {
146 upperBound = CodeUtil.maxValue(bits);
147 }
264 return intToFloat((IntegerStamp) fromStamp);
265 } else {
266 return toStamp;
267 }
268 }
269
270 @Override
271 public boolean inferStamp() {
272 return updateStamp(getReinterpretStamp(stamp(), getValue().stamp()));
273 }
274
275 @Override
276 public void generate(NodeLIRBuilderTool builder, ArithmeticLIRGeneratorTool gen) {
277 LIRKind kind = builder.getLIRGeneratorTool().getLIRKind(stamp());
278 builder.setResult(this, gen.emitReinterpret(kind, builder.operand(getValue())));
279 }
280
281 public static ValueNode reinterpret(JavaKind toKind, ValueNode value) {
282 return value.graph().unique(new ReinterpretNode(toKind, value));
283 }
284 }
|