summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend/maxwell
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell')
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_funnel_shift.cpp77
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp16
2 files changed, 77 insertions, 16 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_funnel_shift.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_funnel_shift.cpp
new file mode 100644
index 000000000..d8d6c939e
--- /dev/null
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_funnel_shift.cpp
@@ -0,0 +1,77 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/bit_field.h"
6#include "common/common_types.h"
7#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
8
9namespace Shader::Maxwell {
10namespace {
11enum class MaxShift : u64 {
12 U32,
13 Undefined,
14 U64,
15 S64,
16};
17
18IR::U64 PackedShift(IR::IREmitter& ir, const IR::U64& packed_int, const IR::U32& safe_shift,
19 bool right_shift, bool is_signed) {
20 if (!right_shift) {
21 return ir.ShiftLeftLogical(packed_int, safe_shift);
22 }
23 if (is_signed) {
24 return ir.ShiftRightArithmetic(packed_int, safe_shift);
25 }
26 return ir.ShiftRightLogical(packed_int, safe_shift);
27}
28
29void SHF(TranslatorVisitor& v, u64 insn, const IR::U32& shift, const IR::U32& high_bits,
30 bool right_shift) {
31 union {
32 u64 insn;
33 BitField<0, 8, IR::Reg> dest_reg;
34 BitField<0, 8, IR::Reg> lo_bits_reg;
35 BitField<37, 2, MaxShift> max_shift;
36 BitField<48, 2, u64> x_mode;
37 BitField<50, 1, u64> wrap;
38 } const shf{insn};
39 if (shf.x_mode != 0) {
40 throw NotImplementedException("SHF X Mode");
41 }
42 if (shf.max_shift == MaxShift::Undefined) {
43 throw NotImplementedException("SHF Use of undefined MaxShift value");
44 }
45 const IR::U32 low_bits{v.X(shf.lo_bits_reg)};
46 const IR::U64 packed_int{v.ir.PackUint2x32(v.ir.CompositeConstruct(low_bits, high_bits))};
47 const IR::U32 max_shift{shf.max_shift == MaxShift::U32 ? v.ir.Imm32(32) : v.ir.Imm32(63)};
48 const IR::U32 safe_shift{shf.wrap != 0
49 ? v.ir.BitwiseAnd(shift, v.ir.ISub(max_shift, v.ir.Imm32(1)))
50 : v.ir.UMin(shift, max_shift)};
51
52 const bool is_signed{shf.max_shift == MaxShift::S64};
53 const IR::U64 shifted_value{PackedShift(v.ir, packed_int, safe_shift, right_shift, is_signed)};
54 const IR::Value unpacked_value{v.ir.UnpackUint2x32(shifted_value)};
55
56 const IR::U32 result{v.ir.CompositeExtract(unpacked_value, right_shift ? 0 : 1)};
57 v.X(shf.dest_reg, result);
58}
59} // Anonymous namespace
60
61void TranslatorVisitor::SHF_l_reg(u64 insn) {
62 SHF(*this, insn, GetReg20(insn), GetReg39(insn), false);
63}
64
65void TranslatorVisitor::SHF_l_imm(u64 insn) {
66 SHF(*this, insn, GetImm20(insn), GetReg39(insn), false);
67}
68
69void TranslatorVisitor::SHF_r_reg(u64 insn) {
70 SHF(*this, insn, GetReg20(insn), GetReg39(insn), true);
71}
72
73void TranslatorVisitor::SHF_r_imm(u64 insn) {
74 SHF(*this, insn, GetImm20(insn), GetReg39(insn), true);
75}
76
77} // namespace Shader::Maxwell
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
index 62863aff6..2ab90d1bf 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp
@@ -553,22 +553,6 @@ void TranslatorVisitor::SETLMEMBASE(u64) {
553 ThrowNotImplemented(Opcode::SETLMEMBASE); 553 ThrowNotImplemented(Opcode::SETLMEMBASE);
554} 554}
555 555
556void TranslatorVisitor::SHF_l_reg(u64) {
557 ThrowNotImplemented(Opcode::SHF_l_reg);
558}
559
560void TranslatorVisitor::SHF_l_imm(u64) {
561 ThrowNotImplemented(Opcode::SHF_l_imm);
562}
563
564void TranslatorVisitor::SHF_r_reg(u64) {
565 ThrowNotImplemented(Opcode::SHF_r_reg);
566}
567
568void TranslatorVisitor::SHF_r_imm(u64) {
569 ThrowNotImplemented(Opcode::SHF_r_imm);
570}
571
572void TranslatorVisitor::SHFL(u64) { 556void TranslatorVisitor::SHFL(u64) {
573 ThrowNotImplemented(Opcode::SHFL); 557 ThrowNotImplemented(Opcode::SHFL);
574} 558}