diff options
Diffstat (limited to 'src/shader_recompiler/frontend')
13 files changed, 277 insertions, 66 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()); |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index 959f4f9da..2c923716a 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h | |||
| @@ -98,7 +98,8 @@ public: | |||
| 98 | const Value& e4); | 98 | const Value& e4); |
| 99 | [[nodiscard]] Value CompositeExtract(const Value& vector, size_t element); | 99 | [[nodiscard]] Value CompositeExtract(const Value& vector, size_t element); |
| 100 | 100 | ||
| 101 | [[nodiscard]] UAny Select(const U1& condition, const UAny& true_value, const UAny& false_value); | 101 | [[nodiscard]] Value Select(const U1& condition, const Value& true_value, |
| 102 | const Value& false_value); | ||
| 102 | 103 | ||
| 103 | template <typename Dest, typename Source> | 104 | template <typename Dest, typename Source> |
| 104 | [[nodiscard]] Dest BitCast(const Source& value); | 105 | [[nodiscard]] Dest BitCast(const Source& value); |
| @@ -121,12 +122,12 @@ public: | |||
| 121 | [[nodiscard]] F16F32F64 FPNeg(const F16F32F64& value); | 122 | [[nodiscard]] F16F32F64 FPNeg(const F16F32F64& value); |
| 122 | [[nodiscard]] F16F32F64 FPAbsNeg(const F16F32F64& value, bool abs, bool neg); | 123 | [[nodiscard]] F16F32F64 FPAbsNeg(const F16F32F64& value, bool abs, bool neg); |
| 123 | 124 | ||
| 124 | [[nodiscard]] F32 FPCosNotReduced(const F32& value); | 125 | [[nodiscard]] F32 FPCos(const F32& value); |
| 125 | [[nodiscard]] F32 FPExp2NotReduced(const F32& value); | 126 | [[nodiscard]] F32 FPSin(const F32& value); |
| 127 | [[nodiscard]] F32 FPExp2(const F32& value); | ||
| 126 | [[nodiscard]] F32 FPLog2(const F32& value); | 128 | [[nodiscard]] F32 FPLog2(const F32& value); |
| 127 | [[nodiscard]] F32F64 FPRecip(const F32F64& value); | 129 | [[nodiscard]] F32F64 FPRecip(const F32F64& value); |
| 128 | [[nodiscard]] F32F64 FPRecipSqrt(const F32F64& value); | 130 | [[nodiscard]] F32F64 FPRecipSqrt(const F32F64& value); |
| 129 | [[nodiscard]] F32 FPSinNotReduced(const F32& value); | ||
| 130 | [[nodiscard]] F32 FPSqrt(const F32& value); | 131 | [[nodiscard]] F32 FPSqrt(const F32& value); |
| 131 | [[nodiscard]] F16F32F64 FPSaturate(const F16F32F64& value); | 132 | [[nodiscard]] F16F32F64 FPSaturate(const F16F32F64& value); |
| 132 | [[nodiscard]] F16F32F64 FPRoundEven(const F16F32F64& value, FpControl control = {}); | 133 | [[nodiscard]] F16F32F64 FPRoundEven(const F16F32F64& value, FpControl control = {}); |
| @@ -134,6 +135,15 @@ public: | |||
| 134 | [[nodiscard]] F16F32F64 FPCeil(const F16F32F64& value, FpControl control = {}); | 135 | [[nodiscard]] F16F32F64 FPCeil(const F16F32F64& value, FpControl control = {}); |
| 135 | [[nodiscard]] F16F32F64 FPTrunc(const F16F32F64& value, FpControl control = {}); | 136 | [[nodiscard]] F16F32F64 FPTrunc(const F16F32F64& value, FpControl control = {}); |
| 136 | 137 | ||
| 138 | [[nodiscard]] U1 FPEqual(const F16F32F64& lhs, const F16F32F64& rhs, bool ordered = true); | ||
| 139 | [[nodiscard]] U1 FPNotEqual(const F16F32F64& lhs, const F16F32F64& rhs, bool ordered = true); | ||
| 140 | [[nodiscard]] U1 FPLessThan(const F16F32F64& lhs, const F16F32F64& rhs, bool ordered = true); | ||
| 141 | [[nodiscard]] U1 FPGreaterThan(const F16F32F64& lhs, const F16F32F64& rhs, bool ordered = true); | ||
| 142 | [[nodiscard]] U1 FPLessThanEqual(const F16F32F64& lhs, const F16F32F64& rhs, | ||
| 143 | bool ordered = true); | ||
| 144 | [[nodiscard]] U1 FPGreaterThanEqual(const F16F32F64& lhs, const F16F32F64& rhs, | ||
| 145 | bool ordered = true); | ||
| 146 | |||
| 137 | [[nodiscard]] U32U64 IAdd(const U32U64& a, const U32U64& b); | 147 | [[nodiscard]] U32U64 IAdd(const U32U64& a, const U32U64& b); |
| 138 | [[nodiscard]] U32U64 ISub(const U32U64& a, const U32U64& b); | 148 | [[nodiscard]] U32U64 ISub(const U32U64& a, const U32U64& b); |
| 139 | [[nodiscard]] U32 IMul(const U32& a, const U32& b); | 149 | [[nodiscard]] U32 IMul(const U32& a, const U32& b); |
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc index 50da77535..f2d71144a 100644 --- a/src/shader_recompiler/frontend/ir/opcodes.inc +++ b/src/shader_recompiler/frontend/ir/opcodes.inc | |||
| @@ -103,10 +103,12 @@ OPCODE(CompositeExtractF64x3, F64, F64x | |||
| 103 | OPCODE(CompositeExtractF64x4, F64, F64x4, U32, ) | 103 | OPCODE(CompositeExtractF64x4, F64, F64x4, U32, ) |
| 104 | 104 | ||
| 105 | // Select operations | 105 | // Select operations |
| 106 | OPCODE(Select8, U8, U1, U8, U8, ) | 106 | OPCODE(SelectU8, U8, U1, U8, U8, ) |
| 107 | OPCODE(Select16, U16, U1, U16, U16, ) | 107 | OPCODE(SelectU16, U16, U1, U16, U16, ) |
| 108 | OPCODE(Select32, U32, U1, U32, U32, ) | 108 | OPCODE(SelectU32, U32, U1, U32, U32, ) |
| 109 | OPCODE(Select64, U64, U1, U64, U64, ) | 109 | OPCODE(SelectU64, U64, U1, U64, U64, ) |
| 110 | OPCODE(SelectF16, F16, U1, F16, F16, ) | ||
| 111 | OPCODE(SelectF32, F32, U1, F32, F32, ) | ||
| 110 | 112 | ||
| 111 | // Bitwise conversions | 113 | // Bitwise conversions |
| 112 | OPCODE(BitCastU16F16, U16, F16, ) | 114 | OPCODE(BitCastU16F16, U16, F16, ) |
| @@ -156,11 +158,8 @@ OPCODE(FPRecipSqrt32, F32, F32, | |||
| 156 | OPCODE(FPRecipSqrt64, F64, F64, ) | 158 | OPCODE(FPRecipSqrt64, F64, F64, ) |
| 157 | OPCODE(FPSqrt, F32, F32, ) | 159 | OPCODE(FPSqrt, F32, F32, ) |
| 158 | OPCODE(FPSin, F32, F32, ) | 160 | OPCODE(FPSin, F32, F32, ) |
| 159 | OPCODE(FPSinNotReduced, F32, F32, ) | ||
| 160 | OPCODE(FPExp2, F32, F32, ) | 161 | OPCODE(FPExp2, F32, F32, ) |
| 161 | OPCODE(FPExp2NotReduced, F32, F32, ) | ||
| 162 | OPCODE(FPCos, F32, F32, ) | 162 | OPCODE(FPCos, F32, F32, ) |
| 163 | OPCODE(FPCosNotReduced, F32, F32, ) | ||
| 164 | OPCODE(FPLog2, F32, F32, ) | 163 | OPCODE(FPLog2, F32, F32, ) |
| 165 | OPCODE(FPSaturate16, F16, F16, ) | 164 | OPCODE(FPSaturate16, F16, F16, ) |
| 166 | OPCODE(FPSaturate32, F32, F32, ) | 165 | OPCODE(FPSaturate32, F32, F32, ) |
| @@ -178,6 +177,43 @@ OPCODE(FPTrunc16, F16, F16, | |||
| 178 | OPCODE(FPTrunc32, F32, F32, ) | 177 | OPCODE(FPTrunc32, F32, F32, ) |
| 179 | OPCODE(FPTrunc64, F64, F64, ) | 178 | OPCODE(FPTrunc64, F64, F64, ) |
| 180 | 179 | ||
| 180 | OPCODE(FPOrdEqual16, U1, F16, F16, ) | ||
| 181 | OPCODE(FPOrdEqual32, U1, F32, F32, ) | ||
| 182 | OPCODE(FPOrdEqual64, U1, F64, F64, ) | ||
| 183 | OPCODE(FPUnordEqual16, U1, F16, F16, ) | ||
| 184 | OPCODE(FPUnordEqual32, U1, F32, F32, ) | ||
| 185 | OPCODE(FPUnordEqual64, U1, F64, F64, ) | ||
| 186 | OPCODE(FPOrdNotEqual16, U1, F16, F16, ) | ||
| 187 | OPCODE(FPOrdNotEqual32, U1, F32, F32, ) | ||
| 188 | OPCODE(FPOrdNotEqual64, U1, F64, F64, ) | ||
| 189 | OPCODE(FPUnordNotEqual16, U1, F16, F16, ) | ||
| 190 | OPCODE(FPUnordNotEqual32, U1, F32, F32, ) | ||
| 191 | OPCODE(FPUnordNotEqual64, U1, F64, F64, ) | ||
| 192 | OPCODE(FPOrdLessThan16, U1, F16, F16, ) | ||
| 193 | OPCODE(FPOrdLessThan32, U1, F32, F32, ) | ||
| 194 | OPCODE(FPOrdLessThan64, U1, F64, F64, ) | ||
| 195 | OPCODE(FPUnordLessThan16, U1, F16, F16, ) | ||
| 196 | OPCODE(FPUnordLessThan32, U1, F32, F32, ) | ||
| 197 | OPCODE(FPUnordLessThan64, U1, F64, F64, ) | ||
| 198 | OPCODE(FPOrdGreaterThan16, U1, F16, F16, ) | ||
| 199 | OPCODE(FPOrdGreaterThan32, U1, F32, F32, ) | ||
| 200 | OPCODE(FPOrdGreaterThan64, U1, F64, F64, ) | ||
| 201 | OPCODE(FPUnordGreaterThan16, U1, F16, F16, ) | ||
| 202 | OPCODE(FPUnordGreaterThan32, U1, F32, F32, ) | ||
| 203 | OPCODE(FPUnordGreaterThan64, U1, F64, F64, ) | ||
| 204 | OPCODE(FPOrdLessThanEqual16, U1, F16, F16, ) | ||
| 205 | OPCODE(FPOrdLessThanEqual32, U1, F32, F32, ) | ||
| 206 | OPCODE(FPOrdLessThanEqual64, U1, F64, F64, ) | ||
| 207 | OPCODE(FPUnordLessThanEqual16, U1, F16, F16, ) | ||
| 208 | OPCODE(FPUnordLessThanEqual32, U1, F32, F32, ) | ||
| 209 | OPCODE(FPUnordLessThanEqual64, U1, F64, F64, ) | ||
| 210 | OPCODE(FPOrdGreaterThanEqual16, U1, F16, F16, ) | ||
| 211 | OPCODE(FPOrdGreaterThanEqual32, U1, F32, F32, ) | ||
| 212 | OPCODE(FPOrdGreaterThanEqual64, U1, F64, F64, ) | ||
| 213 | OPCODE(FPUnordGreaterThanEqual16, U1, F16, F16, ) | ||
| 214 | OPCODE(FPUnordGreaterThanEqual32, U1, F32, F32, ) | ||
| 215 | OPCODE(FPUnordGreaterThanEqual64, U1, F64, F64, ) | ||
| 216 | |||
| 181 | // Integer operations | 217 | // Integer operations |
| 182 | OPCODE(IAdd32, U32, U32, U32, ) | 218 | OPCODE(IAdd32, U32, U32, U32, ) |
| 183 | OPCODE(IAdd64, U64, U64, U64, ) | 219 | OPCODE(IAdd64, U64, U64, U64, ) |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h b/src/shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h index 3da37a2bb..fd73f656c 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h | |||
| @@ -46,7 +46,8 @@ inline IR::FmzMode CastFmzMode(FmzMode fmz_mode) { | |||
| 46 | case FmzMode::FTZ: | 46 | case FmzMode::FTZ: |
| 47 | return IR::FmzMode::FTZ; | 47 | return IR::FmzMode::FTZ; |
| 48 | case FmzMode::FMZ: | 48 | case FmzMode::FMZ: |
| 49 | return IR::FmzMode::FMZ; | 49 | // FMZ is manually handled in the instruction |
| 50 | return IR::FmzMode::FTZ; | ||
| 50 | case FmzMode::INVALIDFMZ3: | 51 | case FmzMode::INVALIDFMZ3: |
| 51 | break; | 52 | break; |
| 52 | } | 53 | } |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp index 219ffcc6a..76a807d4e 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_add.cpp | |||
| @@ -53,7 +53,7 @@ void FADD(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) { | |||
| 53 | } // Anonymous namespace | 53 | } // Anonymous namespace |
| 54 | 54 | ||
| 55 | void TranslatorVisitor::FADD_reg(u64 insn) { | 55 | void TranslatorVisitor::FADD_reg(u64 insn) { |
| 56 | FADD(*this, insn, GetRegFloat20(insn)); | 56 | FADD(*this, insn, GetFloatReg20(insn)); |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | void TranslatorVisitor::FADD_cbuf(u64 insn) { | 59 | void TranslatorVisitor::FADD_cbuf(u64 insn) { |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp index 758700d3c..c2ca0873b 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_fused_multiply_add.cpp | |||
| @@ -51,7 +51,7 @@ void FFMA(TranslatorVisitor& v, u64 insn, const IR::F32& src_b, const IR::F32& s | |||
| 51 | } // Anonymous namespace | 51 | } // Anonymous namespace |
| 52 | 52 | ||
| 53 | void TranslatorVisitor::FFMA_reg(u64 insn) { | 53 | void TranslatorVisitor::FFMA_reg(u64 insn) { |
| 54 | FFMA(*this, insn, GetRegFloat20(insn), GetRegFloat39(insn)); | 54 | FFMA(*this, insn, GetFloatReg20(insn), GetFloatReg39(insn)); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | void TranslatorVisitor::FFMA_rc(u64) { | 57 | void TranslatorVisitor::FFMA_rc(u64) { |
| @@ -59,7 +59,7 @@ void TranslatorVisitor::FFMA_rc(u64) { | |||
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | void TranslatorVisitor::FFMA_cr(u64 insn) { | 61 | void TranslatorVisitor::FFMA_cr(u64 insn) { |
| 62 | FFMA(*this, insn, GetFloatCbuf(insn), GetRegFloat39(insn)); | 62 | FFMA(*this, insn, GetFloatCbuf(insn), GetFloatReg39(insn)); |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | void TranslatorVisitor::FFMA_imm(u64) { | 65 | void TranslatorVisitor::FFMA_imm(u64) { |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multi_function.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multi_function.cpp index ba005fbf4..2f8605619 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multi_function.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multi_function.cpp | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | namespace Shader::Maxwell { | 11 | namespace Shader::Maxwell { |
| 12 | namespace { | 12 | namespace { |
| 13 | enum class Operation { | 13 | enum class Operation : u64 { |
| 14 | Cos = 0, | 14 | Cos = 0, |
| 15 | Sin = 1, | 15 | Sin = 1, |
| 16 | Ex2 = 2, // Base 2 exponent | 16 | Ex2 = 2, // Base 2 exponent |
| @@ -39,11 +39,11 @@ void TranslatorVisitor::MUFU(u64 insn) { | |||
| 39 | IR::F32 value{[&]() -> IR::F32 { | 39 | IR::F32 value{[&]() -> IR::F32 { |
| 40 | switch (mufu.operation) { | 40 | switch (mufu.operation) { |
| 41 | case Operation::Cos: | 41 | case Operation::Cos: |
| 42 | return ir.FPCosNotReduced(op_a); | 42 | return ir.FPCos(op_a); |
| 43 | case Operation::Sin: | 43 | case Operation::Sin: |
| 44 | return ir.FPSinNotReduced(op_a); | 44 | return ir.FPSin(op_a); |
| 45 | case Operation::Ex2: | 45 | case Operation::Ex2: |
| 46 | return ir.FPExp2NotReduced(op_a); | 46 | return ir.FPExp2(op_a); |
| 47 | case Operation::Lg2: | 47 | case Operation::Lg2: |
| 48 | return ir.FPLog2(op_a); | 48 | return ir.FPLog2(op_a); |
| 49 | case Operation::Rcp: | 49 | case Operation::Rcp: |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp index 5c38d3fc1..edf2cadae 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_multiply.cpp | |||
| @@ -55,9 +55,6 @@ void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b, FmzMode fmz_mode | |||
| 55 | if (cc) { | 55 | if (cc) { |
| 56 | throw NotImplementedException("FMUL CC"); | 56 | throw NotImplementedException("FMUL CC"); |
| 57 | } | 57 | } |
| 58 | if (sat) { | ||
| 59 | throw NotImplementedException("FMUL SAT"); | ||
| 60 | } | ||
| 61 | IR::F32 op_a{v.F(fmul.src_a)}; | 58 | IR::F32 op_a{v.F(fmul.src_a)}; |
| 62 | if (scale != Scale::None) { | 59 | if (scale != Scale::None) { |
| 63 | if (fmz_mode != FmzMode::FTZ || fp_rounding != FpRounding::RN) { | 60 | if (fmz_mode != FmzMode::FTZ || fp_rounding != FpRounding::RN) { |
| @@ -71,7 +68,20 @@ void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b, FmzMode fmz_mode | |||
| 71 | .rounding{CastFpRounding(fp_rounding)}, | 68 | .rounding{CastFpRounding(fp_rounding)}, |
| 72 | .fmz_mode{CastFmzMode(fmz_mode)}, | 69 | .fmz_mode{CastFmzMode(fmz_mode)}, |
| 73 | }; | 70 | }; |
| 74 | v.F(fmul.dest_reg, v.ir.FPMul(op_a, op_b, fp_control)); | 71 | IR::F32 value{v.ir.FPMul(op_a, op_b, fp_control)}; |
| 72 | if (fmz_mode == FmzMode::FMZ && !sat) { | ||
| 73 | // Do not implement FMZ if SAT is enabled, as it does the logic for us. | ||
| 74 | // On D3D9 mode, anything * 0 is zero, even NAN and infinity | ||
| 75 | const IR::F32 zero{v.ir.Imm32(0.0f)}; | ||
| 76 | const IR::U1 zero_a{v.ir.FPEqual(op_a, zero)}; | ||
| 77 | const IR::U1 zero_b{v.ir.FPEqual(op_b, zero)}; | ||
| 78 | const IR::U1 any_zero{v.ir.LogicalOr(zero_a, zero_b)}; | ||
| 79 | value = IR::F32{v.ir.Select(any_zero, zero, value)}; | ||
| 80 | } | ||
| 81 | if (sat) { | ||
| 82 | value = v.ir.FPSaturate(value); | ||
| 83 | } | ||
| 84 | v.F(fmul.dest_reg, value); | ||
| 75 | } | 85 | } |
| 76 | 86 | ||
| 77 | void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) { | 87 | void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) { |
| @@ -83,27 +93,33 @@ void FMUL(TranslatorVisitor& v, u64 insn, const IR::F32& src_b) { | |||
| 83 | BitField<47, 1, u64> cc; | 93 | BitField<47, 1, u64> cc; |
| 84 | BitField<48, 1, u64> neg_b; | 94 | BitField<48, 1, u64> neg_b; |
| 85 | BitField<50, 1, u64> sat; | 95 | BitField<50, 1, u64> sat; |
| 86 | } fmul{insn}; | 96 | } const fmul{insn}; |
| 87 | |||
| 88 | FMUL(v, insn, src_b, fmul.fmz, fmul.fp_rounding, fmul.scale, fmul.sat != 0, fmul.cc != 0, | 97 | FMUL(v, insn, src_b, fmul.fmz, fmul.fp_rounding, fmul.scale, fmul.sat != 0, fmul.cc != 0, |
| 89 | fmul.neg_b != 0); | 98 | fmul.neg_b != 0); |
| 90 | } | 99 | } |
| 91 | } // Anonymous namespace | 100 | } // Anonymous namespace |
| 92 | 101 | ||
| 93 | void TranslatorVisitor::FMUL_reg(u64 insn) { | 102 | void TranslatorVisitor::FMUL_reg(u64 insn) { |
| 94 | return FMUL(*this, insn, GetRegFloat20(insn)); | 103 | return FMUL(*this, insn, GetFloatReg20(insn)); |
| 95 | } | 104 | } |
| 96 | 105 | ||
| 97 | void TranslatorVisitor::FMUL_cbuf(u64) { | 106 | void TranslatorVisitor::FMUL_cbuf(u64 insn) { |
| 98 | throw NotImplementedException("FMUL (cbuf)"); | 107 | return FMUL(*this, insn, GetFloatCbuf(insn)); |
| 99 | } | 108 | } |
| 100 | 109 | ||
| 101 | void TranslatorVisitor::FMUL_imm(u64) { | 110 | void TranslatorVisitor::FMUL_imm(u64 insn) { |
| 102 | throw NotImplementedException("FMUL (imm)"); | 111 | return FMUL(*this, insn, GetFloatImm20(insn)); |
| 103 | } | 112 | } |
| 104 | 113 | ||
| 105 | void TranslatorVisitor::FMUL32I(u64) { | 114 | void TranslatorVisitor::FMUL32I(u64 insn) { |
| 106 | throw NotImplementedException("FMUL32I"); | 115 | union { |
| 116 | u64 raw; | ||
| 117 | BitField<52, 1, u64> cc; | ||
| 118 | BitField<53, 2, FmzMode> fmz; | ||
| 119 | BitField<55, 1, u64> sat; | ||
| 120 | } const fmul32i{insn}; | ||
| 121 | FMUL(*this, insn, GetFloatImm32(insn), fmul32i.fmz, FpRounding::RN, Scale::None, | ||
| 122 | fmul32i.sat != 0, fmul32i.cc != 0, false); | ||
| 107 | } | 123 | } |
| 108 | 124 | ||
| 109 | } // namespace Shader::Maxwell \ No newline at end of file | 125 | } // namespace Shader::Maxwell \ No newline at end of file |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_range_reduction.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_range_reduction.cpp new file mode 100644 index 000000000..f91b93fad --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/floating_point_range_reduction.cpp | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/bit_field.h" | ||
| 6 | #include "common/common_types.h" | ||
| 7 | #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" | ||
| 8 | |||
| 9 | namespace Shader::Maxwell { | ||
| 10 | namespace { | ||
| 11 | enum class Mode : u64 { | ||
| 12 | SINCOS, | ||
| 13 | EX2, | ||
| 14 | }; | ||
| 15 | |||
| 16 | void RRO(TranslatorVisitor& v, u64 insn, const IR::F32& src) { | ||
| 17 | union { | ||
| 18 | u64 raw; | ||
| 19 | BitField<0, 8, IR::Reg> dest_reg; | ||
| 20 | BitField<39, 1, Mode> mode; | ||
| 21 | BitField<45, 1, u64> neg; | ||
| 22 | BitField<49, 1, u64> abs; | ||
| 23 | } const rro{insn}; | ||
| 24 | |||
| 25 | v.F(rro.dest_reg, v.ir.FPAbsNeg(src, rro.abs != 0, rro.neg != 0)); | ||
| 26 | } | ||
| 27 | } // Anonymous namespace | ||
| 28 | |||
| 29 | void TranslatorVisitor::RRO_reg(u64 insn) { | ||
| 30 | RRO(*this, insn, GetFloatReg20(insn)); | ||
| 31 | } | ||
| 32 | |||
| 33 | void TranslatorVisitor::RRO_cbuf(u64 insn) { | ||
| 34 | RRO(*this, insn, GetFloatCbuf(insn)); | ||
| 35 | } | ||
| 36 | |||
| 37 | void TranslatorVisitor::RRO_imm(u64) { | ||
| 38 | throw NotImplementedException("RRO (imm)"); | ||
| 39 | } | ||
| 40 | |||
| 41 | } // namespace Shader::Maxwell | ||
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp index 165d475b9..a5a0e1a9b 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.cpp | |||
| @@ -48,11 +48,11 @@ IR::U32 TranslatorVisitor::GetReg39(u64 insn) { | |||
| 48 | return X(reg.index); | 48 | return X(reg.index); |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | IR::F32 TranslatorVisitor::GetRegFloat20(u64 insn) { | 51 | IR::F32 TranslatorVisitor::GetFloatReg20(u64 insn) { |
| 52 | return ir.BitCast<IR::F32>(GetReg20(insn)); | 52 | return ir.BitCast<IR::F32>(GetReg20(insn)); |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | IR::F32 TranslatorVisitor::GetRegFloat39(u64 insn) { | 55 | IR::F32 TranslatorVisitor::GetFloatReg39(u64 insn) { |
| 56 | return ir.BitCast<IR::F32>(GetReg39(insn)); | 56 | return ir.BitCast<IR::F32>(GetReg39(insn)); |
| 57 | } | 57 | } |
| 58 | 58 | ||
| @@ -110,6 +110,14 @@ IR::U32 TranslatorVisitor::GetImm32(u64 insn) { | |||
| 110 | return ir.Imm32(static_cast<u32>(imm.value)); | 110 | return ir.Imm32(static_cast<u32>(imm.value)); |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | IR::F32 TranslatorVisitor::GetFloatImm32(u64 insn) { | ||
| 114 | union { | ||
| 115 | u64 raw; | ||
| 116 | BitField<20, 32, u64> value; | ||
| 117 | } const imm{insn}; | ||
| 118 | return ir.Imm32(Common::BitCast<f32>(static_cast<u32>(imm.value))); | ||
| 119 | } | ||
| 120 | |||
| 113 | void TranslatorVisitor::SetZFlag(const IR::U1& value) { | 121 | void TranslatorVisitor::SetZFlag(const IR::U1& value) { |
| 114 | ir.SetZFlag(value); | 122 | ir.SetZFlag(value); |
| 115 | } | 123 | } |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h index 4d4cf2ebf..4e722e205 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/impl.h | |||
| @@ -304,8 +304,8 @@ public: | |||
| 304 | [[nodiscard]] IR::U32 GetReg8(u64 insn); | 304 | [[nodiscard]] IR::U32 GetReg8(u64 insn); |
| 305 | [[nodiscard]] IR::U32 GetReg20(u64 insn); | 305 | [[nodiscard]] IR::U32 GetReg20(u64 insn); |
| 306 | [[nodiscard]] IR::U32 GetReg39(u64 insn); | 306 | [[nodiscard]] IR::U32 GetReg39(u64 insn); |
| 307 | [[nodiscard]] IR::F32 GetRegFloat20(u64 insn); | 307 | [[nodiscard]] IR::F32 GetFloatReg20(u64 insn); |
| 308 | [[nodiscard]] IR::F32 GetRegFloat39(u64 insn); | 308 | [[nodiscard]] IR::F32 GetFloatReg39(u64 insn); |
| 309 | 309 | ||
| 310 | [[nodiscard]] IR::U32 GetCbuf(u64 insn); | 310 | [[nodiscard]] IR::U32 GetCbuf(u64 insn); |
| 311 | [[nodiscard]] IR::F32 GetFloatCbuf(u64 insn); | 311 | [[nodiscard]] IR::F32 GetFloatCbuf(u64 insn); |
| @@ -314,6 +314,7 @@ public: | |||
| 314 | [[nodiscard]] IR::F32 GetFloatImm20(u64 insn); | 314 | [[nodiscard]] IR::F32 GetFloatImm20(u64 insn); |
| 315 | 315 | ||
| 316 | [[nodiscard]] IR::U32 GetImm32(u64 insn); | 316 | [[nodiscard]] IR::U32 GetImm32(u64 insn); |
| 317 | [[nodiscard]] IR::F32 GetFloatImm32(u64 insn); | ||
| 317 | 318 | ||
| 318 | void SetZFlag(const IR::U1& value); | 319 | void SetZFlag(const IR::U1& value); |
| 319 | void SetSFlag(const IR::U1& value); | 320 | void SetSFlag(const IR::U1& value); |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_left.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_left.cpp index d8a5158b5..20af68852 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_left.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_shift_left.cpp | |||
| @@ -50,7 +50,7 @@ void SHL(TranslatorVisitor& v, u64 insn, const IR::U32& unsafe_shift) { | |||
| 50 | // | 50 | // |
| 51 | const IR::U1 is_safe{v.ir.ILessThan(unsafe_shift, v.ir.Imm32(32), false)}; | 51 | const IR::U1 is_safe{v.ir.ILessThan(unsafe_shift, v.ir.Imm32(32), false)}; |
| 52 | const IR::U32 unsafe_result{v.ir.ShiftLeftLogical(base, unsafe_shift)}; | 52 | const IR::U32 unsafe_result{v.ir.ShiftLeftLogical(base, unsafe_shift)}; |
| 53 | result = v.ir.Select(is_safe, unsafe_result, v.ir.Imm32(0)); | 53 | result = IR::U32{v.ir.Select(is_safe, unsafe_result, v.ir.Imm32(0))}; |
| 54 | } | 54 | } |
| 55 | v.X(shl.dest_reg, result); | 55 | v.X(shl.dest_reg, result); |
| 56 | } | 56 | } |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp index 628cf1c14..4114e10be 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp | |||
| @@ -721,18 +721,6 @@ void TranslatorVisitor::RET(u64) { | |||
| 721 | ThrowNotImplemented(Opcode::RET); | 721 | ThrowNotImplemented(Opcode::RET); |
| 722 | } | 722 | } |
| 723 | 723 | ||
| 724 | void TranslatorVisitor::RRO_reg(u64) { | ||
| 725 | ThrowNotImplemented(Opcode::RRO_reg); | ||
| 726 | } | ||
| 727 | |||
| 728 | void TranslatorVisitor::RRO_cbuf(u64) { | ||
| 729 | ThrowNotImplemented(Opcode::RRO_cbuf); | ||
| 730 | } | ||
| 731 | |||
| 732 | void TranslatorVisitor::RRO_imm(u64) { | ||
| 733 | ThrowNotImplemented(Opcode::RRO_imm); | ||
| 734 | } | ||
| 735 | |||
| 736 | void TranslatorVisitor::RTT(u64) { | 724 | void TranslatorVisitor::RTT(u64) { |
| 737 | ThrowNotImplemented(Opcode::RTT); | 725 | ThrowNotImplemented(Opcode::RTT); |
| 738 | } | 726 | } |