summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend/ir/ir_emitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/frontend/ir/ir_emitter.cpp')
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp80
1 files changed, 53 insertions, 27 deletions
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
index 33819dd36..5d475207e 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
@@ -697,93 +697,107 @@ F16F32F64 IREmitter::FPTrunc(const F16F32F64& value, FpControl control) {
697 } 697 }
698} 698}
699 699
700U1 IREmitter::FPEqual(const F16F32F64& lhs, const F16F32F64& rhs, bool ordered) { 700U1 IREmitter::FPEqual(const F16F32F64& lhs, const F16F32F64& rhs, FpControl control, bool ordered) {
701 if (lhs.Type() != rhs.Type()) { 701 if (lhs.Type() != rhs.Type()) {
702 throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); 702 throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type());
703 } 703 }
704 switch (lhs.Type()) { 704 switch (lhs.Type()) {
705 case Type::F16: 705 case Type::F16:
706 return Inst<U1>(ordered ? Opcode::FPOrdEqual16 : Opcode::FPUnordEqual16, lhs, rhs); 706 return Inst<U1>(ordered ? Opcode::FPOrdEqual16 : Opcode::FPUnordEqual16, Flags{control},
707 lhs, rhs);
707 case Type::F32: 708 case Type::F32:
708 return Inst<U1>(ordered ? Opcode::FPOrdEqual32 : Opcode::FPUnordEqual32, lhs, rhs); 709 return Inst<U1>(ordered ? Opcode::FPOrdEqual32 : Opcode::FPUnordEqual32, Flags{control},
710 lhs, rhs);
709 case Type::F64: 711 case Type::F64:
710 return Inst<U1>(ordered ? Opcode::FPOrdEqual64 : Opcode::FPUnordEqual64, lhs, rhs); 712 return Inst<U1>(ordered ? Opcode::FPOrdEqual64 : Opcode::FPUnordEqual64, Flags{control},
713 lhs, rhs);
711 default: 714 default:
712 ThrowInvalidType(lhs.Type()); 715 ThrowInvalidType(lhs.Type());
713 } 716 }
714} 717}
715 718
716U1 IREmitter::FPNotEqual(const F16F32F64& lhs, const F16F32F64& rhs, bool ordered) { 719U1 IREmitter::FPNotEqual(const F16F32F64& lhs, const F16F32F64& rhs, FpControl control,
720 bool ordered) {
717 if (lhs.Type() != rhs.Type()) { 721 if (lhs.Type() != rhs.Type()) {
718 throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); 722 throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type());
719 } 723 }
720 switch (lhs.Type()) { 724 switch (lhs.Type()) {
721 case Type::F16: 725 case Type::F16:
722 return Inst<U1>(ordered ? Opcode::FPOrdNotEqual16 : Opcode::FPUnordNotEqual16, lhs, rhs); 726 return Inst<U1>(ordered ? Opcode::FPOrdNotEqual16 : Opcode::FPUnordNotEqual16,
727 Flags{control}, lhs, rhs);
723 case Type::F32: 728 case Type::F32:
724 return Inst<U1>(ordered ? Opcode::FPOrdNotEqual32 : Opcode::FPUnordNotEqual32, lhs, rhs); 729 return Inst<U1>(ordered ? Opcode::FPOrdNotEqual32 : Opcode::FPUnordNotEqual32,
730 Flags{control}, lhs, rhs);
725 case Type::F64: 731 case Type::F64:
726 return Inst<U1>(ordered ? Opcode::FPOrdNotEqual64 : Opcode::FPUnordNotEqual64, lhs, rhs); 732 return Inst<U1>(ordered ? Opcode::FPOrdNotEqual64 : Opcode::FPUnordNotEqual64,
733 Flags{control}, lhs, rhs);
727 default: 734 default:
728 ThrowInvalidType(lhs.Type()); 735 ThrowInvalidType(lhs.Type());
729 } 736 }
730} 737}
731 738
732U1 IREmitter::FPLessThan(const F16F32F64& lhs, const F16F32F64& rhs, bool ordered) { 739U1 IREmitter::FPLessThan(const F16F32F64& lhs, const F16F32F64& rhs, FpControl control,
740 bool ordered) {
733 if (lhs.Type() != rhs.Type()) { 741 if (lhs.Type() != rhs.Type()) {
734 throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); 742 throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type());
735 } 743 }
736 switch (lhs.Type()) { 744 switch (lhs.Type()) {
737 case Type::F16: 745 case Type::F16:
738 return Inst<U1>(ordered ? Opcode::FPOrdLessThan16 : Opcode::FPUnordLessThan16, lhs, rhs); 746 return Inst<U1>(ordered ? Opcode::FPOrdLessThan16 : Opcode::FPUnordLessThan16,
747 Flags{control}, lhs, rhs);
739 case Type::F32: 748 case Type::F32:
740 return Inst<U1>(ordered ? Opcode::FPOrdLessThan32 : Opcode::FPUnordLessThan32, lhs, rhs); 749 return Inst<U1>(ordered ? Opcode::FPOrdLessThan32 : Opcode::FPUnordLessThan32,
750 Flags{control}, lhs, rhs);
741 case Type::F64: 751 case Type::F64:
742 return Inst<U1>(ordered ? Opcode::FPOrdLessThan64 : Opcode::FPUnordLessThan64, lhs, rhs); 752 return Inst<U1>(ordered ? Opcode::FPOrdLessThan64 : Opcode::FPUnordLessThan64,
753 Flags{control}, lhs, rhs);
743 default: 754 default:
744 ThrowInvalidType(lhs.Type()); 755 ThrowInvalidType(lhs.Type());
745 } 756 }
746} 757}
747 758
748U1 IREmitter::FPGreaterThan(const F16F32F64& lhs, const F16F32F64& rhs, bool ordered) { 759U1 IREmitter::FPGreaterThan(const F16F32F64& lhs, const F16F32F64& rhs, FpControl control,
760 bool ordered) {
749 if (lhs.Type() != rhs.Type()) { 761 if (lhs.Type() != rhs.Type()) {
750 throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); 762 throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type());
751 } 763 }
752 switch (lhs.Type()) { 764 switch (lhs.Type()) {
753 case Type::F16: 765 case Type::F16:
754 return Inst<U1>(ordered ? Opcode::FPOrdGreaterThan16 : Opcode::FPUnordGreaterThan16, lhs, 766 return Inst<U1>(ordered ? Opcode::FPOrdGreaterThan16 : Opcode::FPUnordGreaterThan16,
755 rhs); 767 Flags{control}, lhs, rhs);
756 case Type::F32: 768 case Type::F32:
757 return Inst<U1>(ordered ? Opcode::FPOrdGreaterThan32 : Opcode::FPUnordGreaterThan32, lhs, 769 return Inst<U1>(ordered ? Opcode::FPOrdGreaterThan32 : Opcode::FPUnordGreaterThan32,
758 rhs); 770 Flags{control}, lhs, rhs);
759 case Type::F64: 771 case Type::F64:
760 return Inst<U1>(ordered ? Opcode::FPOrdGreaterThan64 : Opcode::FPUnordGreaterThan64, lhs, 772 return Inst<U1>(ordered ? Opcode::FPOrdGreaterThan64 : Opcode::FPUnordGreaterThan64,
761 rhs); 773 Flags{control}, lhs, rhs);
762 default: 774 default:
763 ThrowInvalidType(lhs.Type()); 775 ThrowInvalidType(lhs.Type());
764 } 776 }
765} 777}
766 778
767U1 IREmitter::FPLessThanEqual(const F16F32F64& lhs, const F16F32F64& rhs, bool ordered) { 779U1 IREmitter::FPLessThanEqual(const F16F32F64& lhs, const F16F32F64& rhs, FpControl control,
780 bool ordered) {
768 if (lhs.Type() != rhs.Type()) { 781 if (lhs.Type() != rhs.Type()) {
769 throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); 782 throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type());
770 } 783 }
771 switch (lhs.Type()) { 784 switch (lhs.Type()) {
772 case Type::F16: 785 case Type::F16:
773 return Inst<U1>(ordered ? Opcode::FPOrdLessThanEqual16 : Opcode::FPUnordLessThanEqual16, 786 return Inst<U1>(ordered ? Opcode::FPOrdLessThanEqual16 : Opcode::FPUnordLessThanEqual16,
774 lhs, rhs); 787 Flags{control}, lhs, rhs);
775 case Type::F32: 788 case Type::F32:
776 return Inst<U1>(ordered ? Opcode::FPOrdLessThanEqual32 : Opcode::FPUnordLessThanEqual32, 789 return Inst<U1>(ordered ? Opcode::FPOrdLessThanEqual32 : Opcode::FPUnordLessThanEqual32,
777 lhs, rhs); 790 Flags{control}, lhs, rhs);
778 case Type::F64: 791 case Type::F64:
779 return Inst<U1>(ordered ? Opcode::FPOrdLessThanEqual64 : Opcode::FPUnordLessThanEqual64, 792 return Inst<U1>(ordered ? Opcode::FPOrdLessThanEqual64 : Opcode::FPUnordLessThanEqual64,
780 lhs, rhs); 793 Flags{control}, lhs, rhs);
781 default: 794 default:
782 ThrowInvalidType(lhs.Type()); 795 ThrowInvalidType(lhs.Type());
783 } 796 }
784} 797}
785 798
786U1 IREmitter::FPGreaterThanEqual(const F16F32F64& lhs, const F16F32F64& rhs, bool ordered) { 799U1 IREmitter::FPGreaterThanEqual(const F16F32F64& lhs, const F16F32F64& rhs, FpControl control,
800 bool ordered) {
787 if (lhs.Type() != rhs.Type()) { 801 if (lhs.Type() != rhs.Type()) {
788 throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type()); 802 throw InvalidArgument("Mismatching types {} and {}", lhs.Type(), rhs.Type());
789 } 803 }
@@ -791,20 +805,32 @@ U1 IREmitter::FPGreaterThanEqual(const F16F32F64& lhs, const F16F32F64& rhs, boo
791 case Type::F16: 805 case Type::F16:
792 return Inst<U1>(ordered ? Opcode::FPOrdGreaterThanEqual16 806 return Inst<U1>(ordered ? Opcode::FPOrdGreaterThanEqual16
793 : Opcode::FPUnordGreaterThanEqual16, 807 : Opcode::FPUnordGreaterThanEqual16,
794 lhs, rhs); 808 Flags{control}, lhs, rhs);
795 case Type::F32: 809 case Type::F32:
796 return Inst<U1>(ordered ? Opcode::FPOrdGreaterThanEqual32 810 return Inst<U1>(ordered ? Opcode::FPOrdGreaterThanEqual32
797 : Opcode::FPUnordGreaterThanEqual32, 811 : Opcode::FPUnordGreaterThanEqual32,
798 lhs, rhs); 812 Flags{control}, lhs, rhs);
799 case Type::F64: 813 case Type::F64:
800 return Inst<U1>(ordered ? Opcode::FPOrdGreaterThanEqual64 814 return Inst<U1>(ordered ? Opcode::FPOrdGreaterThanEqual64
801 : Opcode::FPUnordGreaterThanEqual64, 815 : Opcode::FPUnordGreaterThanEqual64,
802 lhs, rhs); 816 Flags{control}, lhs, rhs);
803 default: 817 default:
804 ThrowInvalidType(lhs.Type()); 818 ThrowInvalidType(lhs.Type());
805 } 819 }
806} 820}
807 821
822U1 IREmitter::FPIsNan(const F32& value) {
823 return Inst<U1>(Opcode::FPIsNan32, value);
824}
825
826U1 IREmitter::FPOrdered(const F32& lhs, const F32& rhs) {
827 return LogicalAnd(LogicalNot(FPIsNan(lhs)), LogicalNot(FPIsNan(rhs)));
828}
829
830U1 IREmitter::FPUnordered(const F32& lhs, const F32& rhs) {
831 return LogicalOr(FPIsNan(lhs), FPIsNan(rhs));
832}
833
808U32U64 IREmitter::IAdd(const U32U64& a, const U32U64& b) { 834U32U64 IREmitter::IAdd(const U32U64& a, const U32U64& b) {
809 if (a.Type() != b.Type()) { 835 if (a.Type() != b.Type()) {
810 throw InvalidArgument("Mismatching types {} and {}", a.Type(), b.Type()); 836 throw InvalidArgument("Mismatching types {} and {}", a.Type(), b.Type());