1 /*
2 * Copyright 2009 Nicolai Haehnle.
3 * SPDX-License-Identifier: MIT
4 */
5
6 #include "radeon_opcodes.h"
7 #include "radeon_program.h"
8
9 #include "radeon_program_constants.h"
10
11 #include "util/compiler.h"
12
13 const struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE] = {
14 {
15 .Opcode = RC_OPCODE_NOP,
16 .Name = "NOP"
17 },
18 {
19 .Opcode = RC_OPCODE_ILLEGAL_OPCODE,
20 .Name = "ILLEGAL OPCODE"
21 },
22 {
23 .Opcode = RC_OPCODE_ADD,
24 .Name = "ADD",
25 .NumSrcRegs = 2,
26 .HasDstReg = 1,
27 .IsComponentwise = 1
28 },
29 {
30 .Opcode = RC_OPCODE_ARL,
31 .Name = "ARL",
32 .NumSrcRegs = 1,
33 .HasDstReg = 1
34 },
35 {
36 .Opcode = RC_OPCODE_ARR,
37 .Name = "ARR",
38 .NumSrcRegs = 1,
39 .HasDstReg = 1
40 },
41 {
42 .Opcode = RC_OPCODE_CMP,
43 .Name = "CMP",
44 .NumSrcRegs = 3,
45 .HasDstReg = 1,
46 .IsComponentwise = 1
47 },
48 {
49 .Opcode = RC_OPCODE_CND,
50 .Name = "CND",
51 .NumSrcRegs = 3,
52 .HasDstReg = 1,
53 .IsComponentwise = 1
54 },
55 {
56 .Opcode = RC_OPCODE_COS,
57 .Name = "COS",
58 .NumSrcRegs = 1,
59 .HasDstReg = 1,
60 .IsStandardScalar = 1
61 },
62 {
63 .Opcode = RC_OPCODE_DDX,
64 .Name = "DDX",
65 .NumSrcRegs = 2,
66 .HasDstReg = 1,
67 .IsComponentwise = 1
68 },
69 {
70 .Opcode = RC_OPCODE_DDY,
71 .Name = "DDY",
72 .NumSrcRegs = 2,
73 .HasDstReg = 1,
74 .IsComponentwise = 1
75 },
76 {
77 .Opcode = RC_OPCODE_DP2,
78 .Name = "DP2",
79 .NumSrcRegs = 2,
80 .HasDstReg = 1
81 },
82 {
83 .Opcode = RC_OPCODE_DP3,
84 .Name = "DP3",
85 .NumSrcRegs = 2,
86 .HasDstReg = 1
87 },
88 {
89 .Opcode = RC_OPCODE_DP4,
90 .Name = "DP4",
91 .NumSrcRegs = 2,
92 .HasDstReg = 1
93 },
94 {
95 .Opcode = RC_OPCODE_DST,
96 .Name = "DST",
97 .NumSrcRegs = 2,
98 .HasDstReg = 1
99 },
100 {
101 .Opcode = RC_OPCODE_EX2,
102 .Name = "EX2",
103 .NumSrcRegs = 1,
104 .HasDstReg = 1,
105 .IsStandardScalar = 1
106 },
107 {
108 .Opcode = RC_OPCODE_EXP,
109 .Name = "EXP",
110 .NumSrcRegs = 1,
111 .HasDstReg = 1
112 },
113 {
114 .Opcode = RC_OPCODE_FRC,
115 .Name = "FRC",
116 .NumSrcRegs = 1,
117 .HasDstReg = 1,
118 .IsComponentwise = 1
119 },
120 {
121 .Opcode = RC_OPCODE_KIL,
122 .Name = "KIL",
123 .NumSrcRegs = 1
124 },
125 {
126 .Opcode = RC_OPCODE_LG2,
127 .Name = "LG2",
128 .NumSrcRegs = 1,
129 .HasDstReg = 1,
130 .IsStandardScalar = 1
131 },
132 {
133 .Opcode = RC_OPCODE_LIT,
134 .Name = "LIT",
135 .NumSrcRegs = 1,
136 .HasDstReg = 1
137 },
138 {
139 .Opcode = RC_OPCODE_LOG,
140 .Name = "LOG",
141 .NumSrcRegs = 1,
142 .HasDstReg = 1
143 },
144 {
145 .Opcode = RC_OPCODE_MAD,
146 .Name = "MAD",
147 .NumSrcRegs = 3,
148 .HasDstReg = 1,
149 .IsComponentwise = 1
150 },
151 {
152 .Opcode = RC_OPCODE_MAX,
153 .Name = "MAX",
154 .NumSrcRegs = 2,
155 .HasDstReg = 1,
156 .IsComponentwise = 1
157 },
158 {
159 .Opcode = RC_OPCODE_MIN,
160 .Name = "MIN",
161 .NumSrcRegs = 2,
162 .HasDstReg = 1,
163 .IsComponentwise = 1
164 },
165 {
166 .Opcode = RC_OPCODE_MOV,
167 .Name = "MOV",
168 .NumSrcRegs = 1,
169 .HasDstReg = 1,
170 .IsComponentwise = 1
171 },
172 {
173 .Opcode = RC_OPCODE_MUL,
174 .Name = "MUL",
175 .NumSrcRegs = 2,
176 .HasDstReg = 1,
177 .IsComponentwise = 1
178 },
179 {
180 .Opcode = RC_OPCODE_POW,
181 .Name = "POW",
182 .NumSrcRegs = 2,
183 .HasDstReg = 1,
184 .IsStandardScalar = 1
185 },
186 {
187 .Opcode = RC_OPCODE_RCP,
188 .Name = "RCP",
189 .NumSrcRegs = 1,
190 .HasDstReg = 1,
191 .IsStandardScalar = 1
192 },
193 {
194 .Opcode = RC_OPCODE_ROUND,
195 .Name = "ROUND",
196 .NumSrcRegs = 1,
197 .HasDstReg = 1,
198 .IsComponentwise = 1
199 },
200 {
201 .Opcode = RC_OPCODE_RSQ,
202 .Name = "RSQ",
203 .NumSrcRegs = 1,
204 .HasDstReg = 1,
205 .IsStandardScalar = 1
206 },
207 {
208 .Opcode = RC_OPCODE_SEQ,
209 .Name = "SEQ",
210 .NumSrcRegs = 2,
211 .HasDstReg = 1,
212 .IsComponentwise = 1
213 },
214 {
215 .Opcode = RC_OPCODE_SGE,
216 .Name = "SGE",
217 .NumSrcRegs = 2,
218 .HasDstReg = 1,
219 .IsComponentwise = 1
220 },
221 {
222 .Opcode = RC_OPCODE_SIN,
223 .Name = "SIN",
224 .NumSrcRegs = 1,
225 .HasDstReg = 1,
226 .IsStandardScalar = 1
227 },
228 {
229 .Opcode = RC_OPCODE_SLT,
230 .Name = "SLT",
231 .NumSrcRegs = 2,
232 .HasDstReg = 1,
233 .IsComponentwise = 1
234 },
235 {
236 .Opcode = RC_OPCODE_SNE,
237 .Name = "SNE",
238 .NumSrcRegs = 2,
239 .HasDstReg = 1,
240 .IsComponentwise = 1
241 },
242 {
243 .Opcode = RC_OPCODE_TEX,
244 .Name = "TEX",
245 .HasTexture = 1,
246 .NumSrcRegs = 1,
247 .HasDstReg = 1
248 },
249 {
250 .Opcode = RC_OPCODE_TXB,
251 .Name = "TXB",
252 .HasTexture = 1,
253 .NumSrcRegs = 1,
254 .HasDstReg = 1
255 },
256 {
257 .Opcode = RC_OPCODE_TXD,
258 .Name = "TXD",
259 .HasTexture = 1,
260 .NumSrcRegs = 3,
261 .HasDstReg = 1
262 },
263 {
264 .Opcode = RC_OPCODE_TXL,
265 .Name = "TXL",
266 .HasTexture = 1,
267 .NumSrcRegs = 1,
268 .HasDstReg = 1
269 },
270 {
271 .Opcode = RC_OPCODE_TXP,
272 .Name = "TXP",
273 .HasTexture = 1,
274 .NumSrcRegs = 1,
275 .HasDstReg = 1
276 },
277 {
278 .Opcode = RC_OPCODE_IF,
279 .Name = "IF",
280 .IsFlowControl = 1,
281 .NumSrcRegs = 1
282 },
283 {
284 .Opcode = RC_OPCODE_ELSE,
285 .Name = "ELSE",
286 .IsFlowControl = 1,
287 .NumSrcRegs = 0
288 },
289 {
290 .Opcode = RC_OPCODE_ENDIF,
291 .Name = "ENDIF",
292 .IsFlowControl = 1,
293 .NumSrcRegs = 0
294 },
295 {
296 .Opcode = RC_OPCODE_BGNLOOP,
297 .Name = "BGNLOOP",
298 .IsFlowControl = 1,
299 .NumSrcRegs = 0
300 },
301 {
302 .Opcode = RC_OPCODE_BRK,
303 .Name = "BRK",
304 .IsFlowControl = 1,
305 .NumSrcRegs = 0
306 },
307 {
308 .Opcode = RC_OPCODE_ENDLOOP,
309 .Name = "ENDLOOP",
310 .IsFlowControl = 1,
311 .NumSrcRegs = 0,
312 },
313 {
314 .Opcode = RC_OPCODE_CONT,
315 .Name = "CONT",
316 .IsFlowControl = 1,
317 .NumSrcRegs = 0
318 },
319 {
320 .Opcode = RC_OPCODE_REPL_ALPHA,
321 .Name = "REPL_ALPHA",
322 .HasDstReg = 1
323 },
324 {
325 .Opcode = RC_OPCODE_BEGIN_TEX,
326 .Name = "BEGIN_TEX"
327 },
328 {
329 .Opcode = RC_OPCODE_KILP,
330 .Name = "KILP",
331 },
332 {
333 .Opcode = RC_ME_PRED_SEQ,
334 .Name = "ME_PRED_SEQ",
335 .NumSrcRegs = 1,
336 .HasDstReg = 1
337 },
338 {
339 .Opcode = RC_ME_PRED_SGT,
340 .Name = "ME_PRED_SGT",
341 .NumSrcRegs = 1,
342 .HasDstReg = 1
343 },
344 {
345 .Opcode = RC_ME_PRED_SGE,
346 .Name = "ME_PRED_SGE",
347 .NumSrcRegs = 1,
348 .HasDstReg = 1
349 },
350 {
351 .Opcode = RC_ME_PRED_SNEQ,
352 .Name = "ME_PRED_SNEQ",
353 .NumSrcRegs = 1,
354 .HasDstReg = 1
355 },
356 {
357 .Opcode = RC_ME_PRED_SET_CLR,
358 .Name = "ME_PRED_SET_CLEAR",
359 .NumSrcRegs = 1,
360 .HasDstReg = 1
361 },
362 {
363 .Opcode = RC_ME_PRED_SET_INV,
364 .Name = "ME_PRED_SET_INV",
365 .NumSrcRegs = 1,
366 .HasDstReg = 1
367 },
368 {
369 .Opcode = RC_ME_PRED_SET_POP,
370 .Name = "ME_PRED_SET_POP",
371 .NumSrcRegs = 1,
372 .HasDstReg = 1
373 },
374 {
375 .Opcode = RC_ME_PRED_SET_RESTORE,
376 .Name = "ME_PRED_SET_RESTORE",
377 .NumSrcRegs = 1,
378 .HasDstReg = 1
379 },
380 {
381 .Opcode = RC_VE_PRED_SEQ_PUSH,
382 .Name = "VE_PRED_SEQ_PUSH",
383 .NumSrcRegs = 2,
384 .HasDstReg = 1
385 },
386 {
387 .Opcode = RC_VE_PRED_SGT_PUSH,
388 .Name = "VE_PRED_SGT_PUSH",
389 .NumSrcRegs = 2,
390 .HasDstReg = 1
391 },
392 {
393 .Opcode = RC_VE_PRED_SGE_PUSH,
394 .Name = "VE_PRED_SGE_PUSH",
395 .NumSrcRegs = 2,
396 .HasDstReg = 1
397 },
398 {
399 .Opcode = RC_VE_PRED_SNEQ_PUSH,
400 .Name = "VE_PRED_SNEQ_PUSH",
401 .NumSrcRegs = 2,
402 .HasDstReg = 1
403 }
404 };
405
rc_compute_sources_for_writemask(const struct rc_instruction * inst,unsigned int writemask,unsigned int * srcmasks)406 void rc_compute_sources_for_writemask(
407 const struct rc_instruction *inst,
408 unsigned int writemask,
409 unsigned int *srcmasks)
410 {
411 const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
412 srcmasks[0] = 0;
413 srcmasks[1] = 0;
414 srcmasks[2] = 0;
415
416 if (opcode->Opcode == RC_OPCODE_KIL)
417 srcmasks[0] |= RC_MASK_XYZW;
418 else if (opcode->Opcode == RC_OPCODE_IF)
419 srcmasks[0] |= RC_MASK_X;
420
421 if (!writemask)
422 return;
423
424 if (opcode->IsComponentwise) {
425 for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src)
426 srcmasks[src] |= writemask;
427 } else if (opcode->IsStandardScalar) {
428 for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src)
429 srcmasks[src] |= writemask;
430 } else {
431 switch(opcode->Opcode) {
432 case RC_OPCODE_ARL:
433 case RC_OPCODE_ARR:
434 srcmasks[0] |= RC_MASK_X;
435 break;
436 case RC_OPCODE_DP2:
437 srcmasks[0] |= RC_MASK_XY;
438 srcmasks[1] |= RC_MASK_XY;
439 break;
440 case RC_OPCODE_DP3:
441 srcmasks[0] |= RC_MASK_XYZ;
442 srcmasks[1] |= RC_MASK_XYZ;
443 break;
444 case RC_OPCODE_DP4:
445 srcmasks[0] |= RC_MASK_XYZW;
446 srcmasks[1] |= RC_MASK_XYZW;
447 break;
448 case RC_OPCODE_TXB:
449 case RC_OPCODE_TXP:
450 case RC_OPCODE_TXL:
451 srcmasks[0] |= RC_MASK_W;
452 FALLTHROUGH;
453 case RC_OPCODE_TEX:
454 switch (inst->U.I.TexSrcTarget) {
455 case RC_TEXTURE_1D:
456 srcmasks[0] |= RC_MASK_X;
457 break;
458 case RC_TEXTURE_2D:
459 case RC_TEXTURE_RECT:
460 case RC_TEXTURE_1D_ARRAY:
461 srcmasks[0] |= RC_MASK_XY;
462 break;
463 case RC_TEXTURE_3D:
464 case RC_TEXTURE_CUBE:
465 case RC_TEXTURE_2D_ARRAY:
466 srcmasks[0] |= RC_MASK_XYZ;
467 break;
468 }
469 break;
470 case RC_OPCODE_TXD:
471 switch (inst->U.I.TexSrcTarget) {
472 case RC_TEXTURE_1D_ARRAY:
473 srcmasks[0] |= RC_MASK_Y;
474 FALLTHROUGH;
475 case RC_TEXTURE_1D:
476 srcmasks[0] |= RC_MASK_X;
477 srcmasks[1] |= RC_MASK_X;
478 srcmasks[2] |= RC_MASK_X;
479 break;
480 case RC_TEXTURE_2D_ARRAY:
481 srcmasks[0] |= RC_MASK_Z;
482 FALLTHROUGH;
483 case RC_TEXTURE_2D:
484 case RC_TEXTURE_RECT:
485 srcmasks[0] |= RC_MASK_XY;
486 srcmasks[1] |= RC_MASK_XY;
487 srcmasks[2] |= RC_MASK_XY;
488 break;
489 case RC_TEXTURE_3D:
490 case RC_TEXTURE_CUBE:
491 srcmasks[0] |= RC_MASK_XYZ;
492 srcmasks[1] |= RC_MASK_XYZ;
493 srcmasks[2] |= RC_MASK_XYZ;
494 break;
495 }
496 break;
497 case RC_OPCODE_DST:
498 srcmasks[0] |= RC_MASK_Y | RC_MASK_Z;
499 srcmasks[1] |= RC_MASK_Y | RC_MASK_W;
500 break;
501 case RC_OPCODE_EXP:
502 case RC_OPCODE_LOG:
503 srcmasks[0] |= RC_MASK_XY;
504 break;
505 case RC_OPCODE_LIT:
506 srcmasks[0] |= RC_MASK_X | RC_MASK_Y | RC_MASK_W;
507 break;
508 default:
509 break;
510 }
511 }
512 }
513