diff options
| author | 2021-03-17 00:53:53 -0400 | |
|---|---|---|
| committer | 2021-07-22 21:51:23 -0400 | |
| commit | 3b7fd3ad0fcb0419c455c16127f43d01b6dc7fc9 (patch) | |
| tree | 194884a206ae5c4719fa4ddeeca1c3aa45acec36 /src/shader_recompiler/frontend/ir | |
| parent | shader: Reorder phi nodes when redefined as undefined opcodes (diff) | |
| download | yuzu-3b7fd3ad0fcb0419c455c16127f43d01b6dc7fc9.tar.gz yuzu-3b7fd3ad0fcb0419c455c16127f43d01b6dc7fc9.tar.xz yuzu-3b7fd3ad0fcb0419c455c16127f43d01b6dc7fc9.zip | |
shader: Implement CSET and CSETP
Diffstat (limited to '')
| -rw-r--r-- | src/shader_recompiler/frontend/ir/flow_test.h | 5 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/ir_emitter.cpp | 60 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/ir_emitter.h | 1 |
3 files changed, 59 insertions, 7 deletions
diff --git a/src/shader_recompiler/frontend/ir/flow_test.h b/src/shader_recompiler/frontend/ir/flow_test.h index ac883da13..09e113773 100644 --- a/src/shader_recompiler/frontend/ir/flow_test.h +++ b/src/shader_recompiler/frontend/ir/flow_test.h | |||
| @@ -5,12 +5,13 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <string> | 7 | #include <string> |
| 8 | |||
| 9 | #include <fmt/format.h> | 8 | #include <fmt/format.h> |
| 10 | 9 | ||
| 10 | #include "common/common_types.h" | ||
| 11 | |||
| 11 | namespace Shader::IR { | 12 | namespace Shader::IR { |
| 12 | 13 | ||
| 13 | enum class FlowTest { | 14 | enum class FlowTest : u64 { |
| 14 | F, | 15 | F, |
| 15 | LT, | 16 | LT, |
| 16 | EQ, | 17 | EQ, |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index d94596ee9..958282160 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -169,16 +169,62 @@ void IREmitter::SetOFlag(const U1& value) { | |||
| 169 | 169 | ||
| 170 | static U1 GetFlowTest(IREmitter& ir, FlowTest flow_test) { | 170 | static U1 GetFlowTest(IREmitter& ir, FlowTest flow_test) { |
| 171 | switch (flow_test) { | 171 | switch (flow_test) { |
| 172 | case FlowTest::T: | ||
| 173 | return ir.Imm1(true); | ||
| 174 | case FlowTest::F: | 172 | case FlowTest::F: |
| 175 | return ir.Imm1(false); | 173 | return ir.Imm1(false); |
| 174 | case FlowTest::LT: | ||
| 175 | return ir.LogicalXor(ir.LogicalAnd(ir.GetSFlag(), ir.LogicalNot(ir.GetZFlag())), | ||
| 176 | ir.GetOFlag()); | ||
| 176 | case FlowTest::EQ: | 177 | case FlowTest::EQ: |
| 177 | // TODO: Test this | 178 | return ir.LogicalAnd(ir.LogicalNot(ir.GetSFlag()), ir.GetZFlag()); |
| 178 | return ir.GetZFlag(); | 179 | case FlowTest::LE: |
| 180 | return ir.LogicalXor(ir.GetSFlag(), ir.LogicalOr(ir.GetZFlag(), ir.GetOFlag())); | ||
| 181 | case FlowTest::GT: | ||
| 182 | return ir.LogicalAnd(ir.LogicalXor(ir.LogicalNot(ir.GetSFlag()), ir.GetOFlag()), | ||
| 183 | ir.LogicalNot(ir.GetZFlag())); | ||
| 179 | case FlowTest::NE: | 184 | case FlowTest::NE: |
| 180 | // TODO: Test this | ||
| 181 | return ir.LogicalNot(ir.GetZFlag()); | 185 | return ir.LogicalNot(ir.GetZFlag()); |
| 186 | case FlowTest::GE: | ||
| 187 | return ir.LogicalNot(ir.LogicalXor(ir.GetSFlag(), ir.GetOFlag())); | ||
| 188 | case FlowTest::NUM: | ||
| 189 | return ir.LogicalOr(ir.LogicalNot(ir.GetSFlag()), ir.LogicalNot(ir.GetZFlag())); | ||
| 190 | case FlowTest::NaN: | ||
| 191 | return ir.LogicalAnd(ir.GetSFlag(), ir.GetZFlag()); | ||
| 192 | case FlowTest::LTU: | ||
| 193 | return ir.LogicalXor(ir.GetSFlag(), ir.GetOFlag()); | ||
| 194 | case FlowTest::EQU: | ||
| 195 | return ir.GetZFlag(); | ||
| 196 | case FlowTest::LEU: | ||
| 197 | return ir.LogicalOr(ir.LogicalXor(ir.GetSFlag(), ir.GetOFlag()), ir.GetZFlag()); | ||
| 198 | case FlowTest::GTU: | ||
| 199 | return ir.LogicalXor(ir.LogicalNot(ir.GetSFlag()), | ||
| 200 | ir.LogicalOr(ir.GetZFlag(), ir.GetOFlag())); | ||
| 201 | case FlowTest::NEU: | ||
| 202 | return ir.LogicalOr(ir.GetSFlag(), ir.LogicalNot(ir.GetZFlag())); | ||
| 203 | case FlowTest::GEU: | ||
| 204 | return ir.LogicalXor(ir.LogicalOr(ir.LogicalNot(ir.GetSFlag()), ir.GetZFlag()), | ||
| 205 | ir.GetOFlag()); | ||
| 206 | case FlowTest::T: | ||
| 207 | return ir.Imm1(true); | ||
| 208 | case FlowTest::OFF: | ||
| 209 | return ir.LogicalNot(ir.GetOFlag()); | ||
| 210 | case FlowTest::LO: | ||
| 211 | return ir.LogicalNot(ir.GetCFlag()); | ||
| 212 | case FlowTest::SFF: | ||
| 213 | return ir.LogicalNot(ir.GetSFlag()); | ||
| 214 | case FlowTest::LS: | ||
| 215 | return ir.LogicalOr(ir.GetZFlag(), ir.LogicalNot(ir.GetCFlag())); | ||
| 216 | case FlowTest::HI: | ||
| 217 | return ir.LogicalAnd(ir.GetCFlag(), ir.LogicalNot(ir.GetZFlag())); | ||
| 218 | case FlowTest::SFT: | ||
| 219 | return ir.GetSFlag(); | ||
| 220 | case FlowTest::HS: | ||
| 221 | return ir.GetCFlag(); | ||
| 222 | case FlowTest::OFT: | ||
| 223 | return ir.GetOFlag(); | ||
| 224 | case FlowTest::RLE: | ||
| 225 | return ir.LogicalOr(ir.GetSFlag(), ir.GetZFlag()); | ||
| 226 | case FlowTest::RGT: | ||
| 227 | return ir.LogicalAnd(ir.LogicalNot(ir.GetSFlag()), ir.LogicalNot(ir.GetZFlag())); | ||
| 182 | default: | 228 | default: |
| 183 | throw NotImplementedException("Flow test {}", flow_test); | 229 | throw NotImplementedException("Flow test {}", flow_test); |
| 184 | } | 230 | } |
| @@ -190,6 +236,10 @@ U1 IREmitter::Condition(IR::Condition cond) { | |||
| 190 | return LogicalAnd(GetPred(pred, is_negated), GetFlowTest(*this, flow_test)); | 236 | return LogicalAnd(GetPred(pred, is_negated), GetFlowTest(*this, flow_test)); |
| 191 | } | 237 | } |
| 192 | 238 | ||
| 239 | U1 IREmitter::GetFlowTestResult(FlowTest test) { | ||
| 240 | return GetFlowTest(*this, test); | ||
| 241 | } | ||
| 242 | |||
| 193 | F32 IREmitter::GetAttribute(IR::Attribute attribute) { | 243 | F32 IREmitter::GetAttribute(IR::Attribute attribute) { |
| 194 | return Inst<F32>(Opcode::GetAttribute, attribute); | 244 | return Inst<F32>(Opcode::GetAttribute, attribute); |
| 195 | } | 245 | } |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index 27ff5a29d..05263fe8b 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h | |||
| @@ -62,6 +62,7 @@ public: | |||
| 62 | void SetOFlag(const U1& value); | 62 | void SetOFlag(const U1& value); |
| 63 | 63 | ||
| 64 | [[nodiscard]] U1 Condition(IR::Condition cond); | 64 | [[nodiscard]] U1 Condition(IR::Condition cond); |
| 65 | [[nodiscard]] U1 GetFlowTestResult(FlowTest test); | ||
| 65 | 66 | ||
| 66 | [[nodiscard]] F32 GetAttribute(IR::Attribute attribute); | 67 | [[nodiscard]] F32 GetAttribute(IR::Attribute attribute); |
| 67 | void SetAttribute(IR::Attribute attribute, const F32& value); | 68 | void SetAttribute(IR::Attribute attribute, const F32& value); |