diff options
| author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2018-12-21 02:02:15 -0300 | 
|---|---|---|
| committer | ReinUsesLisp <reinuseslisp@airmail.cc> | 2019-01-15 17:54:51 -0300 | 
| commit | 39f1c6246a3c5140f4c2b9a2ba3cbcaecf9521dd (patch) | |
| tree | a619359c0feefa8d035a754f03194b5adcf9cb25 /src/video_core/shader | |
| parent | 501284a81a60a19713aa0509f3db994617f44659 (diff) | |
shader_decode: Implement LOP32I
Diffstat (limited to 'src/video_core/shader')
| -rw-r--r-- | src/video_core/shader/decode/arithmetic_integer_immediate.cpp | 68 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 5 | 
2 files changed, 72 insertions, 1 deletions
diff --git a/src/video_core/shader/decode/arithmetic_integer_immediate.cpp b/src/video_core/shader/decode/arithmetic_integer_immediate.cpp index 46f340235..ee5754161 100644 --- a/src/video_core/shader/decode/arithmetic_integer_immediate.cpp +++ b/src/video_core/shader/decode/arithmetic_integer_immediate.cpp @@ -10,15 +10,81 @@  namespace VideoCommon::Shader {  using Tegra::Shader::Instruction; +using Tegra::Shader::LogicOperation;  using Tegra::Shader::OpCode; +using Tegra::Shader::Pred; +using Tegra::Shader::PredicateResultMode; +using Tegra::Shader::Register;  u32 ShaderIR::DecodeArithmeticIntegerImmediate(BasicBlock& bb, u32 pc) {      const Instruction instr = {program_code[pc]};      const auto opcode = OpCode::Decode(instr); -    UNIMPLEMENTED(); +    Node op_a = GetRegister(instr.gpr8); +    Node op_b = Immediate(static_cast<s32>(instr.alu.imm20_32)); + +    switch (opcode->get().GetId()) { +    case OpCode::Id::LOP32I: { +        UNIMPLEMENTED_IF_MSG(instr.op_32.generates_cc, +                             "Condition codes generation in LOP32I is not implemented"); + +        if (instr.alu.lop32i.invert_a) +            op_a = Operation(OperationCode::IBitwiseNot, NO_PRECISE, op_a); + +        if (instr.alu.lop32i.invert_b) +            op_b = Operation(OperationCode::IBitwiseNot, NO_PRECISE, op_b); + +        WriteLogicOperation(bb, instr.gpr0, instr.alu.lop32i.operation, op_a, op_b, +                            Tegra::Shader::PredicateResultMode::None, +                            Tegra::Shader::Pred::UnusedIndex); +        break; +    } +    default: +        UNIMPLEMENTED_MSG("Unhandled ArithmeticIntegerImmediate instruction: {}", +                          opcode->get().GetName()); +    }      return pc;  } +void ShaderIR::WriteLogicOperation(BasicBlock& bb, Register dest, LogicOperation logic_op, +                                   Node op_a, Node op_b, PredicateResultMode predicate_mode, +                                   Pred predicate) { +    const Node result = [&]() { +        switch (logic_op) { +        case LogicOperation::And: +            return Operation(OperationCode::IBitwiseAnd, PRECISE, op_a, op_b); +        case LogicOperation::Or: +            return Operation(OperationCode::IBitwiseOr, PRECISE, op_a, op_b); +        case LogicOperation::Xor: +            return Operation(OperationCode::IBitwiseXor, PRECISE, op_a, op_b); +        case LogicOperation::PassB: +            return op_b; +        default: +            UNIMPLEMENTED_MSG("Unimplemented logic operation={}", static_cast<u32>(logic_op)); +        } +    }(); + +    if (dest != Register::ZeroIndex) { +        SetRegister(bb, dest, result); +    } + +    using Tegra::Shader::PredicateResultMode; +    // Write the predicate value depending on the predicate mode. +    switch (predicate_mode) { +    case PredicateResultMode::None: +        // Do nothing. +        return; +    case PredicateResultMode::NotZero: { +        // Set the predicate to true if the result is not zero. +        const Node compare = Operation(OperationCode::LogicalIEqual, result, Immediate(0)); +        SetPredicate(bb, static_cast<u64>(predicate), compare); +        break; +    } +    default: +        UNIMPLEMENTED_MSG("Unimplemented predicate result mode: {}", +                          static_cast<u32>(predicate_mode)); +    } +} +  } // namespace VideoCommon::Shader
\ No newline at end of file diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 23a4de2a7..b67fd6531 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h @@ -697,6 +697,11 @@ private:                          Tegra::Shader::TextureProcessMode process_mode, bool depth_compare,                          bool is_array, std::size_t bias_offset, std::vector<Node>&& coords); +    void WriteLogicOperation(BasicBlock& bb, Tegra::Shader::Register dest, +                             Tegra::Shader::LogicOperation logic_op, Node op_a, Node op_b, +                             Tegra::Shader::PredicateResultMode predicate_mode, +                             Tegra::Shader::Pred predicate); +      template <typename... T>      inline Node Operation(OperationCode code, const T*... operands) {          return StoreNode(OperationNode(code, operands...));  | 
