diff options
| author | ameerj <52414509+ameerj@users.noreply.github.com> | 2021-02-24 20:31:15 -0500 | 
|---|---|---|
| committer | ameerj <52414509+ameerj@users.noreply.github.com> | 2021-07-22 21:51:22 -0400 | 
| commit | 8810c88b7e3de2766bf47e07e941fb2c58c6b4b0 (patch) | |
| tree | 73619b1563eefc7103687de8e78bcf3f750812f7 | |
| parent | 726625cf5057157fb5e4c9c210676930ff520dd2 (diff) | |
shader: Implement SEL
4 files changed, 53 insertions, 16 deletions
diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt index 5574feaa6..17ccb3d98 100644 --- a/src/shader_recompiler/CMakeLists.txt +++ b/src/shader_recompiler/CMakeLists.txt @@ -79,6 +79,7 @@ add_library(shader_recompiler STATIC      frontend/maxwell/translate/impl/move_register.cpp      frontend/maxwell/translate/impl/move_special_register.cpp      frontend/maxwell/translate/impl/not_implemented.cpp +    frontend/maxwell/translate/impl/select_source_with_predicate.cpp      frontend/maxwell/translate/translate.cpp      frontend/maxwell/translate/translate.h      ir_opt/collect_shader_info_pass.cpp diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp index 3f6dedfdd..82c73bf8c 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp @@ -729,18 +729,6 @@ void TranslatorVisitor::SAM(u64) {      ThrowNotImplemented(Opcode::SAM);  } -void TranslatorVisitor::SEL_reg(u64) { -    ThrowNotImplemented(Opcode::SEL_reg); -} - -void TranslatorVisitor::SEL_cbuf(u64) { -    ThrowNotImplemented(Opcode::SEL_cbuf); -} - -void TranslatorVisitor::SEL_imm(u64) { -    ThrowNotImplemented(Opcode::SEL_imm); -} -  void TranslatorVisitor::SETCRSPTR(u64) {      ThrowNotImplemented(Opcode::SETCRSPTR);  } diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/select_source_with_predicate.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/select_source_with_predicate.cpp new file mode 100644 index 000000000..25fc6b437 --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/select_source_with_predicate.cpp @@ -0,0 +1,44 @@ +// Copyright 2021 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/bit_field.h" +#include "common/common_types.h" +#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" + +namespace Shader::Maxwell { +namespace { + +void SEL(TranslatorVisitor& v, u64 insn, const IR::U32& src) { +    union { +        u64 raw; +        BitField<0, 8, IR::Reg> dest_reg; +        BitField<8, 8, IR::Reg> op_a; +        BitField<39, 3, IR::Pred> pred; +        BitField<42, 1, u64> neg_pred; +    } const sel{insn}; + +    const IR::U1 pred = v.ir.GetPred(sel.pred); +    IR::U32 op_a{v.X(sel.op_a)}; +    IR::U32 op_b{src}; +    if (sel.neg_pred != 0) { +        std::swap(op_a, op_b); +    } +    const IR::U32 result{v.ir.Select(pred, op_a, op_b)}; + +    v.X(sel.dest_reg, result); +} +} // Anonymous namespace + +void TranslatorVisitor::SEL_reg(u64 insn) { +    SEL(*this, insn, GetReg20(insn)); +} + +void TranslatorVisitor::SEL_cbuf(u64 insn) { +    SEL(*this, insn, GetCbuf(insn)); +} + +void TranslatorVisitor::SEL_imm(u64 insn) { +    SEL(*this, insn, GetImm20(insn)); +} +} // namespace Shader::Maxwell diff --git a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp index 13f9c914a..19d35b1f8 100644 --- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp +++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp @@ -109,11 +109,13 @@ IR::Opcode UndefOpcode(const FlagTag&) noexcept {  class Pass {  public: -    void WriteVariable(auto variable, IR::Block* block, const IR::Value& value) { +    template <typename Type> +    void WriteVariable(Type variable, IR::Block* block, const IR::Value& value) {          current_def[variable].insert_or_assign(block, value);      } -    IR::Value ReadVariable(auto variable, IR::Block* block) { +    template <typename Type> +    IR::Value ReadVariable(Type variable, IR::Block* block) {          const ValueMap& def{current_def[variable]};          if (const auto it{def.find(block)}; it != def.end()) {              return it->second; @@ -132,7 +134,8 @@ public:      }  private: -    IR::Value ReadVariableRecursive(auto variable, IR::Block* block) { +    template <typename Type> +    IR::Value ReadVariableRecursive(Type variable, IR::Block* block) {          IR::Value val;          if (!sealed_blocks.contains(block)) {              // Incomplete CFG @@ -154,7 +157,8 @@ private:          return val;      } -    IR::Value AddPhiOperands(auto variable, IR::Inst& phi, IR::Block* block) { +    template <typename Type> +    IR::Value AddPhiOperands(Type variable, IR::Inst& phi, IR::Block* block) {          for (IR::Block* const imm_pred : block->ImmediatePredecessors()) {              phi.AddPhiOperand(imm_pred, ReadVariable(variable, imm_pred));          }  | 
