diff options
author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2018-12-23 21:24:18 +0100 |
---|---|---|
committer | ReinUsesLisp <reinuseslisp@airmail.cc> | 2019-01-15 21:54:53 +0100 |
commit | 8332482c24136091c3fa2c95d7efdd3dd1fa9adf (patch) | |
tree | 64457e14c20481ee3981bee17ed0e005a0139f3f | |
parent | shader_decode: Implement CSETP (diff) | |
download | yuzu-8332482c24136091c3fa2c95d7efdd3dd1fa9adf.tar yuzu-8332482c24136091c3fa2c95d7efdd3dd1fa9adf.tar.gz yuzu-8332482c24136091c3fa2c95d7efdd3dd1fa9adf.tar.bz2 yuzu-8332482c24136091c3fa2c95d7efdd3dd1fa9adf.tar.lz yuzu-8332482c24136091c3fa2c95d7efdd3dd1fa9adf.tar.xz yuzu-8332482c24136091c3fa2c95d7efdd3dd1fa9adf.tar.zst yuzu-8332482c24136091c3fa2c95d7efdd3dd1fa9adf.zip |
-rw-r--r-- | src/video_core/shader/decode/register_set_predicate.cpp | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/src/video_core/shader/decode/register_set_predicate.cpp b/src/video_core/shader/decode/register_set_predicate.cpp index 29a348cf5..796039cd9 100644 --- a/src/video_core/shader/decode/register_set_predicate.cpp +++ b/src/video_core/shader/decode/register_set_predicate.cpp @@ -16,7 +16,34 @@ u32 ShaderIR::DecodeRegisterSetPredicate(BasicBlock& bb, u32 pc) { const Instruction instr = {program_code[pc]}; const auto opcode = OpCode::Decode(instr); - UNIMPLEMENTED(); + UNIMPLEMENTED_IF(instr.r2p.mode != Tegra::Shader::R2pMode::Pr); + + const Node apply_mask = [&]() { + switch (opcode->get().GetId()) { + case OpCode::Id::R2P_IMM: + return Immediate(static_cast<u32>(instr.r2p.immediate_mask)); + default: + UNREACHABLE(); + return Immediate(static_cast<u32>(instr.r2p.immediate_mask)); + } + }(); + const Node mask = + Operation(OperationCode::ULogicalShiftRight, NO_PRECISE, GetRegister(instr.gpr8), + Immediate(static_cast<u32>(instr.r2p.byte))); + + constexpr u32 programmable_preds = 7; + for (u64 pred = 0; pred < programmable_preds; ++pred) { + const Node shift = Immediate(1u << static_cast<u32>(pred)); + + const Node apply_compare = Operation(OperationCode::UBitwiseAnd, NO_PRECISE, apply_mask, shift); + const Node condition = Operation(OperationCode::LogicalUEqual, apply_compare, Immediate(0)); + + const Node value_compare = Operation(OperationCode::UBitwiseAnd, NO_PRECISE, mask, shift); + const Node value = Operation(OperationCode::LogicalUEqual, value_compare, Immediate(0)); + + const Node code = Operation(OperationCode::LogicalAssign, GetPredicate(pred), value); + bb.push_back(Conditional(condition, {code})); + } return pc; } |