diff options
| author | 2021-03-02 14:59:28 -0500 | |
|---|---|---|
| committer | 2021-07-22 21:51:23 -0400 | |
| commit | 382cba94ed52f4fae7db437a3056563ba2110e8b (patch) | |
| tree | 2e0b0f80bf35810e08fb27680032df7865069f35 /src/shader_recompiler/frontend/maxwell/translate/impl | |
| parent | shader: Implement PSETP (diff) | |
| download | yuzu-382cba94ed52f4fae7db437a3056563ba2110e8b.tar.gz yuzu-382cba94ed52f4fae7db437a3056563ba2110e8b.tar.xz yuzu-382cba94ed52f4fae7db437a3056563ba2110e8b.zip | |
shader: Implement IADD3
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/translate/impl')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/impl/integer_add_three_input.cpp | 103 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp | 12 |
2 files changed, 103 insertions, 12 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/integer_add_three_input.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_add_three_input.cpp new file mode 100644 index 000000000..c2dbd7998 --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/integer_add_three_input.cpp | |||
| @@ -0,0 +1,103 @@ | |||
| 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 Shift : u64 { | ||
| 12 | None, | ||
| 13 | Right, | ||
| 14 | Left, | ||
| 15 | }; | ||
| 16 | enum class Half : u64 { | ||
| 17 | All, | ||
| 18 | Lower, | ||
| 19 | Upper, | ||
| 20 | }; | ||
| 21 | |||
| 22 | [[nodiscard]] IR::U32 IntegerHalf(IR::IREmitter& ir, const IR::U32& value, Half half) { | ||
| 23 | constexpr bool is_signed{false}; | ||
| 24 | switch (half) { | ||
| 25 | case Half::Lower: | ||
| 26 | return ir.BitFieldExtract(value, ir.Imm32(0), ir.Imm32(16), is_signed); | ||
| 27 | case Half::Upper: | ||
| 28 | return ir.BitFieldExtract(value, ir.Imm32(16), ir.Imm32(16), is_signed); | ||
| 29 | default: | ||
| 30 | return value; | ||
| 31 | } | ||
| 32 | } | ||
| 33 | |||
| 34 | [[nodiscard]] IR::U32 IntegerShift(IR::IREmitter& ir, const IR::U32& value, Shift shift) { | ||
| 35 | switch (shift) { | ||
| 36 | case Shift::Right: | ||
| 37 | return ir.ShiftRightLogical(value, ir.Imm32(16)); | ||
| 38 | case Shift::Left: | ||
| 39 | return ir.ShiftLeftLogical(value, ir.Imm32(16)); | ||
| 40 | default: | ||
| 41 | return value; | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 45 | void IADD3(TranslatorVisitor& v, u64 insn, IR::U32 op_b, IR::U32 op_c) { | ||
| 46 | union { | ||
| 47 | u64 insn; | ||
| 48 | BitField<0, 8, IR::Reg> dest_reg; | ||
| 49 | BitField<8, 8, IR::Reg> src_a; | ||
| 50 | BitField<31, 2, Half> half_c; | ||
| 51 | BitField<33, 2, Half> half_b; | ||
| 52 | BitField<35, 2, Half> half_a; | ||
| 53 | BitField<37, 2, Shift> shift; | ||
| 54 | BitField<47, 1, u64> cc; | ||
| 55 | BitField<48, 1, u64> x; | ||
| 56 | BitField<49, 1, u64> neg_c; | ||
| 57 | BitField<50, 1, u64> neg_b; | ||
| 58 | BitField<51, 1, u64> neg_a; | ||
| 59 | } iadd3{insn}; | ||
| 60 | |||
| 61 | if (iadd3.x != 0) { | ||
| 62 | throw NotImplementedException("IADD3 X"); | ||
| 63 | } | ||
| 64 | if (iadd3.cc != 0) { | ||
| 65 | throw NotImplementedException("IADD3 CC"); | ||
| 66 | } | ||
| 67 | |||
| 68 | IR::U32 op_a{v.X(iadd3.src_a)}; | ||
| 69 | op_a = IntegerHalf(v.ir, op_a, iadd3.half_a); | ||
| 70 | op_b = IntegerHalf(v.ir, op_b, iadd3.half_b); | ||
| 71 | op_c = IntegerHalf(v.ir, op_c, iadd3.half_c); | ||
| 72 | |||
| 73 | if (iadd3.neg_a != 0) { | ||
| 74 | op_a = v.ir.INeg(op_a); | ||
| 75 | } | ||
| 76 | if (iadd3.neg_b != 0) { | ||
| 77 | op_b = v.ir.INeg(op_b); | ||
| 78 | } | ||
| 79 | if (iadd3.neg_c != 0) { | ||
| 80 | op_c = v.ir.INeg(op_c); | ||
| 81 | } | ||
| 82 | |||
| 83 | IR::U32 lhs{v.ir.IAdd(op_a, op_b)}; | ||
| 84 | lhs = IntegerShift(v.ir, lhs, iadd3.shift); | ||
| 85 | const IR::U32 result{v.ir.IAdd(lhs, op_c)}; | ||
| 86 | |||
| 87 | v.X(iadd3.dest_reg, result); | ||
| 88 | } | ||
| 89 | } // Anonymous namespace | ||
| 90 | |||
| 91 | void TranslatorVisitor::IADD3_reg(u64 insn) { | ||
| 92 | IADD3(*this, insn, GetReg20(insn), GetReg39(insn)); | ||
| 93 | } | ||
| 94 | |||
| 95 | void TranslatorVisitor::IADD3_cbuf(u64 insn) { | ||
| 96 | IADD3(*this, insn, GetCbuf(insn), GetReg39(insn)); | ||
| 97 | } | ||
| 98 | |||
| 99 | void TranslatorVisitor::IADD3_imm(u64 insn) { | ||
| 100 | IADD3(*this, insn, GetImm20(insn), GetReg39(insn)); | ||
| 101 | } | ||
| 102 | |||
| 103 | } // 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 91a9858c6..c93304a67 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp | |||
| @@ -365,18 +365,6 @@ void TranslatorVisitor::I2I_imm(u64) { | |||
| 365 | ThrowNotImplemented(Opcode::I2I_imm); | 365 | ThrowNotImplemented(Opcode::I2I_imm); |
| 366 | } | 366 | } |
| 367 | 367 | ||
| 368 | void TranslatorVisitor::IADD3_reg(u64) { | ||
| 369 | ThrowNotImplemented(Opcode::IADD3_reg); | ||
| 370 | } | ||
| 371 | |||
| 372 | void TranslatorVisitor::IADD3_cbuf(u64) { | ||
| 373 | ThrowNotImplemented(Opcode::IADD3_cbuf); | ||
| 374 | } | ||
| 375 | |||
| 376 | void TranslatorVisitor::IADD3_imm(u64) { | ||
| 377 | ThrowNotImplemented(Opcode::IADD3_imm); | ||
| 378 | } | ||
| 379 | |||
| 380 | void TranslatorVisitor::IDE(u64) { | 368 | void TranslatorVisitor::IDE(u64) { |
| 381 | ThrowNotImplemented(Opcode::IDE); | 369 | ThrowNotImplemented(Opcode::IDE); |
| 382 | } | 370 | } |