< prev index next >

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

Print this page




 274             return true;
 275         }
 276         if (obj == null || getClass() != obj.getClass() || !super.equals(obj)) {
 277             return false;
 278         }
 279         FloatStamp other = (FloatStamp) obj;
 280         if (Double.doubleToLongBits(lowerBound) != Double.doubleToLongBits(other.lowerBound)) {
 281             return false;
 282         }
 283         if (Double.doubleToLongBits(upperBound) != Double.doubleToLongBits(other.upperBound)) {
 284             return false;
 285         }
 286         if (nonNaN != other.nonNaN) {
 287             return false;
 288         }
 289         return super.equals(other);
 290     }
 291 
 292     @Override
 293     public JavaConstant asConstant() {
 294         if (nonNaN && Double.compare(lowerBound, upperBound) == 0) {
 295             switch (getBits()) {
 296                 case 32:
 297                     return JavaConstant.forFloat((float) lowerBound);
 298                 case 64:
 299                     return JavaConstant.forDouble(lowerBound);
 300             }
 301         }
 302         return null;
 303     }
 304 






























































 305     public static final ArithmeticOpTable OPS = new ArithmeticOpTable(
 306 
 307                     new UnaryOp.Neg() {
 308 
 309                         @Override
 310                         public Constant foldConstant(Constant c) {
 311                             PrimitiveConstant value = (PrimitiveConstant) c;
 312                             switch (value.getJavaKind()) {
 313                                 case Float:
 314                                     return JavaConstant.forFloat(-value.asFloat());
 315                                 case Double:
 316                                     return JavaConstant.forDouble(-value.asDouble());
 317                                 default:
 318                                     throw GraalError.shouldNotReachHere();
 319                             }
 320                         }
 321 
 322                         @Override
 323                         public Stamp foldStamp(Stamp s) {
 324                             FloatStamp stamp = (FloatStamp) s;




 325                             return new FloatStamp(stamp.getBits(), -stamp.upperBound(), -stamp.lowerBound(), stamp.isNonNaN());
 326                         }

 327                     },
 328 
 329                     new BinaryOp.Add(false, true) {
 330 
 331                         @Override
 332                         public Constant foldConstant(Constant const1, Constant const2) {
 333                             PrimitiveConstant a = (PrimitiveConstant) const1;
 334                             PrimitiveConstant b = (PrimitiveConstant) const2;
 335                             assert a.getJavaKind() == b.getJavaKind();
 336                             switch (a.getJavaKind()) {
 337                                 case Float:
 338                                     return JavaConstant.forFloat(a.asFloat() + b.asFloat());
 339                                 case Double:
 340                                     return JavaConstant.forDouble(a.asDouble() + b.asDouble());
 341                                 default:
 342                                     throw GraalError.shouldNotReachHere();
 343                             }
 344                         }
 345 
 346                         @Override
 347                         public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
 348                             // TODO





 349                             return stamp1.unrestricted();
 350                         }
 351 
 352                         @Override
 353                         public boolean isNeutral(Constant value) {
 354                             PrimitiveConstant n = (PrimitiveConstant) value;
 355                             switch (n.getJavaKind()) {
 356                                 case Float:
 357                                     return Float.compare(n.asFloat(), -0.0f) == 0;
 358                                 case Double:
 359                                     return Double.compare(n.asDouble(), -0.0) == 0;
 360                                 default:
 361                                     throw GraalError.shouldNotReachHere();
 362                             }
 363                         }
 364                     },
 365 
 366                     new BinaryOp.Sub(false, false) {
 367 
 368                         @Override
 369                         public Constant foldConstant(Constant const1, Constant const2) {
 370                             PrimitiveConstant a = (PrimitiveConstant) const1;
 371                             PrimitiveConstant b = (PrimitiveConstant) const2;
 372                             assert a.getJavaKind() == b.getJavaKind();
 373                             switch (a.getJavaKind()) {
 374                                 case Float:
 375                                     return JavaConstant.forFloat(a.asFloat() - b.asFloat());
 376                                 case Double:
 377                                     return JavaConstant.forDouble(a.asDouble() - b.asDouble());
 378                                 default:
 379                                     throw GraalError.shouldNotReachHere();
 380                             }
 381                         }
 382 
 383                         @Override
 384                         public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
 385                             // TODO





 386                             return stamp1.unrestricted();
 387                         }
 388 
 389                         @Override
 390                         public boolean isNeutral(Constant value) {
 391                             PrimitiveConstant n = (PrimitiveConstant) value;
 392                             switch (n.getJavaKind()) {
 393                                 case Float:
 394                                     return Float.compare(n.asFloat(), 0.0f) == 0;
 395                                 case Double:
 396                                     return Double.compare(n.asDouble(), 0.0) == 0;
 397                                 default:
 398                                     throw GraalError.shouldNotReachHere();
 399                             }
 400                         }
 401                     },
 402 
 403                     new BinaryOp.Mul(false, true) {
 404 
 405                         @Override
 406                         public Constant foldConstant(Constant const1, Constant const2) {
 407                             PrimitiveConstant a = (PrimitiveConstant) const1;
 408                             PrimitiveConstant b = (PrimitiveConstant) const2;
 409                             assert a.getJavaKind() == b.getJavaKind();
 410                             switch (a.getJavaKind()) {
 411                                 case Float:
 412                                     return JavaConstant.forFloat(a.asFloat() * b.asFloat());
 413                                 case Double:
 414                                     return JavaConstant.forDouble(a.asDouble() * b.asDouble());
 415                                 default:
 416                                     throw GraalError.shouldNotReachHere();
 417                             }
 418                         }
 419 
 420                         @Override
 421                         public Stamp foldStamp(Stamp a, Stamp b) {
 422                             // TODO
 423                             return a.unrestricted();





 424                         }
 425 
 426                         @Override
 427                         public boolean isNeutral(Constant value) {
 428                             PrimitiveConstant n = (PrimitiveConstant) value;
 429                             switch (n.getJavaKind()) {
 430                                 case Float:
 431                                     return Float.compare(n.asFloat(), 1.0f) == 0;
 432                                 case Double:
 433                                     return Double.compare(n.asDouble(), 1.0) == 0;
 434                                 default:
 435                                     throw GraalError.shouldNotReachHere();
 436                             }
 437                         }
 438                     },
 439 
 440                     null,
 441 
 442                     null,
 443 
 444                     new BinaryOp.Div(false, false) {
 445 
 446                         @Override
 447                         public Constant foldConstant(Constant const1, Constant const2) {
 448                             PrimitiveConstant a = (PrimitiveConstant) const1;
 449                             PrimitiveConstant b = (PrimitiveConstant) const2;
 450                             assert a.getJavaKind() == b.getJavaKind();
 451                             switch (a.getJavaKind()) {
 452                                 case Float:
 453                                     return JavaConstant.forFloat(a.asFloat() / b.asFloat());

 454                                 case Double:
 455                                     return JavaConstant.forDouble(a.asDouble() / b.asDouble());

 456                                 default:
 457                                     throw GraalError.shouldNotReachHere();
 458                             }
 459                         }
 460 
 461                         @Override
 462                         public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
 463                             // TODO





 464                             return stamp1.unrestricted();
 465                         }
 466 
 467                         @Override
 468                         public boolean isNeutral(Constant value) {
 469                             PrimitiveConstant n = (PrimitiveConstant) value;
 470                             switch (n.getJavaKind()) {
 471                                 case Float:
 472                                     return Float.compare(n.asFloat(), 1.0f) == 0;
 473                                 case Double:
 474                                     return Double.compare(n.asDouble(), 1.0) == 0;
 475                                 default:
 476                                     throw GraalError.shouldNotReachHere();
 477                             }
 478                         }
 479                     },
 480 
 481                     new BinaryOp.Rem(false, false) {
 482 
 483                         @Override
 484                         public Constant foldConstant(Constant const1, Constant const2) {
 485                             PrimitiveConstant a = (PrimitiveConstant) const1;
 486                             PrimitiveConstant b = (PrimitiveConstant) const2;
 487                             assert a.getJavaKind() == b.getJavaKind();
 488                             switch (a.getJavaKind()) {
 489                                 case Float:
 490                                     return JavaConstant.forFloat(a.asFloat() % b.asFloat());
 491                                 case Double:
 492                                     return JavaConstant.forDouble(a.asDouble() % b.asDouble());
 493                                 default:
 494                                     throw GraalError.shouldNotReachHere();
 495                             }
 496                         }
 497 
 498                         @Override
 499                         public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
 500                             // TODO





 501                             return stamp1.unrestricted();
 502                         }
 503                     },
 504 
 505                     new UnaryOp.Not() {
 506 
 507                         @Override
 508                         public Constant foldConstant(Constant c) {
 509                             PrimitiveConstant value = (PrimitiveConstant) c;
 510                             switch (value.getJavaKind()) {
 511                                 case Float:
 512                                     int f = Float.floatToRawIntBits(value.asFloat());
 513                                     return JavaConstant.forFloat(Float.intBitsToFloat(~f));
 514                                 case Double:
 515                                     long d = Double.doubleToRawLongBits(value.asDouble());
 516                                     return JavaConstant.forDouble(Double.longBitsToDouble(~d));
 517                                 default:
 518                                     throw GraalError.shouldNotReachHere();
 519                             }
 520                         }
 521 
 522                         @Override
 523                         public Stamp foldStamp(Stamp s) {











 524                             return s.unrestricted();
 525                         }
 526                     },
 527 
 528                     new BinaryOp.And(true, true) {
 529 
 530                         @Override
 531                         public Constant foldConstant(Constant const1, Constant const2) {
 532                             PrimitiveConstant a = (PrimitiveConstant) const1;
 533                             PrimitiveConstant b = (PrimitiveConstant) const2;
 534                             assert a.getJavaKind() == b.getJavaKind();
 535                             switch (a.getJavaKind()) {
 536                                 case Float:
 537                                     int fa = Float.floatToRawIntBits(a.asFloat());
 538                                     int fb = Float.floatToRawIntBits(b.asFloat());
 539                                     return JavaConstant.forFloat(Float.intBitsToFloat(fa & fb));
 540                                 case Double:
 541                                     long da = Double.doubleToRawLongBits(a.asDouble());
 542                                     long db = Double.doubleToRawLongBits(b.asDouble());
 543                                     return JavaConstant.forDouble(Double.longBitsToDouble(da & db));
 544                                 default:
 545                                     throw GraalError.shouldNotReachHere();
 546                             }
 547                         }
 548 
 549                         @Override
 550                         public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {






 551                             return stamp1.unrestricted();
 552                         }
 553 
 554                         @Override
 555                         public boolean isNeutral(Constant n) {
 556                             PrimitiveConstant value = (PrimitiveConstant) n;
 557                             switch (value.getJavaKind()) {
 558                                 case Float:
 559                                     return Float.floatToRawIntBits(value.asFloat()) == 0xFFFFFFFF;
 560                                 case Double:
 561                                     return Double.doubleToRawLongBits(value.asDouble()) == 0xFFFFFFFFFFFFFFFFL;
 562                                 default:
 563                                     throw GraalError.shouldNotReachHere();
 564                             }
 565                         }
 566                     },
 567 
 568                     new BinaryOp.Or(true, true) {
 569 
 570                         @Override
 571                         public Constant foldConstant(Constant const1, Constant const2) {
 572                             PrimitiveConstant a = (PrimitiveConstant) const1;
 573                             PrimitiveConstant b = (PrimitiveConstant) const2;
 574                             assert a.getJavaKind() == b.getJavaKind();
 575                             switch (a.getJavaKind()) {
 576                                 case Float:
 577                                     int fa = Float.floatToRawIntBits(a.asFloat());
 578                                     int fb = Float.floatToRawIntBits(b.asFloat());
 579                                     return JavaConstant.forFloat(Float.intBitsToFloat(fa | fb));


 580                                 case Double:
 581                                     long da = Double.doubleToRawLongBits(a.asDouble());
 582                                     long db = Double.doubleToRawLongBits(b.asDouble());
 583                                     return JavaConstant.forDouble(Double.longBitsToDouble(da | db));
 584                                 default:
 585                                     throw GraalError.shouldNotReachHere();
 586                             }
 587                         }
 588 
 589                         @Override
 590                         public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {






 591                             return stamp1.unrestricted();
 592                         }
 593 
 594                         @Override
 595                         public boolean isNeutral(Constant n) {
 596                             PrimitiveConstant value = (PrimitiveConstant) n;
 597                             switch (value.getJavaKind()) {
 598                                 case Float:
 599                                     return Float.floatToRawIntBits(value.asFloat()) == 0;
 600                                 case Double:
 601                                     return Double.doubleToRawLongBits(value.asDouble()) == 0L;
 602                                 default:
 603                                     throw GraalError.shouldNotReachHere();
 604                             }
 605                         }
 606                     },
 607 
 608                     new BinaryOp.Xor(true, true) {
 609 
 610                         @Override
 611                         public Constant foldConstant(Constant const1, Constant const2) {
 612                             PrimitiveConstant a = (PrimitiveConstant) const1;
 613                             PrimitiveConstant b = (PrimitiveConstant) const2;
 614                             assert a.getJavaKind() == b.getJavaKind();
 615                             switch (a.getJavaKind()) {
 616                                 case Float:
 617                                     int fa = Float.floatToRawIntBits(a.asFloat());
 618                                     int fb = Float.floatToRawIntBits(b.asFloat());
 619                                     return JavaConstant.forFloat(Float.intBitsToFloat(fa ^ fb));
 620                                 case Double:
 621                                     long da = Double.doubleToRawLongBits(a.asDouble());
 622                                     long db = Double.doubleToRawLongBits(b.asDouble());
 623                                     return JavaConstant.forDouble(Double.longBitsToDouble(da ^ db));
 624                                 default:
 625                                     throw GraalError.shouldNotReachHere();
 626                             }
 627                         }
 628 
 629                         @Override
 630                         public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {






 631                             return stamp1.unrestricted();
 632                         }
 633 
 634                         @Override
 635                         public boolean isNeutral(Constant n) {
 636                             PrimitiveConstant value = (PrimitiveConstant) n;
 637                             switch (value.getJavaKind()) {
 638                                 case Float:
 639                                     return Float.floatToRawIntBits(value.asFloat()) == 0;
 640                                 case Double:
 641                                     return Double.doubleToRawLongBits(value.asDouble()) == 0L;
 642                                 default:
 643                                     throw GraalError.shouldNotReachHere();
 644                             }
 645                         }
 646                     },
 647 
 648                     null, null, null,
 649 
 650                     new UnaryOp.Abs() {
 651 
 652                         @Override
 653                         public Constant foldConstant(Constant c) {
 654                             PrimitiveConstant value = (PrimitiveConstant) c;
 655                             switch (value.getJavaKind()) {
 656                                 case Float:
 657                                     return JavaConstant.forFloat(Math.abs(value.asFloat()));
 658                                 case Double:
 659                                     return JavaConstant.forDouble(Math.abs(value.asDouble()));
 660                                 default:
 661                                     throw GraalError.shouldNotReachHere();
 662                             }
 663                         }
 664 
 665                         @Override
 666                         public Stamp foldStamp(Stamp s) {
 667                             FloatStamp stamp = (FloatStamp) s;




 668                             if (stamp.isNaN()) {
 669                                 return stamp;
 670                             }
 671                             return new FloatStamp(stamp.getBits(), 0, Math.max(-stamp.lowerBound(), stamp.upperBound()), stamp.isNonNaN());
 672                         }
 673                     },
 674 
 675                     new UnaryOp.Sqrt() {
 676 
 677                         @Override
 678                         public Constant foldConstant(Constant c) {
 679                             PrimitiveConstant value = (PrimitiveConstant) c;
 680                             switch (value.getJavaKind()) {
 681                                 case Float:
 682                                     return JavaConstant.forFloat((float) Math.sqrt(value.asFloat()));
 683                                 case Double:
 684                                     return JavaConstant.forDouble(Math.sqrt(value.asDouble()));
 685                                 default:
 686                                     throw GraalError.shouldNotReachHere();
 687                             }
 688                         }
 689 
 690                         @Override
 691                         public Stamp foldStamp(Stamp s) {





 692                             return s.unrestricted();
 693                         }
 694                     },
 695 
 696                     null, null, null,
 697 
 698                     new FloatConvertOp(F2I) {
 699 
 700                         @Override
 701                         public Constant foldConstant(Constant c) {
 702                             PrimitiveConstant value = (PrimitiveConstant) c;
 703                             return JavaConstant.forInt((int) value.asFloat());
 704                         }
 705 
 706                         @Override
 707                         public Stamp foldStamp(Stamp stamp) {
 708                             FloatStamp floatStamp = (FloatStamp) stamp;
 709                             assert floatStamp.getBits() == 32;
 710                             boolean mustHaveZero = !floatStamp.isNonNaN();
 711                             int lowerBound = (int) floatStamp.lowerBound();




 274             return true;
 275         }
 276         if (obj == null || getClass() != obj.getClass() || !super.equals(obj)) {
 277             return false;
 278         }
 279         FloatStamp other = (FloatStamp) obj;
 280         if (Double.doubleToLongBits(lowerBound) != Double.doubleToLongBits(other.lowerBound)) {
 281             return false;
 282         }
 283         if (Double.doubleToLongBits(upperBound) != Double.doubleToLongBits(other.upperBound)) {
 284             return false;
 285         }
 286         if (nonNaN != other.nonNaN) {
 287             return false;
 288         }
 289         return super.equals(other);
 290     }
 291 
 292     @Override
 293     public JavaConstant asConstant() {
 294         if (isConstant()) {
 295             switch (getBits()) {
 296                 case 32:
 297                     return JavaConstant.forFloat((float) lowerBound);
 298                 case 64:
 299                     return JavaConstant.forDouble(lowerBound);
 300             }
 301         }
 302         return null;
 303     }
 304 
 305     private boolean isConstant() {
 306         /*
 307          * There are many forms of NaNs and any operations on them can silently convert them into
 308          * the canonical NaN.
 309          */
 310         return (Double.compare(lowerBound, upperBound) == 0 && nonNaN);
 311     }
 312 
 313     private static FloatStamp stampForConstant(Constant constant) {
 314         FloatStamp result;
 315         PrimitiveConstant value = (PrimitiveConstant) constant;
 316         switch (value.getJavaKind()) {
 317             case Float:
 318                 if (Float.isNaN(value.asFloat())) {
 319                     result = new FloatStamp(32, Double.NaN, Double.NaN, false);
 320                 } else {
 321                     result = new FloatStamp(32, value.asFloat(), value.asFloat(), !Float.isNaN(value.asFloat()));
 322                 }
 323                 break;
 324             case Double:
 325                 if (Double.isNaN(value.asDouble())) {
 326                     result = new FloatStamp(64, Double.NaN, Double.NaN, false);
 327                 } else {
 328                     result = new FloatStamp(64, value.asDouble(), value.asDouble(), !Double.isNaN(value.asDouble()));
 329                 }
 330                 break;
 331             default:
 332                 throw GraalError.shouldNotReachHere();
 333         }
 334         if (result.isConstant()) {
 335             return result;
 336         }
 337         return null;
 338     }
 339 
 340     private static Stamp maybeFoldConstant(UnaryOp<?> op, FloatStamp stamp) {
 341         if (stamp.isConstant()) {
 342             JavaConstant constant = stamp.asConstant();
 343             Constant folded = op.foldConstant(constant);
 344             if (folded != null) {
 345                 return FloatStamp.stampForConstant(folded);
 346             }
 347         }
 348         return null;
 349     }
 350 
 351     private static Stamp maybeFoldConstant(BinaryOp<?> op, FloatStamp stamp1, FloatStamp stamp2) {
 352         if (stamp1.isConstant() && stamp2.isConstant()) {
 353             JavaConstant constant1 = stamp1.asConstant();
 354             JavaConstant constant2 = stamp2.asConstant();
 355             Constant folded = op.foldConstant(constant1, constant2);
 356             if (folded != null) {
 357                 FloatStamp stamp = stampForConstant(folded);
 358                 if (stamp != null && stamp.isConstant()) {
 359                     assert stamp.asConstant().equals(folded);
 360                     return stamp;
 361                 }
 362             }
 363         }
 364         return null;
 365     }
 366 
 367     public static final ArithmeticOpTable OPS = new ArithmeticOpTable(
 368 
 369                     new UnaryOp.Neg() {
 370 
 371                         @Override
 372                         public Constant foldConstant(Constant c) {
 373                             PrimitiveConstant value = (PrimitiveConstant) c;
 374                             switch (value.getJavaKind()) {
 375                                 case Float:
 376                                     return JavaConstant.forFloat(-value.asFloat());
 377                                 case Double:
 378                                     return JavaConstant.forDouble(-value.asDouble());
 379                                 default:
 380                                     throw GraalError.shouldNotReachHere();
 381                             }
 382                         }
 383 
 384                         @Override
 385                         public Stamp foldStamp(Stamp s) {
 386                             FloatStamp stamp = (FloatStamp) s;
 387                             Stamp folded = maybeFoldConstant(this, stamp);
 388                             if (folded != null) {
 389                                 return folded;
 390                             }
 391                             return new FloatStamp(stamp.getBits(), -stamp.upperBound(), -stamp.lowerBound(), stamp.isNonNaN());
 392                         }
 393 
 394                     },
 395 
 396                     new BinaryOp.Add(false, true) {
 397 
 398                         @Override
 399                         public Constant foldConstant(Constant const1, Constant const2) {
 400                             PrimitiveConstant a = (PrimitiveConstant) const1;
 401                             PrimitiveConstant b = (PrimitiveConstant) const2;
 402                             assert a.getJavaKind() == b.getJavaKind();
 403                             switch (a.getJavaKind()) {
 404                                 case Float:
 405                                     return JavaConstant.forFloat(a.asFloat() + b.asFloat());
 406                                 case Double:
 407                                     return JavaConstant.forDouble(a.asDouble() + b.asDouble());
 408                                 default:
 409                                     throw GraalError.shouldNotReachHere();
 410                             }
 411                         }
 412 
 413                         @Override
 414                         public Stamp foldStamp(Stamp s1, Stamp s2) {
 415                             FloatStamp stamp1 = (FloatStamp) s1;
 416                             FloatStamp stamp2 = (FloatStamp) s2;
 417                             Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
 418                             if (folded != null) {
 419                                 return folded;
 420                             }
 421                             return stamp1.unrestricted();
 422                         }
 423 
 424                         @Override
 425                         public boolean isNeutral(Constant value) {
 426                             PrimitiveConstant n = (PrimitiveConstant) value;
 427                             switch (n.getJavaKind()) {
 428                                 case Float:
 429                                     return Float.compare(n.asFloat(), -0.0f) == 0;
 430                                 case Double:
 431                                     return Double.compare(n.asDouble(), -0.0) == 0;
 432                                 default:
 433                                     throw GraalError.shouldNotReachHere();
 434                             }
 435                         }
 436                     },
 437 
 438                     new BinaryOp.Sub(false, false) {
 439 
 440                         @Override
 441                         public Constant foldConstant(Constant const1, Constant const2) {
 442                             PrimitiveConstant a = (PrimitiveConstant) const1;
 443                             PrimitiveConstant b = (PrimitiveConstant) const2;
 444                             assert a.getJavaKind() == b.getJavaKind();
 445                             switch (a.getJavaKind()) {
 446                                 case Float:
 447                                     return JavaConstant.forFloat(a.asFloat() - b.asFloat());
 448                                 case Double:
 449                                     return JavaConstant.forDouble(a.asDouble() - b.asDouble());
 450                                 default:
 451                                     throw GraalError.shouldNotReachHere();
 452                             }
 453                         }
 454 
 455                         @Override
 456                         public Stamp foldStamp(Stamp s1, Stamp s2) {
 457                             FloatStamp stamp1 = (FloatStamp) s1;
 458                             FloatStamp stamp2 = (FloatStamp) s2;
 459                             Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
 460                             if (folded != null) {
 461                                 return folded;
 462                             }
 463                             return stamp1.unrestricted();
 464                         }
 465 
 466                         @Override
 467                         public boolean isNeutral(Constant value) {
 468                             PrimitiveConstant n = (PrimitiveConstant) value;
 469                             switch (n.getJavaKind()) {
 470                                 case Float:
 471                                     return Float.compare(n.asFloat(), 0.0f) == 0;
 472                                 case Double:
 473                                     return Double.compare(n.asDouble(), 0.0) == 0;
 474                                 default:
 475                                     throw GraalError.shouldNotReachHere();
 476                             }
 477                         }
 478                     },
 479 
 480                     new BinaryOp.Mul(false, true) {
 481 
 482                         @Override
 483                         public Constant foldConstant(Constant const1, Constant const2) {
 484                             PrimitiveConstant a = (PrimitiveConstant) const1;
 485                             PrimitiveConstant b = (PrimitiveConstant) const2;
 486                             assert a.getJavaKind() == b.getJavaKind();
 487                             switch (a.getJavaKind()) {
 488                                 case Float:
 489                                     return JavaConstant.forFloat(a.asFloat() * b.asFloat());
 490                                 case Double:
 491                                     return JavaConstant.forDouble(a.asDouble() * b.asDouble());
 492                                 default:
 493                                     throw GraalError.shouldNotReachHere();
 494                             }
 495                         }
 496 
 497                         @Override
 498                         public Stamp foldStamp(Stamp s1, Stamp s2) {
 499                             FloatStamp stamp1 = (FloatStamp) s1;
 500                             FloatStamp stamp2 = (FloatStamp) s2;
 501                             Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
 502                             if (folded != null) {
 503                                 return folded;
 504                             }
 505                             return stamp1.unrestricted();
 506                         }
 507 
 508                         @Override
 509                         public boolean isNeutral(Constant value) {
 510                             PrimitiveConstant n = (PrimitiveConstant) value;
 511                             switch (n.getJavaKind()) {
 512                                 case Float:
 513                                     return Float.compare(n.asFloat(), 1.0f) == 0;
 514                                 case Double:
 515                                     return Double.compare(n.asDouble(), 1.0) == 0;
 516                                 default:
 517                                     throw GraalError.shouldNotReachHere();
 518                             }
 519                         }
 520                     },
 521 
 522                     null,
 523 
 524                     null,
 525 
 526                     new BinaryOp.Div(false, false) {
 527 
 528                         @Override
 529                         public Constant foldConstant(Constant const1, Constant const2) {
 530                             PrimitiveConstant a = (PrimitiveConstant) const1;
 531                             PrimitiveConstant b = (PrimitiveConstant) const2;
 532                             assert a.getJavaKind() == b.getJavaKind();
 533                             switch (a.getJavaKind()) {
 534                                 case Float:
 535                                     float floatDivisor = b.asFloat();
 536                                     return (floatDivisor == 0) ? null : JavaConstant.forFloat(a.asFloat() / floatDivisor);
 537                                 case Double:
 538                                     double doubleDivisor = b.asDouble();
 539                                     return (doubleDivisor == 0) ? null : JavaConstant.forDouble(a.asDouble() / doubleDivisor);
 540                                 default:
 541                                     throw GraalError.shouldNotReachHere();
 542                             }
 543                         }
 544 
 545                         @Override
 546                         public Stamp foldStamp(Stamp s1, Stamp s2) {
 547                             FloatStamp stamp1 = (FloatStamp) s1;
 548                             FloatStamp stamp2 = (FloatStamp) s2;
 549                             Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
 550                             if (folded != null) {
 551                                 return folded;
 552                             }
 553                             return stamp1.unrestricted();
 554                         }
 555 
 556                         @Override
 557                         public boolean isNeutral(Constant value) {
 558                             PrimitiveConstant n = (PrimitiveConstant) value;
 559                             switch (n.getJavaKind()) {
 560                                 case Float:
 561                                     return Float.compare(n.asFloat(), 1.0f) == 0;
 562                                 case Double:
 563                                     return Double.compare(n.asDouble(), 1.0) == 0;
 564                                 default:
 565                                     throw GraalError.shouldNotReachHere();
 566                             }
 567                         }
 568                     },
 569 
 570                     new BinaryOp.Rem(false, false) {
 571 
 572                         @Override
 573                         public Constant foldConstant(Constant const1, Constant const2) {
 574                             PrimitiveConstant a = (PrimitiveConstant) const1;
 575                             PrimitiveConstant b = (PrimitiveConstant) const2;
 576                             assert a.getJavaKind() == b.getJavaKind();
 577                             switch (a.getJavaKind()) {
 578                                 case Float:
 579                                     return JavaConstant.forFloat(a.asFloat() % b.asFloat());
 580                                 case Double:
 581                                     return JavaConstant.forDouble(a.asDouble() % b.asDouble());
 582                                 default:
 583                                     throw GraalError.shouldNotReachHere();
 584                             }
 585                         }
 586 
 587                         @Override
 588                         public Stamp foldStamp(Stamp s1, Stamp s2) {
 589                             FloatStamp stamp1 = (FloatStamp) s1;
 590                             FloatStamp stamp2 = (FloatStamp) s2;
 591                             Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
 592                             if (folded != null) {
 593                                 return folded;
 594                             }
 595                             return stamp1.unrestricted();
 596                         }
 597                     },
 598 
 599                     new UnaryOp.Not() {
 600 
 601                         @Override
 602                         public Constant foldConstant(Constant c) {
 603                             PrimitiveConstant value = (PrimitiveConstant) c;
 604                             switch (value.getJavaKind()) {
 605                                 case Float:
 606                                     int f = Float.floatToRawIntBits(value.asFloat());
 607                                     return JavaConstant.forFloat(Float.intBitsToFloat(~f));
 608                                 case Double:
 609                                     long d = Double.doubleToRawLongBits(value.asDouble());
 610                                     return JavaConstant.forDouble(Double.longBitsToDouble(~d));
 611                                 default:
 612                                     throw GraalError.shouldNotReachHere();
 613                             }
 614                         }
 615 
 616                         @Override
 617                         public Stamp foldStamp(Stamp s) {
 618                             FloatStamp stamp = (FloatStamp) s;
 619                             JavaConstant constant = stamp.asConstant();
 620                             if (constant != null) {
 621                                 Constant folded = foldConstant(constant);
 622                                 if (folded != null) {
 623                                     FloatStamp result = stampForConstant(folded);
 624                                     if (result != null && result.isConstant()) {
 625                                         return result;
 626                                     }
 627                                 }
 628                             }
 629                             return s.unrestricted();
 630                         }
 631                     },
 632 
 633                     new BinaryOp.And(true, true) {
 634 
 635                         @Override
 636                         public Constant foldConstant(Constant const1, Constant const2) {
 637                             PrimitiveConstant a = (PrimitiveConstant) const1;
 638                             PrimitiveConstant b = (PrimitiveConstant) const2;
 639                             assert a.getJavaKind() == b.getJavaKind();
 640                             switch (a.getJavaKind()) {
 641                                 case Float:
 642                                     int fa = Float.floatToRawIntBits(a.asFloat());
 643                                     int fb = Float.floatToRawIntBits(b.asFloat());
 644                                     return JavaConstant.forFloat(Float.intBitsToFloat(fa & fb));
 645                                 case Double:
 646                                     long da = Double.doubleToRawLongBits(a.asDouble());
 647                                     long db = Double.doubleToRawLongBits(b.asDouble());
 648                                     return JavaConstant.forDouble(Double.longBitsToDouble(da & db));
 649                                 default:
 650                                     throw GraalError.shouldNotReachHere();
 651                             }
 652                         }
 653 
 654                         @Override
 655                         public Stamp foldStamp(Stamp s1, Stamp s2) {
 656                             FloatStamp stamp1 = (FloatStamp) s1;
 657                             FloatStamp stamp2 = (FloatStamp) s2;
 658                             Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
 659                             if (folded != null) {
 660                                 return folded;
 661                             }
 662                             return stamp1.unrestricted();
 663                         }
 664 
 665                         @Override
 666                         public boolean isNeutral(Constant n) {
 667                             PrimitiveConstant value = (PrimitiveConstant) n;
 668                             switch (value.getJavaKind()) {
 669                                 case Float:
 670                                     return Float.floatToRawIntBits(value.asFloat()) == 0xFFFFFFFF;
 671                                 case Double:
 672                                     return Double.doubleToRawLongBits(value.asDouble()) == 0xFFFFFFFFFFFFFFFFL;
 673                                 default:
 674                                     throw GraalError.shouldNotReachHere();
 675                             }
 676                         }
 677                     },
 678 
 679                     new BinaryOp.Or(true, true) {
 680 
 681                         @Override
 682                         public Constant foldConstant(Constant const1, Constant const2) {
 683                             PrimitiveConstant a = (PrimitiveConstant) const1;
 684                             PrimitiveConstant b = (PrimitiveConstant) const2;
 685                             assert a.getJavaKind() == b.getJavaKind();
 686                             switch (a.getJavaKind()) {
 687                                 case Float:
 688                                     int fa = Float.floatToRawIntBits(a.asFloat());
 689                                     int fb = Float.floatToRawIntBits(b.asFloat());
 690                                     float floatOr = Float.intBitsToFloat(fa | fb);
 691                                     assert (fa | fb) == Float.floatToRawIntBits((floatOr));
 692                                     return JavaConstant.forFloat(floatOr);
 693                                 case Double:
 694                                     long da = Double.doubleToRawLongBits(a.asDouble());
 695                                     long db = Double.doubleToRawLongBits(b.asDouble());
 696                                     return JavaConstant.forDouble(Double.longBitsToDouble(da | db));
 697                                 default:
 698                                     throw GraalError.shouldNotReachHere();
 699                             }
 700                         }
 701 
 702                         @Override
 703                         public Stamp foldStamp(Stamp s1, Stamp s2) {
 704                             FloatStamp stamp1 = (FloatStamp) s1;
 705                             FloatStamp stamp2 = (FloatStamp) s2;
 706                             Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
 707                             if (folded != null) {
 708                                 return folded;
 709                             }
 710                             return stamp1.unrestricted();
 711                         }
 712 
 713                         @Override
 714                         public boolean isNeutral(Constant n) {
 715                             PrimitiveConstant value = (PrimitiveConstant) n;
 716                             switch (value.getJavaKind()) {
 717                                 case Float:
 718                                     return Float.floatToRawIntBits(value.asFloat()) == 0;
 719                                 case Double:
 720                                     return Double.doubleToRawLongBits(value.asDouble()) == 0L;
 721                                 default:
 722                                     throw GraalError.shouldNotReachHere();
 723                             }
 724                         }
 725                     },
 726 
 727                     new BinaryOp.Xor(true, true) {
 728 
 729                         @Override
 730                         public Constant foldConstant(Constant const1, Constant const2) {
 731                             PrimitiveConstant a = (PrimitiveConstant) const1;
 732                             PrimitiveConstant b = (PrimitiveConstant) const2;
 733                             assert a.getJavaKind() == b.getJavaKind();
 734                             switch (a.getJavaKind()) {
 735                                 case Float:
 736                                     int fa = Float.floatToRawIntBits(a.asFloat());
 737                                     int fb = Float.floatToRawIntBits(b.asFloat());
 738                                     return JavaConstant.forFloat(Float.intBitsToFloat(fa ^ fb));
 739                                 case Double:
 740                                     long da = Double.doubleToRawLongBits(a.asDouble());
 741                                     long db = Double.doubleToRawLongBits(b.asDouble());
 742                                     return JavaConstant.forDouble(Double.longBitsToDouble(da ^ db));
 743                                 default:
 744                                     throw GraalError.shouldNotReachHere();
 745                             }
 746                         }
 747 
 748                         @Override
 749                         public Stamp foldStamp(Stamp s1, Stamp s2) {
 750                             FloatStamp stamp1 = (FloatStamp) s1;
 751                             FloatStamp stamp2 = (FloatStamp) s2;
 752                             Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
 753                             if (folded != null) {
 754                                 return folded;
 755                             }
 756                             return stamp1.unrestricted();
 757                         }
 758 
 759                         @Override
 760                         public boolean isNeutral(Constant n) {
 761                             PrimitiveConstant value = (PrimitiveConstant) n;
 762                             switch (value.getJavaKind()) {
 763                                 case Float:
 764                                     return Float.floatToRawIntBits(value.asFloat()) == 0;
 765                                 case Double:
 766                                     return Double.doubleToRawLongBits(value.asDouble()) == 0L;
 767                                 default:
 768                                     throw GraalError.shouldNotReachHere();
 769                             }
 770                         }
 771                     },
 772 
 773                     null, null, null,
 774 
 775                     new UnaryOp.Abs() {
 776 
 777                         @Override
 778                         public Constant foldConstant(Constant c) {
 779                             PrimitiveConstant value = (PrimitiveConstant) c;
 780                             switch (value.getJavaKind()) {
 781                                 case Float:
 782                                     return JavaConstant.forFloat(Math.abs(value.asFloat()));
 783                                 case Double:
 784                                     return JavaConstant.forDouble(Math.abs(value.asDouble()));
 785                                 default:
 786                                     throw GraalError.shouldNotReachHere();
 787                             }
 788                         }
 789 
 790                         @Override
 791                         public Stamp foldStamp(Stamp s) {
 792                             FloatStamp stamp = (FloatStamp) s;
 793                             Stamp folded = maybeFoldConstant(this, stamp);
 794                             if (folded != null) {
 795                                 return folded;
 796                             }
 797                             if (stamp.isNaN()) {
 798                                 return stamp;
 799                             }
 800                             return new FloatStamp(stamp.getBits(), 0, Math.max(-stamp.lowerBound(), stamp.upperBound()), stamp.isNonNaN());
 801                         }
 802                     },
 803 
 804                     new UnaryOp.Sqrt() {
 805 
 806                         @Override
 807                         public Constant foldConstant(Constant c) {
 808                             PrimitiveConstant value = (PrimitiveConstant) c;
 809                             switch (value.getJavaKind()) {
 810                                 case Float:
 811                                     return JavaConstant.forFloat((float) Math.sqrt(value.asFloat()));
 812                                 case Double:
 813                                     return JavaConstant.forDouble(Math.sqrt(value.asDouble()));
 814                                 default:
 815                                     throw GraalError.shouldNotReachHere();
 816                             }
 817                         }
 818 
 819                         @Override
 820                         public Stamp foldStamp(Stamp s) {
 821                             FloatStamp stamp = (FloatStamp) s;
 822                             Stamp folded = maybeFoldConstant(this, stamp);
 823                             if (folded != null) {
 824                                 return folded;
 825                             }
 826                             return s.unrestricted();
 827                         }
 828                     },
 829 
 830                     null, null, null,
 831 
 832                     new FloatConvertOp(F2I) {
 833 
 834                         @Override
 835                         public Constant foldConstant(Constant c) {
 836                             PrimitiveConstant value = (PrimitiveConstant) c;
 837                             return JavaConstant.forInt((int) value.asFloat());
 838                         }
 839 
 840                         @Override
 841                         public Stamp foldStamp(Stamp stamp) {
 842                             FloatStamp floatStamp = (FloatStamp) stamp;
 843                             assert floatStamp.getBits() == 32;
 844                             boolean mustHaveZero = !floatStamp.isNonNaN();
 845                             int lowerBound = (int) floatStamp.lowerBound();


< prev index next >