summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend/maxwell/translate/impl
diff options
context:
space:
mode:
authorGravatar Markus Wick2022-03-07 19:13:05 +0100
committerGravatar Markus Wick2022-03-08 09:44:28 +0100
commitc78c8190d5b964c9421b7d0c0c3a96ba599b3c2f (patch)
treef9586978f8b87bf6fcd56dbebe4eabe2fa469cf3 /src/shader_recompiler/frontend/maxwell/translate/impl
parentMerge pull request #7974 from bunnei/improve-code-mem (diff)
downloadyuzu-c78c8190d5b964c9421b7d0c0c3a96ba599b3c2f.tar.gz
yuzu-c78c8190d5b964c9421b7d0c0c3a96ba599b3c2f.tar.xz
yuzu-c78c8190d5b964c9421b7d0c0c3a96ba599b3c2f.zip
shader_recompiler/LOP3: Use brute force python results within switch/case.
Thanks to @asLody for optimizing this function. This raised the focus that this function should be optimized more. The current table assumes that the host GPU is able to invert for free, so only AND,OR,XOR are accumulated in the performance metrik. Performance results: Instructions 0: 8 1: 30 2: 114 3: 80 4: 24 Latency 0: 8 1: 30 2: 194 3: 24
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/translate/impl')
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input.cpp580
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input_lut3.py92
2 files changed, 620 insertions, 52 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input.cpp
index e0fe47912..f3c7ceb57 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input.cpp
@@ -13,59 +13,535 @@ namespace {
13// Emulate GPU's LOP3.LUT (three-input logic op with 8-bit truth table) 13// Emulate GPU's LOP3.LUT (three-input logic op with 8-bit truth table)
14IR::U32 ApplyLUT(IR::IREmitter& ir, const IR::U32& a, const IR::U32& b, const IR::U32& c, 14IR::U32 ApplyLUT(IR::IREmitter& ir, const IR::U32& a, const IR::U32& b, const IR::U32& c,
15 u64 ttbl) { 15 u64 ttbl) {
16 IR::U32 r{ir.Imm32(0)}; 16 switch (ttbl) {
17 const IR::U32 not_a{ir.BitwiseNot(a)}; 17 // generated code, do not edit manually
18 const IR::U32 not_b{ir.BitwiseNot(b)}; 18 case 0:
19 const IR::U32 not_c{ir.BitwiseNot(c)}; 19 return ir.Imm32(0);
20 if (ttbl & 0x01) { 20 case 1:
21 // r |= ~a & ~b & ~c; 21 return ir.BitwiseNot(ir.BitwiseOr(a, ir.BitwiseOr(b, c)));
22 const auto lhs{ir.BitwiseAnd(not_a, not_b)}; 22 case 2:
23 const auto rhs{ir.BitwiseAnd(lhs, not_c)}; 23 return ir.BitwiseAnd(c, ir.BitwiseNot(ir.BitwiseOr(a, b)));
24 r = ir.BitwiseOr(r, rhs); 24 case 3:
25 return ir.BitwiseNot(ir.BitwiseOr(a, b));
26 case 4:
27 return ir.BitwiseAnd(b, ir.BitwiseNot(ir.BitwiseOr(a, c)));
28 case 5:
29 return ir.BitwiseNot(ir.BitwiseOr(a, c));
30 case 6:
31 return ir.BitwiseAnd(ir.BitwiseNot(a), ir.BitwiseXor(b, c));
32 case 7:
33 return ir.BitwiseNot(ir.BitwiseOr(a, ir.BitwiseAnd(b, c)));
34 case 8:
35 return ir.BitwiseAnd(ir.BitwiseAnd(b, c), ir.BitwiseNot(a));
36 case 9:
37 return ir.BitwiseNot(ir.BitwiseOr(a, ir.BitwiseXor(b, c)));
38 case 10:
39 return ir.BitwiseAnd(c, ir.BitwiseNot(a));
40 case 11:
41 return ir.BitwiseAnd(ir.BitwiseNot(a), ir.BitwiseOr(c, ir.BitwiseNot(b)));
42 case 12:
43 return ir.BitwiseAnd(b, ir.BitwiseNot(a));
44 case 13:
45 return ir.BitwiseAnd(ir.BitwiseNot(a), ir.BitwiseOr(b, ir.BitwiseNot(c)));
46 case 14:
47 return ir.BitwiseAnd(ir.BitwiseNot(a), ir.BitwiseOr(b, c));
48 case 15:
49 return ir.BitwiseNot(a);
50 case 16:
51 return ir.BitwiseAnd(a, ir.BitwiseNot(ir.BitwiseOr(b, c)));
52 case 17:
53 return ir.BitwiseNot(ir.BitwiseOr(b, c));
54 case 18:
55 return ir.BitwiseAnd(ir.BitwiseNot(b), ir.BitwiseXor(a, c));
56 case 19:
57 return ir.BitwiseNot(ir.BitwiseOr(b, ir.BitwiseAnd(a, c)));
58 case 20:
59 return ir.BitwiseAnd(ir.BitwiseNot(c), ir.BitwiseXor(a, b));
60 case 21:
61 return ir.BitwiseNot(ir.BitwiseOr(c, ir.BitwiseAnd(a, b)));
62 case 22:
63 return ir.BitwiseXor(ir.BitwiseOr(a, b), ir.BitwiseOr(c, ir.BitwiseAnd(a, b)));
64 case 23:
65 return ir.BitwiseXor(ir.BitwiseAnd(ir.BitwiseXor(a, b), ir.BitwiseXor(a, c)),
66 ir.BitwiseNot(a));
67 case 24:
68 return ir.BitwiseAnd(ir.BitwiseXor(a, b), ir.BitwiseXor(a, c));
69 case 25:
70 return ir.BitwiseNot(ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseXor(b, c)));
71 case 26:
72 return ir.BitwiseAnd(ir.BitwiseOr(c, ir.BitwiseNot(b)), ir.BitwiseXor(a, c));
73 case 27:
74 return ir.BitwiseXor(ir.BitwiseOr(a, ir.BitwiseNot(c)), ir.BitwiseOr(b, c));
75 case 28:
76 return ir.BitwiseAnd(ir.BitwiseOr(b, ir.BitwiseNot(c)), ir.BitwiseXor(a, b));
77 case 29:
78 return ir.BitwiseXor(ir.BitwiseOr(a, ir.BitwiseNot(b)), ir.BitwiseOr(b, c));
79 case 30:
80 return ir.BitwiseXor(a, ir.BitwiseOr(b, c));
81 case 31:
82 return ir.BitwiseNot(ir.BitwiseAnd(a, ir.BitwiseOr(b, c)));
83 case 32:
84 return ir.BitwiseAnd(ir.BitwiseAnd(a, c), ir.BitwiseNot(b));
85 case 33:
86 return ir.BitwiseNot(ir.BitwiseOr(b, ir.BitwiseXor(a, c)));
87 case 34:
88 return ir.BitwiseAnd(c, ir.BitwiseNot(b));
89 case 35:
90 return ir.BitwiseAnd(ir.BitwiseNot(b), ir.BitwiseOr(c, ir.BitwiseNot(a)));
91 case 36:
92 return ir.BitwiseAnd(ir.BitwiseXor(a, b), ir.BitwiseXor(b, c));
93 case 37:
94 return ir.BitwiseNot(ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseXor(a, c)));
95 case 38:
96 return ir.BitwiseAnd(ir.BitwiseOr(c, ir.BitwiseNot(a)), ir.BitwiseXor(b, c));
97 case 39:
98 return ir.BitwiseXor(ir.BitwiseOr(a, c), ir.BitwiseOr(b, ir.BitwiseNot(c)));
99 case 40:
100 return ir.BitwiseAnd(c, ir.BitwiseXor(a, b));
101 case 41:
102 return ir.BitwiseXor(ir.BitwiseOr(a, b),
103 ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseNot(c)));
104 case 42:
105 return ir.BitwiseAnd(c, ir.BitwiseNot(ir.BitwiseAnd(a, b)));
106 case 43:
107 return ir.BitwiseXor(ir.BitwiseOr(a, ir.BitwiseNot(c)),
108 ir.BitwiseOr(b, ir.BitwiseXor(a, c)));
109 case 44:
110 return ir.BitwiseAnd(ir.BitwiseOr(b, c), ir.BitwiseXor(a, b));
111 case 45:
112 return ir.BitwiseXor(a, ir.BitwiseOr(b, ir.BitwiseNot(c)));
113 case 46:
114 return ir.BitwiseXor(ir.BitwiseAnd(a, b), ir.BitwiseOr(b, c));
115 case 47:
116 return ir.BitwiseOr(ir.BitwiseAnd(c, ir.BitwiseNot(b)), ir.BitwiseNot(a));
117 case 48:
118 return ir.BitwiseAnd(a, ir.BitwiseNot(b));
119 case 49:
120 return ir.BitwiseAnd(ir.BitwiseNot(b), ir.BitwiseOr(a, ir.BitwiseNot(c)));
121 case 50:
122 return ir.BitwiseAnd(ir.BitwiseNot(b), ir.BitwiseOr(a, c));
123 case 51:
124 return ir.BitwiseNot(b);
125 case 52:
126 return ir.BitwiseAnd(ir.BitwiseOr(a, ir.BitwiseNot(c)), ir.BitwiseXor(a, b));
127 case 53:
128 return ir.BitwiseXor(ir.BitwiseOr(a, c), ir.BitwiseOr(b, ir.BitwiseNot(a)));
129 case 54:
130 return ir.BitwiseXor(b, ir.BitwiseOr(a, c));
131 case 55:
132 return ir.BitwiseNot(ir.BitwiseAnd(b, ir.BitwiseOr(a, c)));
133 case 56:
134 return ir.BitwiseAnd(ir.BitwiseOr(a, c), ir.BitwiseXor(a, b));
135 case 57:
136 return ir.BitwiseXor(b, ir.BitwiseOr(a, ir.BitwiseNot(c)));
137 case 58:
138 return ir.BitwiseXor(ir.BitwiseAnd(a, b), ir.BitwiseOr(a, c));
139 case 59:
140 return ir.BitwiseOr(ir.BitwiseAnd(c, ir.BitwiseNot(a)), ir.BitwiseNot(b));
141 case 60:
142 return ir.BitwiseXor(a, b);
143 case 61:
144 return ir.BitwiseOr(ir.BitwiseNot(ir.BitwiseOr(a, c)), ir.BitwiseXor(a, b));
145 case 62:
146 return ir.BitwiseOr(ir.BitwiseAnd(c, ir.BitwiseNot(a)), ir.BitwiseXor(a, b));
147 case 63:
148 return ir.BitwiseNot(ir.BitwiseAnd(a, b));
149 case 64:
150 return ir.BitwiseAnd(ir.BitwiseAnd(a, b), ir.BitwiseNot(c));
151 case 65:
152 return ir.BitwiseNot(ir.BitwiseOr(c, ir.BitwiseXor(a, b)));
153 case 66:
154 return ir.BitwiseAnd(ir.BitwiseXor(a, c), ir.BitwiseXor(b, c));
155 case 67:
156 return ir.BitwiseNot(ir.BitwiseOr(ir.BitwiseAnd(a, c), ir.BitwiseXor(a, b)));
157 case 68:
158 return ir.BitwiseAnd(b, ir.BitwiseNot(c));
159 case 69:
160 return ir.BitwiseAnd(ir.BitwiseNot(c), ir.BitwiseOr(b, ir.BitwiseNot(a)));
161 case 70:
162 return ir.BitwiseAnd(ir.BitwiseOr(b, ir.BitwiseNot(a)), ir.BitwiseXor(b, c));
163 case 71:
164 return ir.BitwiseXor(ir.BitwiseOr(a, b), ir.BitwiseOr(c, ir.BitwiseNot(b)));
165 case 72:
166 return ir.BitwiseAnd(b, ir.BitwiseXor(a, c));
167 case 73:
168 return ir.BitwiseXor(ir.BitwiseOr(a, c),
169 ir.BitwiseOr(ir.BitwiseAnd(a, c), ir.BitwiseNot(b)));
170 case 74:
171 return ir.BitwiseAnd(ir.BitwiseOr(b, c), ir.BitwiseXor(a, c));
172 case 75:
173 return ir.BitwiseXor(a, ir.BitwiseOr(c, ir.BitwiseNot(b)));
174 case 76:
175 return ir.BitwiseAnd(b, ir.BitwiseNot(ir.BitwiseAnd(a, c)));
176 case 77:
177 return ir.BitwiseXor(ir.BitwiseOr(a, ir.BitwiseNot(b)),
178 ir.BitwiseOr(c, ir.BitwiseXor(a, b)));
179 case 78:
180 return ir.BitwiseXor(ir.BitwiseAnd(a, c), ir.BitwiseOr(b, c));
181 case 79:
182 return ir.BitwiseOr(ir.BitwiseAnd(b, ir.BitwiseNot(c)), ir.BitwiseNot(a));
183 case 80:
184 return ir.BitwiseAnd(a, ir.BitwiseNot(c));
185 case 81:
186 return ir.BitwiseAnd(ir.BitwiseNot(c), ir.BitwiseOr(a, ir.BitwiseNot(b)));
187 case 82:
188 return ir.BitwiseAnd(ir.BitwiseOr(a, ir.BitwiseNot(b)), ir.BitwiseXor(a, c));
189 case 83:
190 return ir.BitwiseXor(ir.BitwiseOr(a, b), ir.BitwiseOr(c, ir.BitwiseNot(a)));
191 case 84:
192 return ir.BitwiseAnd(ir.BitwiseNot(c), ir.BitwiseOr(a, b));
193 case 85:
194 return ir.BitwiseNot(c);
195 case 86:
196 return ir.BitwiseXor(c, ir.BitwiseOr(a, b));
197 case 87:
198 return ir.BitwiseNot(ir.BitwiseAnd(c, ir.BitwiseOr(a, b)));
199 case 88:
200 return ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseXor(a, c));
201 case 89:
202 return ir.BitwiseXor(c, ir.BitwiseOr(a, ir.BitwiseNot(b)));
203 case 90:
204 return ir.BitwiseXor(a, c);
205 case 91:
206 return ir.BitwiseOr(ir.BitwiseNot(ir.BitwiseOr(a, b)), ir.BitwiseXor(a, c));
207 case 92:
208 return ir.BitwiseXor(ir.BitwiseAnd(a, c), ir.BitwiseOr(a, b));
209 case 93:
210 return ir.BitwiseOr(ir.BitwiseAnd(b, ir.BitwiseNot(a)), ir.BitwiseNot(c));
211 case 94:
212 return ir.BitwiseOr(ir.BitwiseAnd(b, ir.BitwiseNot(a)), ir.BitwiseXor(a, c));
213 case 95:
214 return ir.BitwiseNot(ir.BitwiseAnd(a, c));
215 case 96:
216 return ir.BitwiseAnd(a, ir.BitwiseXor(b, c));
217 case 97:
218 return ir.BitwiseXor(ir.BitwiseOr(b, c),
219 ir.BitwiseOr(ir.BitwiseAnd(b, c), ir.BitwiseNot(a)));
220 case 98:
221 return ir.BitwiseAnd(ir.BitwiseOr(a, c), ir.BitwiseXor(b, c));
222 case 99:
223 return ir.BitwiseXor(b, ir.BitwiseOr(c, ir.BitwiseNot(a)));
224 case 100:
225 return ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseXor(b, c));
226 case 101:
227 return ir.BitwiseXor(c, ir.BitwiseOr(b, ir.BitwiseNot(a)));
228 case 102:
229 return ir.BitwiseXor(b, c);
230 case 103:
231 return ir.BitwiseOr(ir.BitwiseNot(ir.BitwiseOr(a, b)), ir.BitwiseXor(b, c));
232 case 104:
233 return ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseXor(c, ir.BitwiseAnd(a, b)));
234 case 105:
235 return ir.BitwiseXor(ir.BitwiseNot(a), ir.BitwiseXor(b, c));
236 case 106:
237 return ir.BitwiseXor(c, ir.BitwiseAnd(a, b));
238 case 107:
239 return ir.BitwiseXor(ir.BitwiseAnd(c, ir.BitwiseOr(a, b)),
240 ir.BitwiseXor(a, ir.BitwiseNot(b)));
241 case 108:
242 return ir.BitwiseXor(b, ir.BitwiseAnd(a, c));
243 case 109:
244 return ir.BitwiseXor(ir.BitwiseAnd(b, ir.BitwiseOr(a, c)),
245 ir.BitwiseXor(a, ir.BitwiseNot(c)));
246 case 110:
247 return ir.BitwiseOr(ir.BitwiseAnd(b, ir.BitwiseNot(a)), ir.BitwiseXor(b, c));
248 case 111:
249 return ir.BitwiseOr(ir.BitwiseNot(a), ir.BitwiseXor(b, c));
250 case 112:
251 return ir.BitwiseAnd(a, ir.BitwiseNot(ir.BitwiseAnd(b, c)));
252 case 113:
253 return ir.BitwiseXor(ir.BitwiseOr(b, ir.BitwiseNot(a)),
254 ir.BitwiseOr(c, ir.BitwiseXor(a, b)));
255 case 114:
256 return ir.BitwiseXor(ir.BitwiseAnd(b, c), ir.BitwiseOr(a, c));
257 case 115:
258 return ir.BitwiseOr(ir.BitwiseAnd(a, ir.BitwiseNot(c)), ir.BitwiseNot(b));
259 case 116:
260 return ir.BitwiseXor(ir.BitwiseAnd(b, c), ir.BitwiseOr(a, b));
261 case 117:
262 return ir.BitwiseOr(ir.BitwiseAnd(a, ir.BitwiseNot(b)), ir.BitwiseNot(c));
263 case 118:
264 return ir.BitwiseOr(ir.BitwiseAnd(a, ir.BitwiseNot(b)), ir.BitwiseXor(b, c));
265 case 119:
266 return ir.BitwiseNot(ir.BitwiseAnd(b, c));
267 case 120:
268 return ir.BitwiseXor(a, ir.BitwiseAnd(b, c));
269 case 121:
270 return ir.BitwiseXor(ir.BitwiseAnd(a, ir.BitwiseOr(b, c)),
271 ir.BitwiseXor(b, ir.BitwiseNot(c)));
272 case 122:
273 return ir.BitwiseOr(ir.BitwiseAnd(a, ir.BitwiseNot(b)), ir.BitwiseXor(a, c));
274 case 123:
275 return ir.BitwiseOr(ir.BitwiseNot(b), ir.BitwiseXor(a, c));
276 case 124:
277 return ir.BitwiseOr(ir.BitwiseAnd(a, ir.BitwiseNot(c)), ir.BitwiseXor(a, b));
278 case 125:
279 return ir.BitwiseOr(ir.BitwiseNot(c), ir.BitwiseXor(a, b));
280 case 126:
281 return ir.BitwiseOr(ir.BitwiseXor(a, b), ir.BitwiseXor(a, c));
282 case 127:
283 return ir.BitwiseNot(ir.BitwiseAnd(a, ir.BitwiseAnd(b, c)));
284 case 128:
285 return ir.BitwiseAnd(a, ir.BitwiseAnd(b, c));
286 case 129:
287 return ir.BitwiseNot(ir.BitwiseOr(ir.BitwiseXor(a, b), ir.BitwiseXor(a, c)));
288 case 130:
289 return ir.BitwiseAnd(c, ir.BitwiseXor(a, ir.BitwiseNot(b)));
290 case 131:
291 return ir.BitwiseAnd(ir.BitwiseOr(c, ir.BitwiseNot(a)), ir.BitwiseXor(a, ir.BitwiseNot(b)));
292 case 132:
293 return ir.BitwiseAnd(b, ir.BitwiseXor(a, ir.BitwiseNot(c)));
294 case 133:
295 return ir.BitwiseAnd(ir.BitwiseOr(b, ir.BitwiseNot(a)), ir.BitwiseXor(a, ir.BitwiseNot(c)));
296 case 134:
297 return ir.BitwiseAnd(ir.BitwiseOr(b, c), ir.BitwiseXor(a, ir.BitwiseXor(b, c)));
298 case 135:
299 return ir.BitwiseXor(ir.BitwiseAnd(b, c), ir.BitwiseNot(a));
300 case 136:
301 return ir.BitwiseAnd(b, c);
302 case 137:
303 return ir.BitwiseAnd(ir.BitwiseOr(b, ir.BitwiseNot(a)), ir.BitwiseXor(b, ir.BitwiseNot(c)));
304 case 138:
305 return ir.BitwiseAnd(c, ir.BitwiseOr(b, ir.BitwiseNot(a)));
306 case 139:
307 return ir.BitwiseOr(ir.BitwiseAnd(b, c), ir.BitwiseNot(ir.BitwiseOr(a, b)));
308 case 140:
309 return ir.BitwiseAnd(b, ir.BitwiseOr(c, ir.BitwiseNot(a)));
310 case 141:
311 return ir.BitwiseOr(ir.BitwiseAnd(b, c), ir.BitwiseNot(ir.BitwiseOr(a, c)));
312 case 142:
313 return ir.BitwiseXor(a, ir.BitwiseOr(ir.BitwiseXor(a, b), ir.BitwiseXor(a, c)));
314 case 143:
315 return ir.BitwiseOr(ir.BitwiseAnd(b, c), ir.BitwiseNot(a));
316 case 144:
317 return ir.BitwiseAnd(a, ir.BitwiseXor(b, ir.BitwiseNot(c)));
318 case 145:
319 return ir.BitwiseAnd(ir.BitwiseOr(a, ir.BitwiseNot(b)), ir.BitwiseXor(b, ir.BitwiseNot(c)));
320 case 146:
321 return ir.BitwiseAnd(ir.BitwiseOr(a, c), ir.BitwiseXor(a, ir.BitwiseXor(b, c)));
322 case 147:
323 return ir.BitwiseXor(ir.BitwiseAnd(a, c), ir.BitwiseNot(b));
324 case 148:
325 return ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseXor(a, ir.BitwiseXor(b, c)));
326 case 149:
327 return ir.BitwiseXor(ir.BitwiseAnd(a, b), ir.BitwiseNot(c));
328 case 150:
329 return ir.BitwiseXor(a, ir.BitwiseXor(b, c));
330 case 151:
331 return ir.BitwiseOr(ir.BitwiseNot(ir.BitwiseOr(a, b)),
332 ir.BitwiseXor(a, ir.BitwiseXor(b, c)));
333 case 152:
334 return ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseXor(b, ir.BitwiseNot(c)));
335 case 153:
336 return ir.BitwiseXor(b, ir.BitwiseNot(c));
337 case 154:
338 return ir.BitwiseXor(c, ir.BitwiseAnd(a, ir.BitwiseNot(b)));
339 case 155:
340 return ir.BitwiseNot(ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseXor(b, c)));
341 case 156:
342 return ir.BitwiseXor(b, ir.BitwiseAnd(a, ir.BitwiseNot(c)));
343 case 157:
344 return ir.BitwiseNot(ir.BitwiseAnd(ir.BitwiseOr(a, c), ir.BitwiseXor(b, c)));
345 case 158:
346 return ir.BitwiseOr(ir.BitwiseAnd(b, c), ir.BitwiseXor(a, ir.BitwiseOr(b, c)));
347 case 159:
348 return ir.BitwiseNot(ir.BitwiseAnd(a, ir.BitwiseXor(b, c)));
349 case 160:
350 return ir.BitwiseAnd(a, c);
351 case 161:
352 return ir.BitwiseAnd(ir.BitwiseOr(a, ir.BitwiseNot(b)), ir.BitwiseXor(a, ir.BitwiseNot(c)));
353 case 162:
354 return ir.BitwiseAnd(c, ir.BitwiseOr(a, ir.BitwiseNot(b)));
355 case 163:
356 return ir.BitwiseOr(ir.BitwiseAnd(a, c), ir.BitwiseNot(ir.BitwiseOr(a, b)));
357 case 164:
358 return ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseXor(a, ir.BitwiseNot(c)));
359 case 165:
360 return ir.BitwiseXor(a, ir.BitwiseNot(c));
361 case 166:
362 return ir.BitwiseXor(c, ir.BitwiseAnd(b, ir.BitwiseNot(a)));
363 case 167:
364 return ir.BitwiseNot(ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseXor(a, c)));
365 case 168:
366 return ir.BitwiseAnd(c, ir.BitwiseOr(a, b));
367 case 169:
368 return ir.BitwiseXor(ir.BitwiseNot(c), ir.BitwiseOr(a, b));
369 case 170:
370 return c;
371 case 171:
372 return ir.BitwiseOr(c, ir.BitwiseNot(ir.BitwiseOr(a, b)));
373 case 172:
374 return ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseOr(c, ir.BitwiseNot(a)));
375 case 173:
376 return ir.BitwiseOr(ir.BitwiseAnd(b, c), ir.BitwiseXor(a, ir.BitwiseNot(c)));
377 case 174:
378 return ir.BitwiseOr(c, ir.BitwiseAnd(b, ir.BitwiseNot(a)));
379 case 175:
380 return ir.BitwiseOr(c, ir.BitwiseNot(a));
381 case 176:
382 return ir.BitwiseAnd(a, ir.BitwiseOr(c, ir.BitwiseNot(b)));
383 case 177:
384 return ir.BitwiseOr(ir.BitwiseAnd(a, c), ir.BitwiseNot(ir.BitwiseOr(b, c)));
385 case 178:
386 return ir.BitwiseXor(b, ir.BitwiseOr(ir.BitwiseXor(a, b), ir.BitwiseXor(a, c)));
387 case 179:
388 return ir.BitwiseOr(ir.BitwiseAnd(a, c), ir.BitwiseNot(b));
389 case 180:
390 return ir.BitwiseXor(a, ir.BitwiseAnd(b, ir.BitwiseNot(c)));
391 case 181:
392 return ir.BitwiseNot(ir.BitwiseAnd(ir.BitwiseOr(b, c), ir.BitwiseXor(a, c)));
393 case 182:
394 return ir.BitwiseOr(ir.BitwiseAnd(a, c), ir.BitwiseXor(b, ir.BitwiseOr(a, c)));
395 case 183:
396 return ir.BitwiseNot(ir.BitwiseAnd(b, ir.BitwiseXor(a, c)));
397 case 184:
398 return ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseOr(c, ir.BitwiseNot(b)));
399 case 185:
400 return ir.BitwiseOr(ir.BitwiseAnd(a, c), ir.BitwiseXor(b, ir.BitwiseNot(c)));
401 case 186:
402 return ir.BitwiseOr(c, ir.BitwiseAnd(a, ir.BitwiseNot(b)));
403 case 187:
404 return ir.BitwiseOr(c, ir.BitwiseNot(b));
405 case 188:
406 return ir.BitwiseOr(ir.BitwiseAnd(a, c), ir.BitwiseXor(a, b));
407 case 189:
408 return ir.BitwiseOr(ir.BitwiseXor(a, b), ir.BitwiseXor(a, ir.BitwiseNot(c)));
409 case 190:
410 return ir.BitwiseOr(c, ir.BitwiseXor(a, b));
411 case 191:
412 return ir.BitwiseOr(c, ir.BitwiseNot(ir.BitwiseAnd(a, b)));
413 case 192:
414 return ir.BitwiseAnd(a, b);
415 case 193:
416 return ir.BitwiseAnd(ir.BitwiseOr(a, ir.BitwiseNot(c)), ir.BitwiseXor(a, ir.BitwiseNot(b)));
417 case 194:
418 return ir.BitwiseAnd(ir.BitwiseOr(a, c), ir.BitwiseXor(a, ir.BitwiseNot(b)));
419 case 195:
420 return ir.BitwiseXor(a, ir.BitwiseNot(b));
421 case 196:
422 return ir.BitwiseAnd(b, ir.BitwiseOr(a, ir.BitwiseNot(c)));
423 case 197:
424 return ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseNot(ir.BitwiseOr(a, c)));
425 case 198:
426 return ir.BitwiseXor(b, ir.BitwiseAnd(c, ir.BitwiseNot(a)));
427 case 199:
428 return ir.BitwiseNot(ir.BitwiseAnd(ir.BitwiseOr(a, c), ir.BitwiseXor(a, b)));
429 case 200:
430 return ir.BitwiseAnd(b, ir.BitwiseOr(a, c));
431 case 201:
432 return ir.BitwiseXor(ir.BitwiseNot(b), ir.BitwiseOr(a, c));
433 case 202:
434 return ir.BitwiseAnd(ir.BitwiseOr(a, c), ir.BitwiseOr(b, ir.BitwiseNot(a)));
435 case 203:
436 return ir.BitwiseOr(ir.BitwiseAnd(b, c), ir.BitwiseXor(a, ir.BitwiseNot(b)));
437 case 204:
438 return b;
439 case 205:
440 return ir.BitwiseOr(b, ir.BitwiseNot(ir.BitwiseOr(a, c)));
441 case 206:
442 return ir.BitwiseOr(b, ir.BitwiseAnd(c, ir.BitwiseNot(a)));
443 case 207:
444 return ir.BitwiseOr(b, ir.BitwiseNot(a));
445 case 208:
446 return ir.BitwiseAnd(a, ir.BitwiseOr(b, ir.BitwiseNot(c)));
447 case 209:
448 return ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseNot(ir.BitwiseOr(b, c)));
449 case 210:
450 return ir.BitwiseXor(a, ir.BitwiseAnd(c, ir.BitwiseNot(b)));
451 case 211:
452 return ir.BitwiseNot(ir.BitwiseAnd(ir.BitwiseOr(b, c), ir.BitwiseXor(a, b)));
453 case 212:
454 return ir.BitwiseXor(c, ir.BitwiseOr(ir.BitwiseXor(a, b), ir.BitwiseXor(a, c)));
455 case 213:
456 return ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseNot(c));
457 case 214:
458 return ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseXor(c, ir.BitwiseOr(a, b)));
459 case 215:
460 return ir.BitwiseNot(ir.BitwiseAnd(c, ir.BitwiseXor(a, b)));
461 case 216:
462 return ir.BitwiseAnd(ir.BitwiseOr(a, c), ir.BitwiseOr(b, ir.BitwiseNot(c)));
463 case 217:
464 return ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseXor(b, ir.BitwiseNot(c)));
465 case 218:
466 return ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseXor(a, c));
467 case 219:
468 return ir.BitwiseOr(ir.BitwiseXor(a, c), ir.BitwiseXor(a, ir.BitwiseNot(b)));
469 case 220:
470 return ir.BitwiseOr(b, ir.BitwiseAnd(a, ir.BitwiseNot(c)));
471 case 221:
472 return ir.BitwiseOr(b, ir.BitwiseNot(c));
473 case 222:
474 return ir.BitwiseOr(b, ir.BitwiseXor(a, c));
475 case 223:
476 return ir.BitwiseOr(b, ir.BitwiseNot(ir.BitwiseAnd(a, c)));
477 case 224:
478 return ir.BitwiseAnd(a, ir.BitwiseOr(b, c));
479 case 225:
480 return ir.BitwiseXor(ir.BitwiseNot(a), ir.BitwiseOr(b, c));
481 case 226:
482 return ir.BitwiseAnd(ir.BitwiseOr(a, ir.BitwiseNot(b)), ir.BitwiseOr(b, c));
483 case 227:
484 return ir.BitwiseOr(ir.BitwiseAnd(a, c), ir.BitwiseXor(a, ir.BitwiseNot(b)));
485 case 228:
486 return ir.BitwiseAnd(ir.BitwiseOr(a, ir.BitwiseNot(c)), ir.BitwiseOr(b, c));
487 case 229:
488 return ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseXor(a, ir.BitwiseNot(c)));
489 case 230:
490 return ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseXor(b, c));
491 case 231:
492 return ir.BitwiseOr(ir.BitwiseXor(a, ir.BitwiseNot(b)), ir.BitwiseXor(b, c));
493 case 232:
494 return ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseOr(c, ir.BitwiseAnd(a, b)));
495 case 233:
496 return ir.BitwiseOr(ir.BitwiseAnd(a, b),
497 ir.BitwiseXor(ir.BitwiseNot(c), ir.BitwiseOr(a, b)));
498 case 234:
499 return ir.BitwiseOr(c, ir.BitwiseAnd(a, b));
500 case 235:
501 return ir.BitwiseOr(c, ir.BitwiseXor(a, ir.BitwiseNot(b)));
502 case 236:
503 return ir.BitwiseOr(b, ir.BitwiseAnd(a, c));
504 case 237:
505 return ir.BitwiseOr(b, ir.BitwiseXor(a, ir.BitwiseNot(c)));
506 case 238:
507 return ir.BitwiseOr(b, c);
508 case 239:
509 return ir.BitwiseOr(ir.BitwiseNot(a), ir.BitwiseOr(b, c));
510 case 240:
511 return a;
512 case 241:
513 return ir.BitwiseOr(a, ir.BitwiseNot(ir.BitwiseOr(b, c)));
514 case 242:
515 return ir.BitwiseOr(a, ir.BitwiseAnd(c, ir.BitwiseNot(b)));
516 case 243:
517 return ir.BitwiseOr(a, ir.BitwiseNot(b));
518 case 244:
519 return ir.BitwiseOr(a, ir.BitwiseAnd(b, ir.BitwiseNot(c)));
520 case 245:
521 return ir.BitwiseOr(a, ir.BitwiseNot(c));
522 case 246:
523 return ir.BitwiseOr(a, ir.BitwiseXor(b, c));
524 case 247:
525 return ir.BitwiseOr(a, ir.BitwiseNot(ir.BitwiseAnd(b, c)));
526 case 248:
527 return ir.BitwiseOr(a, ir.BitwiseAnd(b, c));
528 case 249:
529 return ir.BitwiseOr(a, ir.BitwiseXor(b, ir.BitwiseNot(c)));
530 case 250:
531 return ir.BitwiseOr(a, c);
532 case 251:
533 return ir.BitwiseOr(ir.BitwiseNot(b), ir.BitwiseOr(a, c));
534 case 252:
535 return ir.BitwiseOr(a, b);
536 case 253:
537 return ir.BitwiseOr(ir.BitwiseNot(c), ir.BitwiseOr(a, b));
538 case 254:
539 return ir.BitwiseOr(a, ir.BitwiseOr(b, c));
540 case 255:
541 return ir.Imm32(0xFFFFFFFF);
542 // end of generated code
25 } 543 }
26 if (ttbl & 0x02) { 544 throw NotImplementedException("LOP3 with out of range ttbl");
27 // r |= ~a & ~b & c;
28 const auto lhs{ir.BitwiseAnd(not_a, not_b)};
29 const auto rhs{ir.BitwiseAnd(lhs, c)};
30 r = ir.BitwiseOr(r, rhs);
31 }
32 if (ttbl & 0x04) {
33 // r |= ~a & b & ~c;
34 const auto lhs{ir.BitwiseAnd(not_a, b)};
35 const auto rhs{ir.BitwiseAnd(lhs, not_c)};
36 r = ir.BitwiseOr(r, rhs);
37 }
38 if (ttbl & 0x08) {
39 // r |= ~a & b & c;
40 const auto lhs{ir.BitwiseAnd(not_a, b)};
41 const auto rhs{ir.BitwiseAnd(lhs, c)};
42 r = ir.BitwiseOr(r, rhs);
43 }
44 if (ttbl & 0x10) {
45 // r |= a & ~b & ~c;
46 const auto lhs{ir.BitwiseAnd(a, not_b)};
47 const auto rhs{ir.BitwiseAnd(lhs, not_c)};
48 r = ir.BitwiseOr(r, rhs);
49 }
50 if (ttbl & 0x20) {
51 // r |= a & ~b & c;
52 const auto lhs{ir.BitwiseAnd(a, not_b)};
53 const auto rhs{ir.BitwiseAnd(lhs, c)};
54 r = ir.BitwiseOr(r, rhs);
55 }
56 if (ttbl & 0x40) {
57 // r |= a & b & ~c;
58 const auto lhs{ir.BitwiseAnd(a, b)};
59 const auto rhs{ir.BitwiseAnd(lhs, not_c)};
60 r = ir.BitwiseOr(r, rhs);
61 }
62 if (ttbl & 0x80) {
63 // r |= a & b & c;
64 const auto lhs{ir.BitwiseAnd(a, b)};
65 const auto rhs{ir.BitwiseAnd(lhs, c)};
66 r = ir.BitwiseOr(r, rhs);
67 }
68 return r;
69} 545}
70 546
71IR::U32 LOP3(TranslatorVisitor& v, u64 insn, const IR::U32& op_b, const IR::U32& op_c, u64 lut) { 547IR::U32 LOP3(TranslatorVisitor& v, u64 insn, const IR::U32& op_b, const IR::U32& op_c, u64 lut) {
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input_lut3.py b/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input_lut3.py
new file mode 100644
index 000000000..8f547c266
--- /dev/null
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input_lut3.py
@@ -0,0 +1,92 @@
1# Copyright © 2022 degasus <markus@selfnet.de>
2# This work is free. You can redistribute it and/or modify it under the
3# terms of the Do What The Fuck You Want To Public License, Version 2,
4# as published by Sam Hocevar. See http://www.wtfpl.net/ for more details.
5
6from itertools import product
7
8# The primitive instructions
9OPS = {
10 'ir.BitwiseAnd({}, {})' : (2, 1, lambda a,b: a&b),
11 'ir.BitwiseOr({}, {})' : (2, 1, lambda a,b: a|b),
12 'ir.BitwiseXor({}, {})' : (2, 1, lambda a,b: a^b),
13 'ir.BitwiseNot({})' : (1, 0.1, lambda a: (~a) & 255), # Only tiny cost, as this can often inlined in other instructions
14}
15
16# Our database of combination of instructions
17optimized_calls = {}
18def cmp(lhs, rhs):
19 if lhs is None: # new entry
20 return True
21 if lhs[3] > rhs[3]: # costs
22 return True
23 if lhs[3] < rhs[3]: # costs
24 return False
25 if len(lhs[0]) > len(rhs[0]): # string len
26 return True
27 if len(lhs[0]) < len(rhs[0]): # string len
28 return False
29 if lhs[0] > rhs[0]: # string sorting
30 return True
31 if lhs[0] < rhs[0]: # string sorting
32 return False
33 assert lhs == rhs, "redundant instruction, bug in brute force"
34 return False
35def register(imm, instruction, count, latency):
36 # Use the sum of instruction count and latency as costs to evaluate which combination is best
37 costs = count + latency
38
39 old = optimized_calls.get(imm, None)
40 new = (instruction, count, latency, costs)
41
42 # Update if new or better
43 if cmp(old, new):
44 optimized_calls[imm] = new
45 return True
46
47 return False
48
49# Constants: 0, 1 (for free)
50register(0, 'ir.Imm32(0)', 0, 0)
51register(255, 'ir.Imm32(0xFFFFFFFF)', 0, 0)
52
53# Inputs: a, b, c (for free)
54ta = 0xF0
55tb = 0xCC
56tc = 0xAA
57inputs = {
58 ta : 'a',
59 tb : 'b',
60 tc : 'c',
61}
62for imm, instruction in inputs.items():
63 register(imm, instruction, 0, 0)
64 register((~imm) & 255, 'ir.BitwiseNot({})'.format(instruction), 0.099, 0.099) # slightly cheaper NEG on inputs
65
66# Try to combine two values from the db with an instruction.
67# If it is better than the old method, update it.
68while True:
69 registered = 0
70 calls_copy = optimized_calls.copy()
71 for OP, (argc, cost, f) in OPS.items():
72 for args in product(calls_copy.items(), repeat=argc):
73 # unpack(transponse) the arrays
74 imm = [arg[0] for arg in args]
75 value = [arg[1][0] for arg in args]
76 count = [arg[1][1] for arg in args]
77 latency = [arg[1][2] for arg in args]
78
79 registered += register(
80 f(*imm),
81 OP.format(*value),
82 sum(count) + cost,
83 max(latency) + cost)
84 if registered == 0:
85 # No update at all? So terminate
86 break
87
88# Hacky output. Please improve me to output valid C++ instead.
89s = """ case {imm}:
90 return {op};"""
91for imm in range(256):
92 print(s.format(imm=imm, op=optimized_calls[imm][0]))