diff options
Diffstat (limited to 'src/shader_recompiler/frontend/ir/ir_emitter.cpp')
| -rw-r--r-- | src/shader_recompiler/frontend/ir/ir_emitter.cpp | 144 |
1 files changed, 127 insertions, 17 deletions
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index 34c2f67fb..8ba86e614 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -361,19 +361,21 @@ Value IREmitter::CompositeExtract(const Value& vector, size_t element) { | |||
| 361 | } | 361 | } |
| 362 | } | 362 | } |
| 363 | 363 | ||
| 364 | UAny IREmitter::Select(const U1& condition, const UAny& true_value, const UAny& false_value) { | 364 | Value IREmitter::Select(const U1& condition, const Value& true_value, const Value& false_value) { |
| 365 | if (true_value.Type() != false_value.Type()) { | 365 | if (true_value.Type() != false_value.Type()) { |
| 366 | throw InvalidArgument("Mismatching types {} and {}", true_value.Type(), false_value.Type()); | 366 | throw InvalidArgument("Mismatching types {} and {}", true_value.Type(), false_value.Type()); |
| 367 | } | 367 | } |
| 368 | switch (true_value.Type()) { | 368 | switch (true_value.Type()) { |
| 369 | case Type::U8: | 369 | case Type::U8: |
| 370 | return Inst<UAny>(Opcode::Select8, condition, true_value, false_value); | 370 | return Inst(Opcode::SelectU8, condition, true_value, false_value); |
| 371 | case Type::U16: | 371 | case Type::U16: |
| 372 | return Inst<UAny>(Opcode::Select16, condition, true_value, false_value); | 372 | return Inst(Opcode::SelectU16, condition, true_value, false_value); |
| 373 | case Type::U32: | 373 | case Type::U32: |
| 374 | return Inst<UAny>(Opcode::Select32, condition, true_value, false_value); | 374 | return Inst(Opcode::SelectU32, condition, true_value, false_value); |
| 375 | case Type::U64: | 375 | case Type::U64: |
| 376 | return Inst<UAny>(Opcode::Select64, condition, true_value, false_value); | 376 | return Inst(Opcode::SelectU64, condition, true_value, false_value); |
| 377 | case Type::F32: | ||
| 378 | return Inst(Opcode::SelectF32, condition, true_value, false_value); | ||
| 377 | default: | 379 | default: |
| 378 | throw InvalidArgument("Invalid type {}", true_value.Type()); | 380 | throw InvalidArgument("Invalid type {}", true_value.Type()); |
| 379 | } | 381 | } |
| @@ -503,12 +505,16 @@ F16F32F64 IREmitter::FPAbsNeg(const F16F32F64& value, bool abs, bool neg) { | |||
| 503 | return result; | 505 | return result; |
| 504 | } | 506 | } |
| 505 | 507 | ||
| 506 | F32 IREmitter::FPCosNotReduced(const F32& value) { | 508 | F32 IREmitter::FPCos(const F32& value) { |
| 507 | return Inst<F32>(Opcode::FPCosNotReduced, value); | 509 | return Inst<F32>(Opcode::FPCos, value); |
| 510 | } | ||
| 511 | |||
| 512 | F32 IREmitter::FPSin(const F32& value) { | ||
| 513 | return Inst<F32>(Opcode::FPSin, value); | ||
| 508 | } | 514 | } |
| 509 | 515 | ||
| 510 | F32 IREmitter::FPExp2NotReduced(const F32& value) { | 516 | F32 IREmitter::FPExp2(const F32& value) { |
| 511 | return Inst<F32>(Opcode::FPExp2NotReduced, value); | 517 | return Inst<F32>(Opcode::FPExp2, value); |
| 512 | } | 518 | } |
| 513 | 519 | ||
| 514 | F32 IREmitter::FPLog2(const F32& value) { | 520 | F32 IREmitter::FPLog2(const F32& value) { |
| @@ -517,9 +523,9 @@ F32 IREmitter::FPLog2(const F32& value) { | |||
| 517 | 523 | ||
| 518 | F32F64 IREmitter::FPRecip(const F32F64& value) { | 524 | F32F64 IREmitter::FPRecip(const F32F64& value) { |
| 519 | switch (value.Type()) { | 525 | switch (value.Type()) { |
| 520 | case Type::U32: | 526 | case Type::F32: |
| 521 | return Inst<F32>(Opcode::FPRecip32, value); | 527 | return Inst<F32>(Opcode::FPRecip32, value); |
| 522 | case Type::U64: | 528 | case Type::F64: |
| 523 | return Inst<F64>(Opcode::FPRecip64, value); | 529 | return Inst<F64>(Opcode::FPRecip64, value); |
| 524 | default: | 530 | default: |
| 525 | ThrowInvalidType(value.Type()); | 531 | ThrowInvalidType(value.Type()); |
| @@ -528,19 +534,15 @@ F32F64 IREmitter::FPRecip(const F32F64& value) { | |||
| 528 | 534 | ||
| 529 | F32F64 IREmitter::FPRecipSqrt(const F32F64& value) { | 535 | F32F64 IREmitter::FPRecipSqrt(const F32F64& value) { |
| 530 | switch (value.Type()) { | 536 | switch (value.Type()) { |
| 531 | case Type::U32: | 537 | case Type::F32: |
| 532 | return Inst<F32>(Opcode::FPRecipSqrt32, value); | 538 | return Inst<F32>(Opcode::FPRecipSqrt32, value); |
| 533 | case Type::U64: | 539 | case Type::F64: |
| 534 | return Inst<F64>(Opcode::FPRecipSqrt64, value); | 540 | return Inst<F64>(Opcode::FPRecipSqrt64, value); |
| 535 | default: | 541 | default: |
| 536 | ThrowInvalidType(value.Type()); | 542 | ThrowInvalidType(value.Type()); |
| 537 | } | 543 | } |
| 538 | } | 544 | } |
| 539 | 545 | ||
| 540 | F32 IREmitter::FPSinNotReduced(const F32& value) { | ||
| 541 | return Inst<F32>(Opcode::FPSinNotReduced, value); | ||
| 542 | } | ||
| 543 | |||
| 544 | F32 IREmitter::FPSqrt(const F32& value) { | 546 | F32 IREmitter::FPSqrt(const F32& value) { |
| 545 | return Inst<F32>(Opcode::FPSqrt, value); | 547 | return Inst<F32>(Opcode::FPSqrt, value); |
| 546 | } | 548 | } |
| @@ -610,6 +612,114 @@ F16F32F64 IREmitter::FPTrunc(const F16F32F64& value, FpControl control) { | |||
| 610 | } | 612 | } |
| 611 | } | 613 | } |
| 612 | 614 | ||
| 615 | U1 IREmitter::FPEqual(const F16F32F64& lhs, const F16F32F64& rhs, bool ordered) { | ||
| 616 | if (lhs.Type() != rhs.Type()) { | ||
| 617 | throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); | ||
| 618 | } | ||
| 619 | switch (lhs.Type()) { | ||
| 620 | case Type::F16: | ||
| 621 | return Inst<U1>(ordered ? Opcode::FPOrdEqual16 : Opcode::FPUnordEqual16, lhs, rhs); | ||
| 622 | case Type::F32: | ||
| 623 | return Inst<U1>(ordered ? Opcode::FPOrdEqual32 : Opcode::FPUnordEqual32, lhs, rhs); | ||
| 624 | case Type::F64: | ||
| 625 | return Inst<U1>(ordered ? Opcode::FPOrdEqual64 : Opcode::FPUnordEqual64, lhs, rhs); | ||
| 626 | default: | ||
| 627 | ThrowInvalidType(lhs.Type()); | ||
| 628 | } | ||
| 629 | } | ||
| 630 | |||
| 631 | U1 IREmitter::FPNotEqual(const F16F32F64& lhs, const F16F32F64& rhs, bool ordered) { | ||
| 632 | if (lhs.Type() != rhs.Type()) { | ||
| 633 | throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); | ||
| 634 | } | ||
| 635 | switch (lhs.Type()) { | ||
| 636 | case Type::F16: | ||
| 637 | return Inst<U1>(ordered ? Opcode::FPOrdNotEqual16 : Opcode::FPUnordNotEqual16, lhs, rhs); | ||
| 638 | case Type::F32: | ||
| 639 | return Inst<U1>(ordered ? Opcode::FPOrdNotEqual32 : Opcode::FPUnordNotEqual32, lhs, rhs); | ||
| 640 | case Type::F64: | ||
| 641 | return Inst<U1>(ordered ? Opcode::FPOrdNotEqual64 : Opcode::FPUnordNotEqual64, lhs, rhs); | ||
| 642 | default: | ||
| 643 | ThrowInvalidType(lhs.Type()); | ||
| 644 | } | ||
| 645 | } | ||
| 646 | |||
| 647 | U1 IREmitter::FPLessThan(const F16F32F64& lhs, const F16F32F64& rhs, bool ordered) { | ||
| 648 | if (lhs.Type() != rhs.Type()) { | ||
| 649 | throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); | ||
| 650 | } | ||
| 651 | switch (lhs.Type()) { | ||
| 652 | case Type::F16: | ||
| 653 | return Inst<U1>(ordered ? Opcode::FPOrdLessThan16 : Opcode::FPUnordLessThan16, lhs, rhs); | ||
| 654 | case Type::F32: | ||
| 655 | return Inst<U1>(ordered ? Opcode::FPOrdLessThan32 : Opcode::FPUnordLessThan32, lhs, rhs); | ||
| 656 | case Type::F64: | ||
| 657 | return Inst<U1>(ordered ? Opcode::FPOrdLessThan64 : Opcode::FPUnordLessThan64, lhs, rhs); | ||
| 658 | default: | ||
| 659 | ThrowInvalidType(lhs.Type()); | ||
| 660 | } | ||
| 661 | } | ||
| 662 | |||
| 663 | U1 IREmitter::FPGreaterThan(const F16F32F64& lhs, const F16F32F64& rhs, bool ordered) { | ||
| 664 | if (lhs.Type() != rhs.Type()) { | ||
| 665 | throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); | ||
| 666 | } | ||
| 667 | switch (lhs.Type()) { | ||
| 668 | case Type::F16: | ||
| 669 | return Inst<U1>(ordered ? Opcode::FPOrdGreaterThan16 : Opcode::FPUnordGreaterThan16, lhs, | ||
| 670 | rhs); | ||
| 671 | case Type::F32: | ||
| 672 | return Inst<U1>(ordered ? Opcode::FPOrdGreaterThan32 : Opcode::FPUnordGreaterThan32, lhs, | ||
| 673 | rhs); | ||
| 674 | case Type::F64: | ||
| 675 | return Inst<U1>(ordered ? Opcode::FPOrdGreaterThan64 : Opcode::FPUnordGreaterThan64, lhs, | ||
| 676 | rhs); | ||
| 677 | default: | ||
| 678 | ThrowInvalidType(lhs.Type()); | ||
| 679 | } | ||
| 680 | } | ||
| 681 | |||
| 682 | U1 IREmitter::FPLessThanEqual(const F16F32F64& lhs, const F16F32F64& rhs, bool ordered) { | ||
| 683 | if (lhs.Type() != rhs.Type()) { | ||
| 684 | throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); | ||
| 685 | } | ||
| 686 | switch (lhs.Type()) { | ||
| 687 | case Type::F16: | ||
| 688 | return Inst<U1>(ordered ? Opcode::FPOrdLessThanEqual16 : Opcode::FPUnordLessThanEqual16, | ||
| 689 | lhs, rhs); | ||
| 690 | case Type::F32: | ||
| 691 | return Inst<U1>(ordered ? Opcode::FPOrdLessThanEqual32 : Opcode::FPUnordLessThanEqual32, | ||
| 692 | lhs, rhs); | ||
| 693 | case Type::F64: | ||
| 694 | return Inst<U1>(ordered ? Opcode::FPOrdLessThanEqual64 : Opcode::FPUnordLessThanEqual64, | ||
| 695 | lhs, rhs); | ||
| 696 | default: | ||
| 697 | ThrowInvalidType(lhs.Type()); | ||
| 698 | } | ||
| 699 | } | ||
| 700 | |||
| 701 | U1 IREmitter::FPGreaterThanEqual(const F16F32F64& lhs, const F16F32F64& rhs, bool ordered) { | ||
| 702 | if (lhs.Type() != rhs.Type()) { | ||
| 703 | throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); | ||
| 704 | } | ||
| 705 | switch (lhs.Type()) { | ||
| 706 | case Type::F16: | ||
| 707 | return Inst<U1>(ordered ? Opcode::FPOrdGreaterThanEqual16 | ||
| 708 | : Opcode::FPUnordGreaterThanEqual16, | ||
| 709 | lhs, rhs); | ||
| 710 | case Type::F32: | ||
| 711 | return Inst<U1>(ordered ? Opcode::FPOrdGreaterThanEqual32 | ||
| 712 | : Opcode::FPUnordGreaterThanEqual32, | ||
| 713 | lhs, rhs); | ||
| 714 | case Type::F64: | ||
| 715 | return Inst<U1>(ordered ? Opcode::FPOrdGreaterThanEqual64 | ||
| 716 | : Opcode::FPUnordGreaterThanEqual64, | ||
| 717 | lhs, rhs); | ||
| 718 | default: | ||
| 719 | ThrowInvalidType(lhs.Type()); | ||
| 720 | } | ||
| 721 | } | ||
| 722 | |||
| 613 | U32U64 IREmitter::IAdd(const U32U64& a, const U32U64& b) { | 723 | U32U64 IREmitter::IAdd(const U32U64& a, const U32U64& b) { |
| 614 | if (a.Type() != b.Type()) { | 724 | if (a.Type() != b.Type()) { |
| 615 | throw InvalidArgument("Mismatching types {} and {}", a.Type(), b.Type()); | 725 | throw InvalidArgument("Mismatching types {} and {}", a.Type(), b.Type()); |