summaryrefslogtreecommitdiffstats
path: root/src/video_core/shader/decode/bfi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/shader/decode/bfi.cpp')
-rw-r--r--src/video_core/shader/decode/bfi.cpp41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/video_core/shader/decode/bfi.cpp b/src/video_core/shader/decode/bfi.cpp
new file mode 100644
index 000000000..942d6729d
--- /dev/null
+++ b/src/video_core/shader/decode/bfi.cpp
@@ -0,0 +1,41 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/assert.h"
+#include "common/common_types.h"
+#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/shader_ir.h"
+
+namespace VideoCommon::Shader {
+
+using Tegra::Shader::Instruction;
+using Tegra::Shader::OpCode;
+
+u32 ShaderIR::DecodeBfi(BasicBlock& bb, const BasicBlock& code, u32 pc) {
+ const Instruction instr = {program_code[pc]};
+ const auto opcode = OpCode::Decode(instr);
+
+ 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();
+ return {Immediate(0), Immediate(0)};
+ }
+ }();
+ const Node insert = GetRegister(instr.gpr8);
+ const Node offset = BitfieldExtract(packed_shift, 0, 8);
+ const Node bits = BitfieldExtract(packed_shift, 8, 8);
+
+ const Node value =
+ Operation(OperationCode::UBitfieldInsert, PRECISE, base, insert, offset, bits);
+
+ SetInternalFlagsFromInteger(bb, value, instr.generates_cc);
+ SetRegister(bb, instr.gpr0, value);
+
+ return pc;
+}
+
+} // namespace VideoCommon::Shader \ No newline at end of file