diff options
| author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2018-12-17 17:09:23 -0300 |
|---|---|---|
| committer | ReinUsesLisp <reinuseslisp@airmail.cc> | 2019-01-15 17:54:51 -0300 |
| commit | 9516ef648d3752e08fb7753e40d809d18cb9f3b2 (patch) | |
| tree | 5638dffc94d78eb26fffbff72bdef4272b1f52d1 /src/video_core/shader/decode/bfi.cpp | |
| parent | 1fa5026f8d9bfee8f7146e5da0437d6c2456053e (diff) | |
shader_decode: Implement BFI
Diffstat (limited to 'src/video_core/shader/decode/bfi.cpp')
| -rw-r--r-- | src/video_core/shader/decode/bfi.cpp | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/src/video_core/shader/decode/bfi.cpp b/src/video_core/shader/decode/bfi.cpp index b94d46ce6c..6a851b22e6 100644 --- a/src/video_core/shader/decode/bfi.cpp +++ b/src/video_core/shader/decode/bfi.cpp @@ -16,7 +16,28 @@ u32 ShaderIR::DecodeBfi(BasicBlock& bb, u32 pc) { const Instruction instr = {program_code[pc]}; const auto opcode = OpCode::Decode(instr); - UNIMPLEMENTED(); + UNIMPLEMENTED_IF(instr.generates_cc); + + const auto [base, packed_shift] = [&]() -> std::tuple<Node, Node> { + switch (opcode->get().GetId()) { + case OpCode::Id::BFI_IMM_R: + return {GetRegister(instr.gpr39), Immediate(instr.alu.GetSignedImm20_20())}; + default: + UNREACHABLE(); + } + }(); + const Node insert = GetRegister(instr.gpr8); + + const Node offset = + Operation(OperationCode::UBitwiseAnd, NO_PRECISE, packed_shift, Immediate(0xff)); + + Node bits = + Operation(OperationCode::ULogicalShiftRight, NO_PRECISE, packed_shift, Immediate(8)); + bits = Operation(OperationCode::UBitwiseAnd, NO_PRECISE, bits, Immediate(0xff)); + + const Node value = + Operation(OperationCode::UBitfieldInsert, PRECISE, base, insert, offset, bits); + SetRegister(bb, instr.gpr0, value); return pc; } |
