summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend/ir
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/frontend/ir')
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp144
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.h18
-rw-r--r--src/shader_recompiler/frontend/ir/opcodes.inc50
3 files changed, 184 insertions, 28 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
364UAny IREmitter::Select(const U1& condition, const UAny& true_value, const UAny& false_value) { 364Value 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
506F32 IREmitter::FPCosNotReduced(const F32& value) { 508F32 IREmitter::FPCos(const F32& value) {
507 return Inst<F32>(Opcode::FPCosNotReduced, value); 509 return Inst<F32>(Opcode::FPCos, value);
510}
511
512F32 IREmitter::FPSin(const F32& value) {
513 return Inst<F32>(Opcode::FPSin, value);
508} 514}
509 515
510F32 IREmitter::FPExp2NotReduced(const F32& value) { 516F32 IREmitter::FPExp2(const F32& value) {
511 return Inst<F32>(Opcode::FPExp2NotReduced, value); 517 return Inst<F32>(Opcode::FPExp2, value);
512} 518}
513 519
514F32 IREmitter::FPLog2(const F32& value) { 520F32 IREmitter::FPLog2(const F32& value) {
@@ -517,9 +523,9 @@ F32 IREmitter::FPLog2(const F32& value) {
517 523
518F32F64 IREmitter::FPRecip(const F32F64& value) { 524F32F64 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
529F32F64 IREmitter::FPRecipSqrt(const F32F64& value) { 535F32F64 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
540F32 IREmitter::FPSinNotReduced(const F32& value) {
541 return Inst<F32>(Opcode::FPSinNotReduced, value);
542}
543
544F32 IREmitter::FPSqrt(const F32& value) { 546F32 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
615U1 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
631U1 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
647U1 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
663U1 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
682U1 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
701U1 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
613U32U64 IREmitter::IAdd(const U32U64& a, const U32U64& b) { 723U32U64 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
103OPCODE(CompositeExtractF64x4, F64, F64x4, U32, ) 103OPCODE(CompositeExtractF64x4, F64, F64x4, U32, )
104 104
105// Select operations 105// Select operations
106OPCODE(Select8, U8, U1, U8, U8, ) 106OPCODE(SelectU8, U8, U1, U8, U8, )
107OPCODE(Select16, U16, U1, U16, U16, ) 107OPCODE(SelectU16, U16, U1, U16, U16, )
108OPCODE(Select32, U32, U1, U32, U32, ) 108OPCODE(SelectU32, U32, U1, U32, U32, )
109OPCODE(Select64, U64, U1, U64, U64, ) 109OPCODE(SelectU64, U64, U1, U64, U64, )
110OPCODE(SelectF16, F16, U1, F16, F16, )
111OPCODE(SelectF32, F32, U1, F32, F32, )
110 112
111// Bitwise conversions 113// Bitwise conversions
112OPCODE(BitCastU16F16, U16, F16, ) 114OPCODE(BitCastU16F16, U16, F16, )
@@ -156,11 +158,8 @@ OPCODE(FPRecipSqrt32, F32, F32,
156OPCODE(FPRecipSqrt64, F64, F64, ) 158OPCODE(FPRecipSqrt64, F64, F64, )
157OPCODE(FPSqrt, F32, F32, ) 159OPCODE(FPSqrt, F32, F32, )
158OPCODE(FPSin, F32, F32, ) 160OPCODE(FPSin, F32, F32, )
159OPCODE(FPSinNotReduced, F32, F32, )
160OPCODE(FPExp2, F32, F32, ) 161OPCODE(FPExp2, F32, F32, )
161OPCODE(FPExp2NotReduced, F32, F32, )
162OPCODE(FPCos, F32, F32, ) 162OPCODE(FPCos, F32, F32, )
163OPCODE(FPCosNotReduced, F32, F32, )
164OPCODE(FPLog2, F32, F32, ) 163OPCODE(FPLog2, F32, F32, )
165OPCODE(FPSaturate16, F16, F16, ) 164OPCODE(FPSaturate16, F16, F16, )
166OPCODE(FPSaturate32, F32, F32, ) 165OPCODE(FPSaturate32, F32, F32, )
@@ -178,6 +177,43 @@ OPCODE(FPTrunc16, F16, F16,
178OPCODE(FPTrunc32, F32, F32, ) 177OPCODE(FPTrunc32, F32, F32, )
179OPCODE(FPTrunc64, F64, F64, ) 178OPCODE(FPTrunc64, F64, F64, )
180 179
180OPCODE(FPOrdEqual16, U1, F16, F16, )
181OPCODE(FPOrdEqual32, U1, F32, F32, )
182OPCODE(FPOrdEqual64, U1, F64, F64, )
183OPCODE(FPUnordEqual16, U1, F16, F16, )
184OPCODE(FPUnordEqual32, U1, F32, F32, )
185OPCODE(FPUnordEqual64, U1, F64, F64, )
186OPCODE(FPOrdNotEqual16, U1, F16, F16, )
187OPCODE(FPOrdNotEqual32, U1, F32, F32, )
188OPCODE(FPOrdNotEqual64, U1, F64, F64, )
189OPCODE(FPUnordNotEqual16, U1, F16, F16, )
190OPCODE(FPUnordNotEqual32, U1, F32, F32, )
191OPCODE(FPUnordNotEqual64, U1, F64, F64, )
192OPCODE(FPOrdLessThan16, U1, F16, F16, )
193OPCODE(FPOrdLessThan32, U1, F32, F32, )
194OPCODE(FPOrdLessThan64, U1, F64, F64, )
195OPCODE(FPUnordLessThan16, U1, F16, F16, )
196OPCODE(FPUnordLessThan32, U1, F32, F32, )
197OPCODE(FPUnordLessThan64, U1, F64, F64, )
198OPCODE(FPOrdGreaterThan16, U1, F16, F16, )
199OPCODE(FPOrdGreaterThan32, U1, F32, F32, )
200OPCODE(FPOrdGreaterThan64, U1, F64, F64, )
201OPCODE(FPUnordGreaterThan16, U1, F16, F16, )
202OPCODE(FPUnordGreaterThan32, U1, F32, F32, )
203OPCODE(FPUnordGreaterThan64, U1, F64, F64, )
204OPCODE(FPOrdLessThanEqual16, U1, F16, F16, )
205OPCODE(FPOrdLessThanEqual32, U1, F32, F32, )
206OPCODE(FPOrdLessThanEqual64, U1, F64, F64, )
207OPCODE(FPUnordLessThanEqual16, U1, F16, F16, )
208OPCODE(FPUnordLessThanEqual32, U1, F32, F32, )
209OPCODE(FPUnordLessThanEqual64, U1, F64, F64, )
210OPCODE(FPOrdGreaterThanEqual16, U1, F16, F16, )
211OPCODE(FPOrdGreaterThanEqual32, U1, F32, F32, )
212OPCODE(FPOrdGreaterThanEqual64, U1, F64, F64, )
213OPCODE(FPUnordGreaterThanEqual16, U1, F16, F16, )
214OPCODE(FPUnordGreaterThanEqual32, U1, F32, F32, )
215OPCODE(FPUnordGreaterThanEqual64, U1, F64, F64, )
216
181// Integer operations 217// Integer operations
182OPCODE(IAdd32, U32, U32, U32, ) 218OPCODE(IAdd32, U32, U32, U32, )
183OPCODE(IAdd64, U64, U64, U64, ) 219OPCODE(IAdd64, U64, U64, U64, )