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(); |