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/ir_emitter.cpp | |
| 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 'src/shader_recompiler/frontend/ir/ir_emitter.cpp')
| -rw-r--r-- | src/shader_recompiler/frontend/ir/ir_emitter.cpp | 60 |
1 files changed, 55 insertions, 5 deletions
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 | } |