summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-02-21 17:50:14 -0300
committerGravatar ameerj2021-07-22 21:51:22 -0400
commit704c6f353f68745168902c6c66c04bb730bd30e6 (patch)
tree71ed9654de41b5828ae2613167537d39499d2f3b /src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
parentshader: Add denorm flush support (diff)
downloadyuzu-704c6f353f68745168902c6c66c04bb730bd30e6.tar.gz
yuzu-704c6f353f68745168902c6c66c04bb730bd30e6.tar.xz
yuzu-704c6f353f68745168902c6c66c04bb730bd30e6.zip
shader: Rename, implement FADD.SAT and P2R (imm)
Diffstat (limited to 'src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp75
1 files changed, 52 insertions, 23 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
index 22117a4ee..4c0b5990d 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
@@ -7,10 +7,39 @@
7namespace Shader::Backend::SPIRV { 7namespace Shader::Backend::SPIRV {
8 8
9Id EmitIAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b) { 9Id EmitIAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b) {
10 if (inst->HasAssociatedPseudoOperation()) { 10 Id result{};
11 throw NotImplementedException("Pseudo-operations on IAdd32"); 11 if (IR::Inst* const carry{inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp)}) {
12 const Id carry_type{ctx.TypeStruct(ctx.U32[1], ctx.U32[1])};
13 const Id carry_result{ctx.OpIAddCarry(carry_type, a, b)};
14 result = ctx.OpCompositeExtract(ctx.U32[1], carry_result, 0U);
15
16 const Id carry_value{ctx.OpCompositeExtract(ctx.U32[1], carry_result, 1U)};
17 carry->SetDefinition(ctx.OpINotEqual(ctx.U1, carry_value, ctx.u32_zero_value));
18 carry->Invalidate();
19 } else {
20 result = ctx.OpIAdd(ctx.U32[1], a, b);
12 } 21 }
13 return ctx.OpIAdd(ctx.U32[1], a, b); 22 if (IR::Inst* const zero{inst->GetAssociatedPseudoOperation(IR::Opcode::GetZeroFromOp)}) {
23 zero->SetDefinition(ctx.OpIEqual(ctx.U1, result, ctx.u32_zero_value));
24 zero->Invalidate();
25 }
26 if (IR::Inst* const sign{inst->GetAssociatedPseudoOperation(IR::Opcode::GetSignFromOp)}) {
27 sign->SetDefinition(ctx.OpSLessThan(ctx.U1, result, ctx.u32_zero_value));
28 sign->Invalidate();
29 }
30 if (IR::Inst * overflow{inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp)}) {
31 // https://stackoverflow.com/questions/55468823/how-to-detect-integer-overflow-in-c
32 constexpr u32 s32_max{static_cast<u32>(std::numeric_limits<s32>::max())};
33 const Id is_positive{ctx.OpSGreaterThanEqual(ctx.U1, a, ctx.u32_zero_value)};
34 const Id sub_a{ctx.OpISub(ctx.U32[1], ctx.Constant(ctx.U32[1], s32_max), a)};
35
36 const Id positive_test{ctx.OpSGreaterThan(ctx.U1, b, sub_a)};
37 const Id negative_test{ctx.OpSLessThan(ctx.U1, b, sub_a)};
38 const Id carry_flag{ctx.OpSelect(ctx.U1, is_positive, positive_test, negative_test)};
39 overflow->SetDefinition(carry_flag);
40 overflow->Invalidate();
41 }
42 return result;
14} 43}
15 44
16void EmitIAdd64(EmitContext&) { 45void EmitIAdd64(EmitContext&) {
@@ -49,16 +78,16 @@ void EmitShiftRightArithmetic32(EmitContext&) {
49 throw NotImplementedException("SPIR-V Instruction"); 78 throw NotImplementedException("SPIR-V Instruction");
50} 79}
51 80
52void EmitBitwiseAnd32(EmitContext&) { 81Id EmitBitwiseAnd32(EmitContext& ctx, Id a, Id b) {
53 throw NotImplementedException("SPIR-V Instruction"); 82 return ctx.OpBitwiseAnd(ctx.U32[1], a, b);
54} 83}
55 84
56void EmitBitwiseOr32(EmitContext&) { 85Id EmitBitwiseOr32(EmitContext& ctx, Id a, Id b) {
57 throw NotImplementedException("SPIR-V Instruction"); 86 return ctx.OpBitwiseOr(ctx.U32[1], a, b);
58} 87}
59 88
60void EmitBitwiseXor32(EmitContext&) { 89Id EmitBitwiseXor32(EmitContext& ctx, Id a, Id b) {
61 throw NotImplementedException("SPIR-V Instruction"); 90 return ctx.OpBitwiseXor(ctx.U32[1], a, b);
62} 91}
63 92
64void EmitBitFieldInsert(EmitContext&) { 93void EmitBitFieldInsert(EmitContext&) {
@@ -77,36 +106,36 @@ Id EmitSLessThan(EmitContext& ctx, Id lhs, Id rhs) {
77 return ctx.OpSLessThan(ctx.U1, lhs, rhs); 106 return ctx.OpSLessThan(ctx.U1, lhs, rhs);
78} 107}
79 108
80void EmitULessThan(EmitContext&) { 109Id EmitULessThan(EmitContext& ctx, Id lhs, Id rhs) {
81 throw NotImplementedException("SPIR-V Instruction"); 110 return ctx.OpULessThan(ctx.U1, lhs, rhs);
82} 111}
83 112
84void EmitIEqual(EmitContext&) { 113Id EmitIEqual(EmitContext& ctx, Id lhs, Id rhs) {
85 throw NotImplementedException("SPIR-V Instruction"); 114 return ctx.OpIEqual(ctx.U1, lhs, rhs);
86} 115}
87 116
88void EmitSLessThanEqual(EmitContext&) { 117Id EmitSLessThanEqual(EmitContext& ctx, Id lhs, Id rhs) {
89 throw NotImplementedException("SPIR-V Instruction"); 118 return ctx.OpSLessThanEqual(ctx.U1, lhs, rhs);
90} 119}
91 120
92void EmitULessThanEqual(EmitContext&) { 121Id EmitULessThanEqual(EmitContext& ctx, Id lhs, Id rhs) {
93 throw NotImplementedException("SPIR-V Instruction"); 122 return ctx.OpULessThanEqual(ctx.U1, lhs, rhs);
94} 123}
95 124
96Id EmitSGreaterThan(EmitContext& ctx, Id lhs, Id rhs) { 125Id EmitSGreaterThan(EmitContext& ctx, Id lhs, Id rhs) {
97 return ctx.OpSGreaterThan(ctx.U1, lhs, rhs); 126 return ctx.OpSGreaterThan(ctx.U1, lhs, rhs);
98} 127}
99 128
100void EmitUGreaterThan(EmitContext&) { 129Id EmitUGreaterThan(EmitContext& ctx, Id lhs, Id rhs) {
101 throw NotImplementedException("SPIR-V Instruction"); 130 return ctx.OpUGreaterThan(ctx.U1, lhs, rhs);
102} 131}
103 132
104void EmitINotEqual(EmitContext&) { 133Id EmitINotEqual(EmitContext& ctx, Id lhs, Id rhs) {
105 throw NotImplementedException("SPIR-V Instruction"); 134 return ctx.OpINotEqual(ctx.U1, lhs, rhs);
106} 135}
107 136
108void EmitSGreaterThanEqual(EmitContext&) { 137Id EmitSGreaterThanEqual(EmitContext& ctx, Id lhs, Id rhs) {
109 throw NotImplementedException("SPIR-V Instruction"); 138 return ctx.OpSGreaterThanEqual(ctx.U1, lhs, rhs);
110} 139}
111 140
112Id EmitUGreaterThanEqual(EmitContext& ctx, Id lhs, Id rhs) { 141Id EmitUGreaterThanEqual(EmitContext& ctx, Id lhs, Id rhs) {