< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/IntegerStamp.java

Print this page




 580         if (bits == 64) {
 581             return (((x ^ y) & (x ^ result)) < 0);
 582         }
 583         return result < CodeUtil.minValue(bits) || result > CodeUtil.maxValue(bits);
 584     }
 585 
 586     public static final ArithmeticOpTable OPS = new ArithmeticOpTable(
 587 
 588                     new UnaryOp.Neg() {
 589 
 590                         @Override
 591                         public Constant foldConstant(Constant value) {
 592                             PrimitiveConstant c = (PrimitiveConstant) value;
 593                             return JavaConstant.forIntegerKind(c.getJavaKind(), -c.asLong());
 594                         }
 595 
 596                         @Override
 597                         public Stamp foldStamp(Stamp s) {
 598                             IntegerStamp stamp = (IntegerStamp) s;
 599                             int bits = stamp.getBits();




 600                             if (stamp.lowerBound() != CodeUtil.minValue(bits)) {
 601                                 // TODO(ls) check if the mask calculation is correct...
 602                                 return StampFactory.forInteger(bits, -stamp.upperBound(), -stamp.lowerBound());
 603                             } else {
 604                                 return stamp.unrestricted();
 605                             }
 606                         }
 607                     },
 608 
 609                     new BinaryOp.Add(true, true) {
 610 
 611                         @Override
 612                         public Constant foldConstant(Constant const1, Constant const2) {
 613                             PrimitiveConstant a = (PrimitiveConstant) const1;
 614                             PrimitiveConstant b = (PrimitiveConstant) const2;
 615                             assert a.getJavaKind() == b.getJavaKind();
 616                             return JavaConstant.forIntegerKind(a.getJavaKind(), a.asLong() + b.asLong());
 617                         }
 618 
 619                         @Override
 620                         public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
 621                             IntegerStamp a = (IntegerStamp) stamp1;
 622                             IntegerStamp b = (IntegerStamp) stamp2;
 623 
 624                             int bits = a.getBits();
 625                             assert bits == b.getBits();
 626 





 627                             if (a.isUnrestricted()) {
 628                                 return a;
 629                             } else if (b.isUnrestricted()) {
 630                                 return b;
 631                             }
 632                             long defaultMask = CodeUtil.mask(bits);
 633                             long variableBits = (a.downMask() ^ a.upMask()) | (b.downMask() ^ b.upMask());
 634                             long variableBitsWithCarry = variableBits | (carryBits(a.downMask(), b.downMask()) ^ carryBits(a.upMask(), b.upMask()));
 635                             long newDownMask = (a.downMask() + b.downMask()) & ~variableBitsWithCarry;
 636                             long newUpMask = (a.downMask() + b.downMask()) | variableBitsWithCarry;
 637 
 638                             newDownMask &= defaultMask;
 639                             newUpMask &= defaultMask;
 640 
 641                             long newLowerBound;
 642                             long newUpperBound;
 643                             boolean lowerOverflowsPositively = addOverflowsPositively(a.lowerBound(), b.lowerBound(), bits);
 644                             boolean upperOverflowsPositively = addOverflowsPositively(a.upperBound(), b.upperBound(), bits);
 645                             boolean lowerOverflowsNegatively = addOverflowsNegatively(a.lowerBound(), b.lowerBound(), bits);
 646                             boolean upperOverflowsNegatively = addOverflowsNegatively(a.upperBound(), b.upperBound(), bits);


 694                         }
 695                     },
 696 
 697                     new BinaryOp.Mul(true, true) {
 698 
 699                         @Override
 700                         public Constant foldConstant(Constant const1, Constant const2) {
 701                             PrimitiveConstant a = (PrimitiveConstant) const1;
 702                             PrimitiveConstant b = (PrimitiveConstant) const2;
 703                             assert a.getJavaKind() == b.getJavaKind();
 704                             return JavaConstant.forIntegerKind(a.getJavaKind(), a.asLong() * b.asLong());
 705                         }
 706 
 707                         @Override
 708                         public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
 709                             IntegerStamp a = (IntegerStamp) stamp1;
 710                             IntegerStamp b = (IntegerStamp) stamp2;
 711 
 712                             int bits = a.getBits();
 713                             assert bits == b.getBits();






 714                             // if a==0 or b==0 result of a*b is always 0
 715                             if (a.upMask() == 0) {
 716                                 return a;
 717                             } else if (b.upMask() == 0) {
 718                                 return b;
 719                             } else {
 720                                 // if a has the full range or b, the result will also have it
 721                                 if (a.isUnrestricted()) {
 722                                     return a;
 723                                 } else if (b.isUnrestricted()) {
 724                                     return b;
 725                                 }
 726                                 // a!=0 && b !=0 holds
 727                                 long newLowerBound = Long.MAX_VALUE;
 728                                 long newUpperBound = Long.MIN_VALUE;
 729                                 /*
 730                                  * Based on the signs of the incoming stamps lower and upper bound
 731                                  * of the result of the multiplication may be swapped. LowerBound
 732                                  * can become upper bound if both signs are negative, and so on. To
 733                                  * determine the new values for lower and upper bound we need to


 774                                  *         maxNegB |  /        MIN    :    MAX      /
 775                                  *                 |------------------+-----------------
 776                                  *         minPosB |  /        MAX    :    MIN      /
 777                                  *         maxPosB | MIN        /     :     /      MAX
 778                                  *
 779                                  * @formatter:on
 780                                  */
 781                                 // We materialize all factors here. If they are needed, the signs of
 782                                 // the stamp will ensure the correct value is used.
 783                                 long minNegA = a.lowerBound();
 784                                 long maxNegA = Math.min(0, a.upperBound());
 785                                 long minPosA = Math.max(0, a.lowerBound());
 786                                 long maxPosA = a.upperBound();
 787 
 788                                 long minNegB = b.lowerBound();
 789                                 long maxNegB = Math.min(0, b.upperBound());
 790                                 long minPosB = Math.max(0, b.lowerBound());
 791                                 long maxPosB = b.upperBound();
 792 
 793                                 // multiplication has shift semantics
 794                                 long newUpMask = ~CodeUtil.mask(Long.numberOfTrailingZeros(a.upMask) + Long.numberOfTrailingZeros(b.upMask)) & CodeUtil.mask(bits);
 795 
 796                                 if (a.canBePositive()) {
 797                                     if (b.canBePositive()) {
 798                                         if (multiplicationOverflows(maxPosA, maxPosB, bits)) {
 799                                             return a.unrestricted();
 800                                         }
 801                                         long maxCandidate = maxPosA * maxPosB;
 802                                         if (multiplicationOverflows(minPosA, minPosB, bits)) {
 803                                             return a.unrestricted();
 804                                         }
 805                                         long minCandidate = minPosA * minPosB;
 806                                         newLowerBound = Math.min(newLowerBound, minCandidate);
 807                                         newUpperBound = Math.max(newUpperBound, maxCandidate);
 808                                     }
 809                                     if (b.canBeNegative()) {
 810                                         if (multiplicationOverflows(minPosA, maxNegB, bits)) {
 811                                             return a.unrestricted();
 812                                         }
 813                                         long maxCandidate = minPosA * maxNegB;
 814                                         if (multiplicationOverflows(maxPosA, minNegB, bits)) {


1006                                 long y1 = y >>> 32;
1007 
1008                                 long z0 = x0 * y0;
1009                                 long t = x1 * y0 + (z0 >>> 32);
1010                                 long z1 = t & 0xFFFFFFFFL;
1011                                 long z2 = t >>> 32;
1012                                 z1 += x0 * y1;
1013 
1014                                 return x1 * y1 + z2 + (z1 >>> 32);
1015                             }
1016                         }
1017                     },
1018 
1019                     new BinaryOp.Div(true, false) {
1020 
1021                         @Override
1022                         public Constant foldConstant(Constant const1, Constant const2) {
1023                             PrimitiveConstant a = (PrimitiveConstant) const1;
1024                             PrimitiveConstant b = (PrimitiveConstant) const2;
1025                             assert a.getJavaKind() == b.getJavaKind();



1026                             return JavaConstant.forIntegerKind(a.getJavaKind(), a.asLong() / b.asLong());
1027                         }
1028 
1029                         @Override
1030                         public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
1031                             IntegerStamp a = (IntegerStamp) stamp1;
1032                             IntegerStamp b = (IntegerStamp) stamp2;
1033                             assert a.getBits() == b.getBits();
1034                             if (b.isStrictlyPositive()) {
1035                                 long newLowerBound = a.lowerBound() / b.upperBound();
1036                                 long newUpperBound = a.upperBound() / b.lowerBound();



1037                                 return StampFactory.forInteger(a.getBits(), newLowerBound, newUpperBound);
1038                             } else {
1039                                 return a.unrestricted();
1040                             }
1041                         }
1042 
1043                         @Override
1044                         public boolean isNeutral(Constant value) {
1045                             PrimitiveConstant n = (PrimitiveConstant) value;
1046                             return n.asLong() == 1;
1047                         }
1048                     },
1049 
1050                     new BinaryOp.Rem(false, false) {
1051 
1052                         @Override
1053                         public Constant foldConstant(Constant const1, Constant const2) {
1054                             PrimitiveConstant a = (PrimitiveConstant) const1;
1055                             PrimitiveConstant b = (PrimitiveConstant) const2;
1056                             assert a.getJavaKind() == b.getJavaKind();



1057                             return JavaConstant.forIntegerKind(a.getJavaKind(), a.asLong() % b.asLong());
1058                         }
1059 
1060                         @Override
1061                         public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
1062                             IntegerStamp a = (IntegerStamp) stamp1;
1063                             IntegerStamp b = (IntegerStamp) stamp2;
1064                             assert a.getBits() == b.getBits();






1065                             // zero is always possible
1066                             long newLowerBound = Math.min(a.lowerBound(), 0);
1067                             long newUpperBound = Math.max(a.upperBound(), 0);
1068 
1069                             /* the maximum absolute value of the result, derived from b */
1070                             long magnitude;
1071                             if (b.lowerBound() == CodeUtil.minValue(b.getBits())) {
1072                                 // Math.abs(...) - 1 does not work in a case
1073                                 magnitude = CodeUtil.maxValue(b.getBits());
1074                             } else {
1075                                 magnitude = Math.max(Math.abs(b.lowerBound()), Math.abs(b.upperBound())) - 1;
1076                             }
1077                             newLowerBound = Math.max(newLowerBound, -magnitude);
1078                             newUpperBound = Math.min(newUpperBound, magnitude);
1079 
1080                             return StampFactory.forInteger(a.getBits(), newLowerBound, newUpperBound);
1081                         }
1082                     },
1083 
1084                     new UnaryOp.Not() {


1347                         @Override
1348                         public int getShiftAmountMask(Stamp s) {
1349                             IntegerStamp stamp = (IntegerStamp) s;
1350                             assert CodeUtil.isPowerOf2(stamp.getBits());
1351                             return stamp.getBits() - 1;
1352                         }
1353                     },
1354 
1355                     new UnaryOp.Abs() {
1356 
1357                         @Override
1358                         public Constant foldConstant(Constant value) {
1359                             PrimitiveConstant c = (PrimitiveConstant) value;
1360                             return JavaConstant.forIntegerKind(c.getJavaKind(), Math.abs(c.asLong()));
1361                         }
1362 
1363                         @Override
1364                         public Stamp foldStamp(Stamp input) {
1365                             IntegerStamp stamp = (IntegerStamp) input;
1366                             int bits = stamp.getBits();




1367                             if (stamp.lowerBound() == CodeUtil.minValue(bits)) {
1368                                 return input.unrestricted();
1369                             } else {
1370                                 long limit = Math.max(-stamp.lowerBound(), stamp.upperBound());
1371                                 return StampFactory.forInteger(bits, 0, limit);
1372                             }
1373                         }
1374                     },
1375 
1376                     null,
1377 
1378                     new IntegerConvertOp.ZeroExtend() {
1379 
1380                         @Override
1381                         public Constant foldConstant(int inputBits, int resultBits, Constant c) {
1382                             PrimitiveConstant value = (PrimitiveConstant) c;
1383                             return JavaConstant.forPrimitiveInt(resultBits, CodeUtil.zeroExtend(value.asLong(), inputBits));
1384                         }
1385 
1386                         @Override




 580         if (bits == 64) {
 581             return (((x ^ y) & (x ^ result)) < 0);
 582         }
 583         return result < CodeUtil.minValue(bits) || result > CodeUtil.maxValue(bits);
 584     }
 585 
 586     public static final ArithmeticOpTable OPS = new ArithmeticOpTable(
 587 
 588                     new UnaryOp.Neg() {
 589 
 590                         @Override
 591                         public Constant foldConstant(Constant value) {
 592                             PrimitiveConstant c = (PrimitiveConstant) value;
 593                             return JavaConstant.forIntegerKind(c.getJavaKind(), -c.asLong());
 594                         }
 595 
 596                         @Override
 597                         public Stamp foldStamp(Stamp s) {
 598                             IntegerStamp stamp = (IntegerStamp) s;
 599                             int bits = stamp.getBits();
 600                             if (stamp.lowerBound == stamp.upperBound) {
 601                                 long value = CodeUtil.convert(-stamp.lowerBound(), stamp.getBits(), false);
 602                                 return StampFactory.forInteger(stamp.getBits(), value, value);
 603                             }
 604                             if (stamp.lowerBound() != CodeUtil.minValue(bits)) {
 605                                 // TODO(ls) check if the mask calculation is correct...
 606                                 return StampFactory.forInteger(bits, -stamp.upperBound(), -stamp.lowerBound());
 607                             } else {
 608                                 return stamp.unrestricted();
 609                             }
 610                         }
 611                     },
 612 
 613                     new BinaryOp.Add(true, true) {
 614 
 615                         @Override
 616                         public Constant foldConstant(Constant const1, Constant const2) {
 617                             PrimitiveConstant a = (PrimitiveConstant) const1;
 618                             PrimitiveConstant b = (PrimitiveConstant) const2;
 619                             assert a.getJavaKind() == b.getJavaKind();
 620                             return JavaConstant.forIntegerKind(a.getJavaKind(), a.asLong() + b.asLong());
 621                         }
 622 
 623                         @Override
 624                         public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
 625                             IntegerStamp a = (IntegerStamp) stamp1;
 626                             IntegerStamp b = (IntegerStamp) stamp2;
 627 
 628                             int bits = a.getBits();
 629                             assert bits == b.getBits();
 630 
 631                             if (a.lowerBound == a.upperBound && b.lowerBound == b.upperBound) {
 632                                 long value = CodeUtil.convert(a.lowerBound() + b.lowerBound(), a.getBits(), false);
 633                                 return StampFactory.forInteger(a.getBits(), value, value);
 634                             }
 635 
 636                             if (a.isUnrestricted()) {
 637                                 return a;
 638                             } else if (b.isUnrestricted()) {
 639                                 return b;
 640                             }
 641                             long defaultMask = CodeUtil.mask(bits);
 642                             long variableBits = (a.downMask() ^ a.upMask()) | (b.downMask() ^ b.upMask());
 643                             long variableBitsWithCarry = variableBits | (carryBits(a.downMask(), b.downMask()) ^ carryBits(a.upMask(), b.upMask()));
 644                             long newDownMask = (a.downMask() + b.downMask()) & ~variableBitsWithCarry;
 645                             long newUpMask = (a.downMask() + b.downMask()) | variableBitsWithCarry;
 646 
 647                             newDownMask &= defaultMask;
 648                             newUpMask &= defaultMask;
 649 
 650                             long newLowerBound;
 651                             long newUpperBound;
 652                             boolean lowerOverflowsPositively = addOverflowsPositively(a.lowerBound(), b.lowerBound(), bits);
 653                             boolean upperOverflowsPositively = addOverflowsPositively(a.upperBound(), b.upperBound(), bits);
 654                             boolean lowerOverflowsNegatively = addOverflowsNegatively(a.lowerBound(), b.lowerBound(), bits);
 655                             boolean upperOverflowsNegatively = addOverflowsNegatively(a.upperBound(), b.upperBound(), bits);


 703                         }
 704                     },
 705 
 706                     new BinaryOp.Mul(true, true) {
 707 
 708                         @Override
 709                         public Constant foldConstant(Constant const1, Constant const2) {
 710                             PrimitiveConstant a = (PrimitiveConstant) const1;
 711                             PrimitiveConstant b = (PrimitiveConstant) const2;
 712                             assert a.getJavaKind() == b.getJavaKind();
 713                             return JavaConstant.forIntegerKind(a.getJavaKind(), a.asLong() * b.asLong());
 714                         }
 715 
 716                         @Override
 717                         public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
 718                             IntegerStamp a = (IntegerStamp) stamp1;
 719                             IntegerStamp b = (IntegerStamp) stamp2;
 720 
 721                             int bits = a.getBits();
 722                             assert bits == b.getBits();
 723 
 724                             if (a.lowerBound == a.upperBound && b.lowerBound == b.upperBound) {
 725                                 long value = CodeUtil.convert(a.lowerBound() * b.lowerBound(), a.getBits(), false);
 726                                 return StampFactory.forInteger(a.getBits(), value, value);
 727                             }
 728 
 729                             // if a==0 or b==0 result of a*b is always 0
 730                             if (a.upMask() == 0) {
 731                                 return a;
 732                             } else if (b.upMask() == 0) {
 733                                 return b;
 734                             } else {
 735                                 // if a has the full range or b, the result will also have it
 736                                 if (a.isUnrestricted()) {
 737                                     return a;
 738                                 } else if (b.isUnrestricted()) {
 739                                     return b;
 740                                 }
 741                                 // a!=0 && b !=0 holds
 742                                 long newLowerBound = Long.MAX_VALUE;
 743                                 long newUpperBound = Long.MIN_VALUE;
 744                                 /*
 745                                  * Based on the signs of the incoming stamps lower and upper bound
 746                                  * of the result of the multiplication may be swapped. LowerBound
 747                                  * can become upper bound if both signs are negative, and so on. To
 748                                  * determine the new values for lower and upper bound we need to


 789                                  *         maxNegB |  /        MIN    :    MAX      /
 790                                  *                 |------------------+-----------------
 791                                  *         minPosB |  /        MAX    :    MIN      /
 792                                  *         maxPosB | MIN        /     :     /      MAX
 793                                  *
 794                                  * @formatter:on
 795                                  */
 796                                 // We materialize all factors here. If they are needed, the signs of
 797                                 // the stamp will ensure the correct value is used.
 798                                 long minNegA = a.lowerBound();
 799                                 long maxNegA = Math.min(0, a.upperBound());
 800                                 long minPosA = Math.max(0, a.lowerBound());
 801                                 long maxPosA = a.upperBound();
 802 
 803                                 long minNegB = b.lowerBound();
 804                                 long maxNegB = Math.min(0, b.upperBound());
 805                                 long minPosB = Math.max(0, b.lowerBound());
 806                                 long maxPosB = b.upperBound();
 807 
 808                                 // multiplication has shift semantics
 809                                 long newUpMask = ~CodeUtil.mask(Math.min(64, Long.numberOfTrailingZeros(a.upMask) + Long.numberOfTrailingZeros(b.upMask))) & CodeUtil.mask(bits);
 810 
 811                                 if (a.canBePositive()) {
 812                                     if (b.canBePositive()) {
 813                                         if (multiplicationOverflows(maxPosA, maxPosB, bits)) {
 814                                             return a.unrestricted();
 815                                         }
 816                                         long maxCandidate = maxPosA * maxPosB;
 817                                         if (multiplicationOverflows(minPosA, minPosB, bits)) {
 818                                             return a.unrestricted();
 819                                         }
 820                                         long minCandidate = minPosA * minPosB;
 821                                         newLowerBound = Math.min(newLowerBound, minCandidate);
 822                                         newUpperBound = Math.max(newUpperBound, maxCandidate);
 823                                     }
 824                                     if (b.canBeNegative()) {
 825                                         if (multiplicationOverflows(minPosA, maxNegB, bits)) {
 826                                             return a.unrestricted();
 827                                         }
 828                                         long maxCandidate = minPosA * maxNegB;
 829                                         if (multiplicationOverflows(maxPosA, minNegB, bits)) {


1021                                 long y1 = y >>> 32;
1022 
1023                                 long z0 = x0 * y0;
1024                                 long t = x1 * y0 + (z0 >>> 32);
1025                                 long z1 = t & 0xFFFFFFFFL;
1026                                 long z2 = t >>> 32;
1027                                 z1 += x0 * y1;
1028 
1029                                 return x1 * y1 + z2 + (z1 >>> 32);
1030                             }
1031                         }
1032                     },
1033 
1034                     new BinaryOp.Div(true, false) {
1035 
1036                         @Override
1037                         public Constant foldConstant(Constant const1, Constant const2) {
1038                             PrimitiveConstant a = (PrimitiveConstant) const1;
1039                             PrimitiveConstant b = (PrimitiveConstant) const2;
1040                             assert a.getJavaKind() == b.getJavaKind();
1041                             if (b.asLong() == 0) {
1042                                 return null;
1043                             }
1044                             return JavaConstant.forIntegerKind(a.getJavaKind(), a.asLong() / b.asLong());
1045                         }
1046 
1047                         @Override
1048                         public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
1049                             IntegerStamp a = (IntegerStamp) stamp1;
1050                             IntegerStamp b = (IntegerStamp) stamp2;
1051                             assert a.getBits() == b.getBits();
1052                             if (a.lowerBound == a.upperBound && b.lowerBound == b.upperBound && b.lowerBound != 0) {
1053                                 long value = CodeUtil.convert(a.lowerBound() / b.lowerBound(), a.getBits(), false);
1054                                 return StampFactory.forInteger(a.getBits(), value, value);
1055                             } else if (b.isStrictlyPositive()) {
1056                                 long newLowerBound = a.lowerBound() < 0 ? a.lowerBound() / b.lowerBound() : a.lowerBound() / b.upperBound();
1057                                 long newUpperBound = a.upperBound() < 0 ? a.upperBound() / b.upperBound() : a.upperBound() / b.lowerBound();
1058                                 return StampFactory.forInteger(a.getBits(), newLowerBound, newUpperBound);
1059                             } else {
1060                                 return a.unrestricted();
1061                             }
1062                         }
1063 
1064                         @Override
1065                         public boolean isNeutral(Constant value) {
1066                             PrimitiveConstant n = (PrimitiveConstant) value;
1067                             return n.asLong() == 1;
1068                         }
1069                     },
1070 
1071                     new BinaryOp.Rem(false, false) {
1072 
1073                         @Override
1074                         public Constant foldConstant(Constant const1, Constant const2) {
1075                             PrimitiveConstant a = (PrimitiveConstant) const1;
1076                             PrimitiveConstant b = (PrimitiveConstant) const2;
1077                             assert a.getJavaKind() == b.getJavaKind();
1078                             if (b.asLong() == 0) {
1079                                 return null;
1080                             }
1081                             return JavaConstant.forIntegerKind(a.getJavaKind(), a.asLong() % b.asLong());
1082                         }
1083 
1084                         @Override
1085                         public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
1086                             IntegerStamp a = (IntegerStamp) stamp1;
1087                             IntegerStamp b = (IntegerStamp) stamp2;
1088                             assert a.getBits() == b.getBits();
1089 
1090                             if (a.lowerBound == a.upperBound && b.lowerBound == b.upperBound && b.lowerBound != 0) {
1091                                 long value = CodeUtil.convert(a.lowerBound() % b.lowerBound(), a.getBits(), false);
1092                                 return StampFactory.forInteger(a.getBits(), value, value);
1093                             }
1094 
1095                             // zero is always possible
1096                             long newLowerBound = Math.min(a.lowerBound(), 0);
1097                             long newUpperBound = Math.max(a.upperBound(), 0);
1098 
1099                             /* the maximum absolute value of the result, derived from b */
1100                             long magnitude;
1101                             if (b.lowerBound() == CodeUtil.minValue(b.getBits())) {
1102                                 // Math.abs(...) - 1 does not work in a case
1103                                 magnitude = CodeUtil.maxValue(b.getBits());
1104                             } else {
1105                                 magnitude = Math.max(Math.abs(b.lowerBound()), Math.abs(b.upperBound())) - 1;
1106                             }
1107                             newLowerBound = Math.max(newLowerBound, -magnitude);
1108                             newUpperBound = Math.min(newUpperBound, magnitude);
1109 
1110                             return StampFactory.forInteger(a.getBits(), newLowerBound, newUpperBound);
1111                         }
1112                     },
1113 
1114                     new UnaryOp.Not() {


1377                         @Override
1378                         public int getShiftAmountMask(Stamp s) {
1379                             IntegerStamp stamp = (IntegerStamp) s;
1380                             assert CodeUtil.isPowerOf2(stamp.getBits());
1381                             return stamp.getBits() - 1;
1382                         }
1383                     },
1384 
1385                     new UnaryOp.Abs() {
1386 
1387                         @Override
1388                         public Constant foldConstant(Constant value) {
1389                             PrimitiveConstant c = (PrimitiveConstant) value;
1390                             return JavaConstant.forIntegerKind(c.getJavaKind(), Math.abs(c.asLong()));
1391                         }
1392 
1393                         @Override
1394                         public Stamp foldStamp(Stamp input) {
1395                             IntegerStamp stamp = (IntegerStamp) input;
1396                             int bits = stamp.getBits();
1397                             if (stamp.lowerBound == stamp.upperBound) {
1398                                 long value = CodeUtil.convert(Math.abs(stamp.lowerBound()), stamp.getBits(), false);
1399                                 return StampFactory.forInteger(stamp.getBits(), value, value);
1400                             }
1401                             if (stamp.lowerBound() == CodeUtil.minValue(bits)) {
1402                                 return input.unrestricted();
1403                             } else {
1404                                 long limit = Math.max(-stamp.lowerBound(), stamp.upperBound());
1405                                 return StampFactory.forInteger(bits, 0, limit);
1406                             }
1407                         }
1408                     },
1409 
1410                     null,
1411 
1412                     new IntegerConvertOp.ZeroExtend() {
1413 
1414                         @Override
1415                         public Constant foldConstant(int inputBits, int resultBits, Constant c) {
1416                             PrimitiveConstant value = (PrimitiveConstant) c;
1417                             return JavaConstant.forPrimitiveInt(resultBits, CodeUtil.zeroExtend(value.asLong(), inputBits));
1418                         }
1419 
1420                         @Override


< prev index next >