summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar ameerj2021-03-02 14:59:28 -0500
committerGravatar ameerj2021-07-22 21:51:23 -0400
commit382cba94ed52f4fae7db437a3056563ba2110e8b (patch)
tree2e0b0f80bf35810e08fb27680032df7865069f35
parentshader: Implement PSETP (diff)
downloadyuzu-382cba94ed52f4fae7db437a3056563ba2110e8b.tar.gz
yuzu-382cba94ed52f4fae7db437a3056563ba2110e8b.tar.xz
yuzu-382cba94ed52f4fae7db437a3056563ba2110e8b.zip
shader: Implement IADD3
Diffstat (limited to '')
-rw-r--r--src/shader_recompiler/CMakeLists.txt1
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/integer_add_three_input.cpp103
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp12
3 files changed, 104 insertions, 12 deletions
diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt
index 981a79e44..8a0f73a4d 100644
--- a/src/shader_recompiler/CMakeLists.txt
+++ b/src/shader_recompiler/CMakeLists.txt
@@ -74,6 +74,7 @@ add_library(shader_recompiler STATIC
74 frontend/maxwell/translate/impl/impl.cpp 74 frontend/maxwell/translate/impl/impl.cpp
75 frontend/maxwell/translate/impl/impl.h 75 frontend/maxwell/translate/impl/impl.h
76 frontend/maxwell/translate/impl/integer_add.cpp 76 frontend/maxwell/translate/impl/integer_add.cpp
77 frontend/maxwell/translate/impl/integer_add_three_input.cpp
77 frontend/maxwell/translate/impl/integer_compare.cpp 78 frontend/maxwell/translate/impl/integer_compare.cpp
78 frontend/maxwell/translate/impl/integer_compare_and_set.cpp 79 frontend/maxwell/translate/impl/integer_compare_and_set.cpp
79 frontend/maxwell/translate/impl/integer_minimum_maximum.cpp 80 frontend/maxwell/translate/impl/integer_minimum_maximum.cpp
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
9namespace Shader::Maxwell {
10namespace {
11enum class Shift : u64 {
12 None,
13 Right,
14 Left,
15};
16enum 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
45void 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
91void TranslatorVisitor::IADD3_reg(u64 insn) {
92 IADD3(*this, insn, GetReg20(insn), GetReg39(insn));
93}
94
95void TranslatorVisitor::IADD3_cbuf(u64 insn) {
96 IADD3(*this, insn, GetCbuf(insn), GetReg39(insn));
97}
98
99void 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
368void TranslatorVisitor::IADD3_reg(u64) {
369 ThrowNotImplemented(Opcode::IADD3_reg);
370}
371
372void TranslatorVisitor::IADD3_cbuf(u64) {
373 ThrowNotImplemented(Opcode::IADD3_cbuf);
374}
375
376void TranslatorVisitor::IADD3_imm(u64) {
377 ThrowNotImplemented(Opcode::IADD3_imm);
378}
379
380void TranslatorVisitor::IDE(u64) { 368void TranslatorVisitor::IDE(u64) {
381 ThrowNotImplemented(Opcode::IDE); 369 ThrowNotImplemented(Opcode::IDE);
382} 370}