1 /*
2 * Copyright (C) 2009 Nicolai Haehnle.
3 *
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 */
27
28 #include "radeon_opcodes.h"
29 #include "radeon_program.h"
30
31 #include "radeon_program_constants.h"
32
33 #include "util/compiler.h"
34
35 const struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE] = {
36 {
37 .Opcode = RC_OPCODE_NOP,
38 .Name = "NOP"
39 },
40 {
41 .Opcode = RC_OPCODE_ILLEGAL_OPCODE,
42 .Name = "ILLEGAL OPCODE"
43 },
44 {
45 .Opcode = RC_OPCODE_ADD,
46 .Name = "ADD",
47 .NumSrcRegs = 2,
48 .HasDstReg = 1,
49 .IsComponentwise = 1
50 },
51 {
52 .Opcode = RC_OPCODE_ARL,
53 .Name = "ARL",
54 .NumSrcRegs = 1,
55 .HasDstReg = 1
56 },
57 {
58 .Opcode = RC_OPCODE_ARR,
59 .Name = "ARR",
60 .NumSrcRegs = 1,
61 .HasDstReg = 1
62 },
63 {
64 .Opcode = RC_OPCODE_CEIL,
65 .Name = "CEIL",
66 .NumSrcRegs = 1,
67 .HasDstReg = 1,
68 .IsComponentwise = 1
69 },
70 {
71 .Opcode = RC_OPCODE_CMP,
72 .Name = "CMP",
73 .NumSrcRegs = 3,
74 .HasDstReg = 1,
75 .IsComponentwise = 1
76 },
77 {
78 .Opcode = RC_OPCODE_CND,
79 .Name = "CND",
80 .NumSrcRegs = 3,
81 .HasDstReg = 1,
82 .IsComponentwise = 1
83 },
84 {
85 .Opcode = RC_OPCODE_COS,
86 .Name = "COS",
87 .NumSrcRegs = 1,
88 .HasDstReg = 1,
89 .IsStandardScalar = 1
90 },
91 {
92 .Opcode = RC_OPCODE_DDX,
93 .Name = "DDX",
94 .NumSrcRegs = 2,
95 .HasDstReg = 1,
96 .IsComponentwise = 1
97 },
98 {
99 .Opcode = RC_OPCODE_DDY,
100 .Name = "DDY",
101 .NumSrcRegs = 2,
102 .HasDstReg = 1,
103 .IsComponentwise = 1
104 },
105 {
106 .Opcode = RC_OPCODE_DP2,
107 .Name = "DP2",
108 .NumSrcRegs = 2,
109 .HasDstReg = 1
110 },
111 {
112 .Opcode = RC_OPCODE_DP3,
113 .Name = "DP3",
114 .NumSrcRegs = 2,
115 .HasDstReg = 1
116 },
117 {
118 .Opcode = RC_OPCODE_DP4,
119 .Name = "DP4",
120 .NumSrcRegs = 2,
121 .HasDstReg = 1
122 },
123 {
124 .Opcode = RC_OPCODE_DST,
125 .Name = "DST",
126 .NumSrcRegs = 2,
127 .HasDstReg = 1
128 },
129 {
130 .Opcode = RC_OPCODE_EX2,
131 .Name = "EX2",
132 .NumSrcRegs = 1,
133 .HasDstReg = 1,
134 .IsStandardScalar = 1
135 },
136 {
137 .Opcode = RC_OPCODE_EXP,
138 .Name = "EXP",
139 .NumSrcRegs = 1,
140 .HasDstReg = 1
141 },
142 {
143 .Opcode = RC_OPCODE_FLR,
144 .Name = "FLR",
145 .NumSrcRegs = 1,
146 .HasDstReg = 1,
147 .IsComponentwise = 1
148 },
149 {
150 .Opcode = RC_OPCODE_FRC,
151 .Name = "FRC",
152 .NumSrcRegs = 1,
153 .HasDstReg = 1,
154 .IsComponentwise = 1
155 },
156 {
157 .Opcode = RC_OPCODE_KIL,
158 .Name = "KIL",
159 .NumSrcRegs = 1
160 },
161 {
162 .Opcode = RC_OPCODE_LG2,
163 .Name = "LG2",
164 .NumSrcRegs = 1,
165 .HasDstReg = 1,
166 .IsStandardScalar = 1
167 },
168 {
169 .Opcode = RC_OPCODE_LIT,
170 .Name = "LIT",
171 .NumSrcRegs = 1,
172 .HasDstReg = 1
173 },
174 {
175 .Opcode = RC_OPCODE_LOG,
176 .Name = "LOG",
177 .NumSrcRegs = 1,
178 .HasDstReg = 1
179 },
180 {
181 .Opcode = RC_OPCODE_LRP,
182 .Name = "LRP",
183 .NumSrcRegs = 3,
184 .HasDstReg = 1,
185 .IsComponentwise = 1
186 },
187 {
188 .Opcode = RC_OPCODE_MAD,
189 .Name = "MAD",
190 .NumSrcRegs = 3,
191 .HasDstReg = 1,
192 .IsComponentwise = 1
193 },
194 {
195 .Opcode = RC_OPCODE_MAX,
196 .Name = "MAX",
197 .NumSrcRegs = 2,
198 .HasDstReg = 1,
199 .IsComponentwise = 1
200 },
201 {
202 .Opcode = RC_OPCODE_MIN,
203 .Name = "MIN",
204 .NumSrcRegs = 2,
205 .HasDstReg = 1,
206 .IsComponentwise = 1
207 },
208 {
209 .Opcode = RC_OPCODE_MOV,
210 .Name = "MOV",
211 .NumSrcRegs = 1,
212 .HasDstReg = 1,
213 .IsComponentwise = 1
214 },
215 {
216 .Opcode = RC_OPCODE_MUL,
217 .Name = "MUL",
218 .NumSrcRegs = 2,
219 .HasDstReg = 1,
220 .IsComponentwise = 1
221 },
222 {
223 .Opcode = RC_OPCODE_POW,
224 .Name = "POW",
225 .NumSrcRegs = 2,
226 .HasDstReg = 1,
227 .IsStandardScalar = 1
228 },
229 {
230 .Opcode = RC_OPCODE_RCP,
231 .Name = "RCP",
232 .NumSrcRegs = 1,
233 .HasDstReg = 1,
234 .IsStandardScalar = 1
235 },
236 {
237 .Opcode = RC_OPCODE_ROUND,
238 .Name = "ROUND",
239 .NumSrcRegs = 1,
240 .HasDstReg = 1,
241 .IsComponentwise = 1
242 },
243 {
244 .Opcode = RC_OPCODE_RSQ,
245 .Name = "RSQ",
246 .NumSrcRegs = 1,
247 .HasDstReg = 1,
248 .IsStandardScalar = 1
249 },
250 {
251 .Opcode = RC_OPCODE_SEQ,
252 .Name = "SEQ",
253 .NumSrcRegs = 2,
254 .HasDstReg = 1,
255 .IsComponentwise = 1
256 },
257 {
258 .Opcode = RC_OPCODE_SGE,
259 .Name = "SGE",
260 .NumSrcRegs = 2,
261 .HasDstReg = 1,
262 .IsComponentwise = 1
263 },
264 {
265 .Opcode = RC_OPCODE_SGT,
266 .Name = "SGT",
267 .NumSrcRegs = 2,
268 .HasDstReg = 1,
269 .IsComponentwise = 1
270 },
271 {
272 .Opcode = RC_OPCODE_SIN,
273 .Name = "SIN",
274 .NumSrcRegs = 1,
275 .HasDstReg = 1,
276 .IsStandardScalar = 1
277 },
278 {
279 .Opcode = RC_OPCODE_SLE,
280 .Name = "SLE",
281 .NumSrcRegs = 2,
282 .HasDstReg = 1,
283 .IsComponentwise = 1
284 },
285 {
286 .Opcode = RC_OPCODE_SLT,
287 .Name = "SLT",
288 .NumSrcRegs = 2,
289 .HasDstReg = 1,
290 .IsComponentwise = 1
291 },
292 {
293 .Opcode = RC_OPCODE_SNE,
294 .Name = "SNE",
295 .NumSrcRegs = 2,
296 .HasDstReg = 1,
297 .IsComponentwise = 1
298 },
299 {
300 .Opcode = RC_OPCODE_SSG,
301 .Name = "SSG",
302 .NumSrcRegs = 1,
303 .HasDstReg = 1,
304 .IsComponentwise = 1
305 },
306 {
307 .Opcode = RC_OPCODE_SUB,
308 .Name = "SUB",
309 .NumSrcRegs = 2,
310 .HasDstReg = 1,
311 .IsComponentwise = 1
312 },
313 {
314 .Opcode = RC_OPCODE_TRUNC,
315 .Name = "TRUNC",
316 .NumSrcRegs = 1,
317 .HasDstReg = 1,
318 .IsComponentwise = 1
319 },
320 {
321 .Opcode = RC_OPCODE_TEX,
322 .Name = "TEX",
323 .HasTexture = 1,
324 .NumSrcRegs = 1,
325 .HasDstReg = 1
326 },
327 {
328 .Opcode = RC_OPCODE_TXB,
329 .Name = "TXB",
330 .HasTexture = 1,
331 .NumSrcRegs = 1,
332 .HasDstReg = 1
333 },
334 {
335 .Opcode = RC_OPCODE_TXD,
336 .Name = "TXD",
337 .HasTexture = 1,
338 .NumSrcRegs = 3,
339 .HasDstReg = 1
340 },
341 {
342 .Opcode = RC_OPCODE_TXL,
343 .Name = "TXL",
344 .HasTexture = 1,
345 .NumSrcRegs = 1,
346 .HasDstReg = 1
347 },
348 {
349 .Opcode = RC_OPCODE_TXP,
350 .Name = "TXP",
351 .HasTexture = 1,
352 .NumSrcRegs = 1,
353 .HasDstReg = 1
354 },
355 {
356 .Opcode = RC_OPCODE_IF,
357 .Name = "IF",
358 .IsFlowControl = 1,
359 .NumSrcRegs = 1
360 },
361 {
362 .Opcode = RC_OPCODE_ELSE,
363 .Name = "ELSE",
364 .IsFlowControl = 1,
365 .NumSrcRegs = 0
366 },
367 {
368 .Opcode = RC_OPCODE_ENDIF,
369 .Name = "ENDIF",
370 .IsFlowControl = 1,
371 .NumSrcRegs = 0
372 },
373 {
374 .Opcode = RC_OPCODE_BGNLOOP,
375 .Name = "BGNLOOP",
376 .IsFlowControl = 1,
377 .NumSrcRegs = 0
378 },
379 {
380 .Opcode = RC_OPCODE_BRK,
381 .Name = "BRK",
382 .IsFlowControl = 1,
383 .NumSrcRegs = 0
384 },
385 {
386 .Opcode = RC_OPCODE_ENDLOOP,
387 .Name = "ENDLOOP",
388 .IsFlowControl = 1,
389 .NumSrcRegs = 0,
390 },
391 {
392 .Opcode = RC_OPCODE_CONT,
393 .Name = "CONT",
394 .IsFlowControl = 1,
395 .NumSrcRegs = 0
396 },
397 {
398 .Opcode = RC_OPCODE_REPL_ALPHA,
399 .Name = "REPL_ALPHA",
400 .HasDstReg = 1
401 },
402 {
403 .Opcode = RC_OPCODE_BEGIN_TEX,
404 .Name = "BEGIN_TEX"
405 },
406 {
407 .Opcode = RC_OPCODE_KILP,
408 .Name = "KILP",
409 },
410 {
411 .Opcode = RC_ME_PRED_SEQ,
412 .Name = "ME_PRED_SEQ",
413 .NumSrcRegs = 1,
414 .HasDstReg = 1
415 },
416 {
417 .Opcode = RC_ME_PRED_SGT,
418 .Name = "ME_PRED_SGT",
419 .NumSrcRegs = 1,
420 .HasDstReg = 1
421 },
422 {
423 .Opcode = RC_ME_PRED_SGE,
424 .Name = "ME_PRED_SGE",
425 .NumSrcRegs = 1,
426 .HasDstReg = 1
427 },
428 {
429 .Opcode = RC_ME_PRED_SNEQ,
430 .Name = "ME_PRED_SNEQ",
431 .NumSrcRegs = 1,
432 .HasDstReg = 1
433 },
434 {
435 .Opcode = RC_ME_PRED_SET_CLR,
436 .Name = "ME_PRED_SET_CLEAR",
437 .NumSrcRegs = 1,
438 .HasDstReg = 1
439 },
440 {
441 .Opcode = RC_ME_PRED_SET_INV,
442 .Name = "ME_PRED_SET_INV",
443 .NumSrcRegs = 1,
444 .HasDstReg = 1
445 },
446 {
447 .Opcode = RC_ME_PRED_SET_POP,
448 .Name = "ME_PRED_SET_POP",
449 .NumSrcRegs = 1,
450 .HasDstReg = 1
451 },
452 {
453 .Opcode = RC_ME_PRED_SET_RESTORE,
454 .Name = "ME_PRED_SET_RESTORE",
455 .NumSrcRegs = 1,
456 .HasDstReg = 1
457 },
458 {
459 .Opcode = RC_VE_PRED_SEQ_PUSH,
460 .Name = "VE_PRED_SEQ_PUSH",
461 .NumSrcRegs = 2,
462 .HasDstReg = 1
463 },
464 {
465 .Opcode = RC_VE_PRED_SGT_PUSH,
466 .Name = "VE_PRED_SGT_PUSH",
467 .NumSrcRegs = 2,
468 .HasDstReg = 1
469 },
470 {
471 .Opcode = RC_VE_PRED_SGE_PUSH,
472 .Name = "VE_PRED_SGE_PUSH",
473 .NumSrcRegs = 2,
474 .HasDstReg = 1
475 },
476 {
477 .Opcode = RC_VE_PRED_SNEQ_PUSH,
478 .Name = "VE_PRED_SNEQ_PUSH",
479 .NumSrcRegs = 2,
480 .HasDstReg = 1
481 }
482 };
483
rc_compute_sources_for_writemask( const struct rc_instruction *inst, unsigned int writemask, unsigned int *srcmasks)484 void rc_compute_sources_for_writemask(
485 const struct rc_instruction *inst,
486 unsigned int writemask,
487 unsigned int *srcmasks)
488 {
489 const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
490 srcmasks[0] = 0;
491 srcmasks[1] = 0;
492 srcmasks[2] = 0;
493
494 if (opcode->Opcode == RC_OPCODE_KIL)
495 srcmasks[0] |= RC_MASK_XYZW;
496 else if (opcode->Opcode == RC_OPCODE_IF)
497 srcmasks[0] |= RC_MASK_X;
498
499 if (!writemask)
500 return;
501
502 if (opcode->IsComponentwise) {
503 for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src)
504 srcmasks[src] |= writemask;
505 } else if (opcode->IsStandardScalar) {
506 for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src)
507 srcmasks[src] |= writemask;
508 } else {
509 switch(opcode->Opcode) {
510 case RC_OPCODE_ARL:
511 case RC_OPCODE_ARR:
512 srcmasks[0] |= RC_MASK_X;
513 break;
514 case RC_OPCODE_DP2:
515 srcmasks[0] |= RC_MASK_XY;
516 srcmasks[1] |= RC_MASK_XY;
517 break;
518 case RC_OPCODE_DP3:
519 srcmasks[0] |= RC_MASK_XYZ;
520 srcmasks[1] |= RC_MASK_XYZ;
521 break;
522 case RC_OPCODE_DP4:
523 srcmasks[0] |= RC_MASK_XYZW;
524 srcmasks[1] |= RC_MASK_XYZW;
525 break;
526 case RC_OPCODE_TXB:
527 case RC_OPCODE_TXP:
528 case RC_OPCODE_TXL:
529 srcmasks[0] |= RC_MASK_W;
530 FALLTHROUGH;
531 case RC_OPCODE_TEX:
532 switch (inst->U.I.TexSrcTarget) {
533 case RC_TEXTURE_1D:
534 srcmasks[0] |= RC_MASK_X;
535 break;
536 case RC_TEXTURE_2D:
537 case RC_TEXTURE_RECT:
538 case RC_TEXTURE_1D_ARRAY:
539 srcmasks[0] |= RC_MASK_XY;
540 break;
541 case RC_TEXTURE_3D:
542 case RC_TEXTURE_CUBE:
543 case RC_TEXTURE_2D_ARRAY:
544 srcmasks[0] |= RC_MASK_XYZ;
545 break;
546 }
547 break;
548 case RC_OPCODE_TXD:
549 switch (inst->U.I.TexSrcTarget) {
550 case RC_TEXTURE_1D_ARRAY:
551 srcmasks[0] |= RC_MASK_Y;
552 FALLTHROUGH;
553 case RC_TEXTURE_1D:
554 srcmasks[0] |= RC_MASK_X;
555 srcmasks[1] |= RC_MASK_X;
556 srcmasks[2] |= RC_MASK_X;
557 break;
558 case RC_TEXTURE_2D_ARRAY:
559 srcmasks[0] |= RC_MASK_Z;
560 FALLTHROUGH;
561 case RC_TEXTURE_2D:
562 case RC_TEXTURE_RECT:
563 srcmasks[0] |= RC_MASK_XY;
564 srcmasks[1] |= RC_MASK_XY;
565 srcmasks[2] |= RC_MASK_XY;
566 break;
567 case RC_TEXTURE_3D:
568 case RC_TEXTURE_CUBE:
569 srcmasks[0] |= RC_MASK_XYZ;
570 srcmasks[1] |= RC_MASK_XYZ;
571 srcmasks[2] |= RC_MASK_XYZ;
572 break;
573 }
574 break;
575 case RC_OPCODE_DST:
576 srcmasks[0] |= RC_MASK_Y | RC_MASK_Z;
577 srcmasks[1] |= RC_MASK_Y | RC_MASK_W;
578 break;
579 case RC_OPCODE_EXP:
580 case RC_OPCODE_LOG:
581 srcmasks[0] |= RC_MASK_XY;
582 break;
583 case RC_OPCODE_LIT:
584 srcmasks[0] |= RC_MASK_X | RC_MASK_Y | RC_MASK_W;
585 break;
586 default:
587 break;
588 }
589 }
590 }
591