diff options
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/impl/integer_funnel_shift.cpp | 77 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp | 16 |
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 | |||
| 9 | namespace Shader::Maxwell { | ||
| 10 | namespace { | ||
| 11 | enum class MaxShift : u64 { | ||
| 12 | U32, | ||
| 13 | Undefined, | ||
| 14 | U64, | ||
| 15 | S64, | ||
| 16 | }; | ||
| 17 | |||
| 18 | IR::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 | |||
| 29 | void 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 | |||
| 61 | void TranslatorVisitor::SHF_l_reg(u64 insn) { | ||
| 62 | SHF(*this, insn, GetReg20(insn), GetReg39(insn), false); | ||
| 63 | } | ||
| 64 | |||
| 65 | void TranslatorVisitor::SHF_l_imm(u64 insn) { | ||
| 66 | SHF(*this, insn, GetImm20(insn), GetReg39(insn), false); | ||
| 67 | } | ||
| 68 | |||
| 69 | void TranslatorVisitor::SHF_r_reg(u64 insn) { | ||
| 70 | SHF(*this, insn, GetReg20(insn), GetReg39(insn), true); | ||
| 71 | } | ||
| 72 | |||
| 73 | void 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 | ||
| 556 | void TranslatorVisitor::SHF_l_reg(u64) { | ||
| 557 | ThrowNotImplemented(Opcode::SHF_l_reg); | ||
| 558 | } | ||
| 559 | |||
| 560 | void TranslatorVisitor::SHF_l_imm(u64) { | ||
| 561 | ThrowNotImplemented(Opcode::SHF_l_imm); | ||
| 562 | } | ||
| 563 | |||
| 564 | void TranslatorVisitor::SHF_r_reg(u64) { | ||
| 565 | ThrowNotImplemented(Opcode::SHF_r_reg); | ||
| 566 | } | ||
| 567 | |||
| 568 | void TranslatorVisitor::SHF_r_imm(u64) { | ||
| 569 | ThrowNotImplemented(Opcode::SHF_r_imm); | ||
| 570 | } | ||
| 571 | |||
| 572 | void TranslatorVisitor::SHFL(u64) { | 556 | void TranslatorVisitor::SHFL(u64) { |
| 573 | ThrowNotImplemented(Opcode::SHFL); | 557 | ThrowNotImplemented(Opcode::SHFL); |
| 574 | } | 558 | } |