From 8332482c24136091c3fa2c95d7efdd3dd1fa9adf Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 23 Dec 2018 17:24:18 -0300 Subject: shader_decode: Implement R2P --- .../shader/decode/register_set_predicate.cpp | 29 +++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'src/video_core/shader') 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(instr.r2p.immediate_mask)); + default: + UNREACHABLE(); + return Immediate(static_cast(instr.r2p.immediate_mask)); + } + }(); + const Node mask = + Operation(OperationCode::ULogicalShiftRight, NO_PRECISE, GetRegister(instr.gpr8), + Immediate(static_cast(instr.r2p.byte))); + + constexpr u32 programmable_preds = 7; + for (u64 pred = 0; pred < programmable_preds; ++pred) { + const Node shift = Immediate(1u << static_cast(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; } -- cgit v1.2.3