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_ABS,
46 .Name = "ABS",
47 .NumSrcRegs = 1,
48 .HasDstReg = 1,
49 .IsComponentwise = 1
50 },
51 {
52 .Opcode = RC_OPCODE_ADD,
53 .Name = "ADD",
54 .NumSrcRegs = 2,
55 .HasDstReg = 1,
56 .IsComponentwise = 1
57 },
58 {
59 .Opcode = RC_OPCODE_ARL,
60 .Name = "ARL",
61 .NumSrcRegs = 1,
62 .HasDstReg = 1
63 },
64 {
65 .Opcode = RC_OPCODE_ARR,
66 .Name = "ARR",
67 .NumSrcRegs = 1,
68 .HasDstReg = 1
69 },
70 {
71 .Opcode = RC_OPCODE_CEIL,
72 .Name = "CEIL",
73 .NumSrcRegs = 1,
74 .HasDstReg = 1,
75 .IsComponentwise = 1
76 },
77 {
78 .Opcode = RC_OPCODE_CLAMP,
79 .Name = "CLAMP",
80 .NumSrcRegs = 3,
81 .HasDstReg = 1,
82 .IsComponentwise = 1
83 },
84 {
85 .Opcode = RC_OPCODE_CMP,
86 .Name = "CMP",
87 .NumSrcRegs = 3,
88 .HasDstReg = 1,
89 .IsComponentwise = 1
90 },
91 {
92 .Opcode = RC_OPCODE_CND,
93 .Name = "CND",
94 .NumSrcRegs = 3,
95 .HasDstReg = 1,
96 .IsComponentwise = 1
97 },
98 {
99 .Opcode = RC_OPCODE_COS,
100 .Name = "COS",
101 .NumSrcRegs = 1,
102 .HasDstReg = 1,
103 .IsStandardScalar = 1
104 },
105 {
106 .Opcode = RC_OPCODE_DDX,
107 .Name = "DDX",
108 .NumSrcRegs = 2,
109 .HasDstReg = 1,
110 .IsComponentwise = 1
111 },
112 {
113 .Opcode = RC_OPCODE_DDY,
114 .Name = "DDY",
115 .NumSrcRegs = 2,
116 .HasDstReg = 1,
117 .IsComponentwise = 1
118 },
119 {
120 .Opcode = RC_OPCODE_DP2,
121 .Name = "DP2",
122 .NumSrcRegs = 2,
123 .HasDstReg = 1
124 },
125 {
126 .Opcode = RC_OPCODE_DP3,
127 .Name = "DP3",
128 .NumSrcRegs = 2,
129 .HasDstReg = 1
130 },
131 {
132 .Opcode = RC_OPCODE_DP4,
133 .Name = "DP4",
134 .NumSrcRegs = 2,
135 .HasDstReg = 1
136 },
137 {
138 .Opcode = RC_OPCODE_DPH,
139 .Name = "DPH",
140 .NumSrcRegs = 2,
141 .HasDstReg = 1
142 },
143 {
144 .Opcode = RC_OPCODE_DST,
145 .Name = "DST",
146 .NumSrcRegs = 2,
147 .HasDstReg = 1
148 },
149 {
150 .Opcode = RC_OPCODE_EX2,
151 .Name = "EX2",
152 .NumSrcRegs = 1,
153 .HasDstReg = 1,
154 .IsStandardScalar = 1
155 },
156 {
157 .Opcode = RC_OPCODE_EXP,
158 .Name = "EXP",
159 .NumSrcRegs = 1,
160 .HasDstReg = 1
161 },
162 {
163 .Opcode = RC_OPCODE_FLR,
164 .Name = "FLR",
165 .NumSrcRegs = 1,
166 .HasDstReg = 1,
167 .IsComponentwise = 1
168 },
169 {
170 .Opcode = RC_OPCODE_FRC,
171 .Name = "FRC",
172 .NumSrcRegs = 1,
173 .HasDstReg = 1,
174 .IsComponentwise = 1
175 },
176 {
177 .Opcode = RC_OPCODE_KIL,
178 .Name = "KIL",
179 .NumSrcRegs = 1
180 },
181 {
182 .Opcode = RC_OPCODE_LG2,
183 .Name = "LG2",
184 .NumSrcRegs = 1,
185 .HasDstReg = 1,
186 .IsStandardScalar = 1
187 },
188 {
189 .Opcode = RC_OPCODE_LIT,
190 .Name = "LIT",
191 .NumSrcRegs = 1,
192 .HasDstReg = 1
193 },
194 {
195 .Opcode = RC_OPCODE_LOG,
196 .Name = "LOG",
197 .NumSrcRegs = 1,
198 .HasDstReg = 1
199 },
200 {
201 .Opcode = RC_OPCODE_LRP,
202 .Name = "LRP",
203 .NumSrcRegs = 3,
204 .HasDstReg = 1,
205 .IsComponentwise = 1
206 },
207 {
208 .Opcode = RC_OPCODE_MAD,
209 .Name = "MAD",
210 .NumSrcRegs = 3,
211 .HasDstReg = 1,
212 .IsComponentwise = 1
213 },
214 {
215 .Opcode = RC_OPCODE_MAX,
216 .Name = "MAX",
217 .NumSrcRegs = 2,
218 .HasDstReg = 1,
219 .IsComponentwise = 1
220 },
221 {
222 .Opcode = RC_OPCODE_MIN,
223 .Name = "MIN",
224 .NumSrcRegs = 2,
225 .HasDstReg = 1,
226 .IsComponentwise = 1
227 },
228 {
229 .Opcode = RC_OPCODE_MOV,
230 .Name = "MOV",
231 .NumSrcRegs = 1,
232 .HasDstReg = 1,
233 .IsComponentwise = 1
234 },
235 {
236 .Opcode = RC_OPCODE_MUL,
237 .Name = "MUL",
238 .NumSrcRegs = 2,
239 .HasDstReg = 1,
240 .IsComponentwise = 1
241 },
242 {
243 .Opcode = RC_OPCODE_POW,
244 .Name = "POW",
245 .NumSrcRegs = 2,
246 .HasDstReg = 1,
247 .IsStandardScalar = 1
248 },
249 {
250 .Opcode = RC_OPCODE_RCP,
251 .Name = "RCP",
252 .NumSrcRegs = 1,
253 .HasDstReg = 1,
254 .IsStandardScalar = 1
255 },
256 {
257 .Opcode = RC_OPCODE_ROUND,
258 .Name = "ROUND",
259 .NumSrcRegs = 1,
260 .HasDstReg = 1,
261 .IsComponentwise = 1
262 },
263 {
264 .Opcode = RC_OPCODE_RSQ,
265 .Name = "RSQ",
266 .NumSrcRegs = 1,
267 .HasDstReg = 1,
268 .IsStandardScalar = 1
269 },
270 {
271 .Opcode = RC_OPCODE_SCS,
272 .Name = "SCS",
273 .NumSrcRegs = 1,
274 .HasDstReg = 1
275 },
276 {
277 .Opcode = RC_OPCODE_SEQ,
278 .Name = "SEQ",
279 .NumSrcRegs = 2,
280 .HasDstReg = 1,
281 .IsComponentwise = 1
282 },
283 {
284 .Opcode = RC_OPCODE_SFL,
285 .Name = "SFL",
286 .NumSrcRegs = 0,
287 .HasDstReg = 1,
288 .IsComponentwise = 1
289 },
290 {
291 .Opcode = RC_OPCODE_SGE,
292 .Name = "SGE",
293 .NumSrcRegs = 2,
294 .HasDstReg = 1,
295 .IsComponentwise = 1
296 },
297 {
298 .Opcode = RC_OPCODE_SGT,
299 .Name = "SGT",
300 .NumSrcRegs = 2,
301 .HasDstReg = 1,
302 .IsComponentwise = 1
303 },
304 {
305 .Opcode = RC_OPCODE_SIN,
306 .Name = "SIN",
307 .NumSrcRegs = 1,
308 .HasDstReg = 1,
309 .IsStandardScalar = 1
310 },
311 {
312 .Opcode = RC_OPCODE_SLE,
313 .Name = "SLE",
314 .NumSrcRegs = 2,
315 .HasDstReg = 1,
316 .IsComponentwise = 1
317 },
318 {
319 .Opcode = RC_OPCODE_SLT,
320 .Name = "SLT",
321 .NumSrcRegs = 2,
322 .HasDstReg = 1,
323 .IsComponentwise = 1
324 },
325 {
326 .Opcode = RC_OPCODE_SNE,
327 .Name = "SNE",
328 .NumSrcRegs = 2,
329 .HasDstReg = 1,
330 .IsComponentwise = 1
331 },
332 {
333 .Opcode = RC_OPCODE_SSG,
334 .Name = "SSG",
335 .NumSrcRegs = 1,
336 .HasDstReg = 1,
337 .IsComponentwise = 1
338 },
339 {
340 .Opcode = RC_OPCODE_SUB,
341 .Name = "SUB",
342 .NumSrcRegs = 2,
343 .HasDstReg = 1,
344 .IsComponentwise = 1
345 },
346 {
347 .Opcode = RC_OPCODE_SWZ,
348 .Name = "SWZ",
349 .NumSrcRegs = 1,
350 .HasDstReg = 1,
351 .IsComponentwise = 1
352 },
353 {
354 .Opcode = RC_OPCODE_TRUNC,
355 .Name = "TRUNC",
356 .NumSrcRegs = 1,
357 .HasDstReg = 1,
358 .IsComponentwise = 1
359 },
360 {
361 .Opcode = RC_OPCODE_XPD,
362 .Name = "XPD",
363 .NumSrcRegs = 2,
364 .HasDstReg = 1
365 },
366 {
367 .Opcode = RC_OPCODE_TEX,
368 .Name = "TEX",
369 .HasTexture = 1,
370 .NumSrcRegs = 1,
371 .HasDstReg = 1
372 },
373 {
374 .Opcode = RC_OPCODE_TXB,
375 .Name = "TXB",
376 .HasTexture = 1,
377 .NumSrcRegs = 1,
378 .HasDstReg = 1
379 },
380 {
381 .Opcode = RC_OPCODE_TXD,
382 .Name = "TXD",
383 .HasTexture = 1,
384 .NumSrcRegs = 3,
385 .HasDstReg = 1
386 },
387 {
388 .Opcode = RC_OPCODE_TXL,
389 .Name = "TXL",
390 .HasTexture = 1,
391 .NumSrcRegs = 1,
392 .HasDstReg = 1
393 },
394 {
395 .Opcode = RC_OPCODE_TXP,
396 .Name = "TXP",
397 .HasTexture = 1,
398 .NumSrcRegs = 1,
399 .HasDstReg = 1
400 },
401 {
402 .Opcode = RC_OPCODE_IF,
403 .Name = "IF",
404 .IsFlowControl = 1,
405 .NumSrcRegs = 1
406 },
407 {
408 .Opcode = RC_OPCODE_ELSE,
409 .Name = "ELSE",
410 .IsFlowControl = 1,
411 .NumSrcRegs = 0
412 },
413 {
414 .Opcode = RC_OPCODE_ENDIF,
415 .Name = "ENDIF",
416 .IsFlowControl = 1,
417 .NumSrcRegs = 0
418 },
419 {
420 .Opcode = RC_OPCODE_BGNLOOP,
421 .Name = "BGNLOOP",
422 .IsFlowControl = 1,
423 .NumSrcRegs = 0
424 },
425 {
426 .Opcode = RC_OPCODE_BRK,
427 .Name = "BRK",
428 .IsFlowControl = 1,
429 .NumSrcRegs = 0
430 },
431 {
432 .Opcode = RC_OPCODE_ENDLOOP,
433 .Name = "ENDLOOP",
434 .IsFlowControl = 1,
435 .NumSrcRegs = 0,
436 },
437 {
438 .Opcode = RC_OPCODE_CONT,
439 .Name = "CONT",
440 .IsFlowControl = 1,
441 .NumSrcRegs = 0
442 },
443 {
444 .Opcode = RC_OPCODE_REPL_ALPHA,
445 .Name = "REPL_ALPHA",
446 .HasDstReg = 1
447 },
448 {
449 .Opcode = RC_OPCODE_BEGIN_TEX,
450 .Name = "BEGIN_TEX"
451 },
452 {
453 .Opcode = RC_OPCODE_KILP,
454 .Name = "KILP",
455 },
456 {
457 .Opcode = RC_ME_PRED_SEQ,
458 .Name = "ME_PRED_SEQ",
459 .NumSrcRegs = 1,
460 .HasDstReg = 1
461 },
462 {
463 .Opcode = RC_ME_PRED_SGT,
464 .Name = "ME_PRED_SGT",
465 .NumSrcRegs = 1,
466 .HasDstReg = 1
467 },
468 {
469 .Opcode = RC_ME_PRED_SGE,
470 .Name = "ME_PRED_SGE",
471 .NumSrcRegs = 1,
472 .HasDstReg = 1
473 },
474 {
475 .Opcode = RC_ME_PRED_SNEQ,
476 .Name = "ME_PRED_SNEQ",
477 .NumSrcRegs = 1,
478 .HasDstReg = 1
479 },
480 {
481 .Opcode = RC_ME_PRED_SET_CLR,
482 .Name = "ME_PRED_SET_CLEAR",
483 .NumSrcRegs = 1,
484 .HasDstReg = 1
485 },
486 {
487 .Opcode = RC_ME_PRED_SET_INV,
488 .Name = "ME_PRED_SET_INV",
489 .NumSrcRegs = 1,
490 .HasDstReg = 1
491 },
492 {
493 .Opcode = RC_ME_PRED_SET_POP,
494 .Name = "ME_PRED_SET_POP",
495 .NumSrcRegs = 1,
496 .HasDstReg = 1
497 },
498 {
499 .Opcode = RC_ME_PRED_SET_RESTORE,
500 .Name = "ME_PRED_SET_RESTORE",
501 .NumSrcRegs = 1,
502 .HasDstReg = 1
503 },
504 {
505 .Opcode = RC_VE_PRED_SEQ_PUSH,
506 .Name = "VE_PRED_SEQ_PUSH",
507 .NumSrcRegs = 2,
508 .HasDstReg = 1
509 },
510 {
511 .Opcode = RC_VE_PRED_SGT_PUSH,
512 .Name = "VE_PRED_SGT_PUSH",
513 .NumSrcRegs = 2,
514 .HasDstReg = 1
515 },
516 {
517 .Opcode = RC_VE_PRED_SGE_PUSH,
518 .Name = "VE_PRED_SGE_PUSH",
519 .NumSrcRegs = 2,
520 .HasDstReg = 1
521 },
522 {
523 .Opcode = RC_VE_PRED_SNEQ_PUSH,
524 .Name = "VE_PRED_SNEQ_PUSH",
525 .NumSrcRegs = 2,
526 .HasDstReg = 1
527 }
528 };
529
rc_compute_sources_for_writemask(const struct rc_instruction * inst,unsigned int writemask,unsigned int * srcmasks)530 void rc_compute_sources_for_writemask(
531 const struct rc_instruction *inst,
532 unsigned int writemask,
533 unsigned int *srcmasks)
534 {
535 const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
536 srcmasks[0] = 0;
537 srcmasks[1] = 0;
538 srcmasks[2] = 0;
539
540 if (opcode->Opcode == RC_OPCODE_KIL)
541 srcmasks[0] |= RC_MASK_XYZW;
542 else if (opcode->Opcode == RC_OPCODE_IF)
543 srcmasks[0] |= RC_MASK_X;
544
545 if (!writemask)
546 return;
547
548 if (opcode->IsComponentwise) {
549 for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src)
550 srcmasks[src] |= writemask;
551 } else if (opcode->IsStandardScalar) {
552 for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src)
553 srcmasks[src] |= writemask;
554 } else {
555 switch(opcode->Opcode) {
556 case RC_OPCODE_ARL:
557 case RC_OPCODE_ARR:
558 srcmasks[0] |= RC_MASK_X;
559 break;
560 case RC_OPCODE_DP2:
561 srcmasks[0] |= RC_MASK_XY;
562 srcmasks[1] |= RC_MASK_XY;
563 break;
564 case RC_OPCODE_DP3:
565 case RC_OPCODE_XPD:
566 srcmasks[0] |= RC_MASK_XYZ;
567 srcmasks[1] |= RC_MASK_XYZ;
568 break;
569 case RC_OPCODE_DP4:
570 srcmasks[0] |= RC_MASK_XYZW;
571 srcmasks[1] |= RC_MASK_XYZW;
572 break;
573 case RC_OPCODE_DPH:
574 srcmasks[0] |= RC_MASK_XYZ;
575 srcmasks[1] |= RC_MASK_XYZW;
576 break;
577 case RC_OPCODE_TXB:
578 case RC_OPCODE_TXP:
579 case RC_OPCODE_TXL:
580 srcmasks[0] |= RC_MASK_W;
581 FALLTHROUGH;
582 case RC_OPCODE_TEX:
583 switch (inst->U.I.TexSrcTarget) {
584 case RC_TEXTURE_1D:
585 srcmasks[0] |= RC_MASK_X;
586 break;
587 case RC_TEXTURE_2D:
588 case RC_TEXTURE_RECT:
589 case RC_TEXTURE_1D_ARRAY:
590 srcmasks[0] |= RC_MASK_XY;
591 break;
592 case RC_TEXTURE_3D:
593 case RC_TEXTURE_CUBE:
594 case RC_TEXTURE_2D_ARRAY:
595 srcmasks[0] |= RC_MASK_XYZ;
596 break;
597 }
598 break;
599 case RC_OPCODE_TXD:
600 switch (inst->U.I.TexSrcTarget) {
601 case RC_TEXTURE_1D_ARRAY:
602 srcmasks[0] |= RC_MASK_Y;
603 FALLTHROUGH;
604 case RC_TEXTURE_1D:
605 srcmasks[0] |= RC_MASK_X;
606 srcmasks[1] |= RC_MASK_X;
607 srcmasks[2] |= RC_MASK_X;
608 break;
609 case RC_TEXTURE_2D_ARRAY:
610 srcmasks[0] |= RC_MASK_Z;
611 FALLTHROUGH;
612 case RC_TEXTURE_2D:
613 case RC_TEXTURE_RECT:
614 srcmasks[0] |= RC_MASK_XY;
615 srcmasks[1] |= RC_MASK_XY;
616 srcmasks[2] |= RC_MASK_XY;
617 break;
618 case RC_TEXTURE_3D:
619 case RC_TEXTURE_CUBE:
620 srcmasks[0] |= RC_MASK_XYZ;
621 srcmasks[1] |= RC_MASK_XYZ;
622 srcmasks[2] |= RC_MASK_XYZ;
623 break;
624 }
625 break;
626 case RC_OPCODE_DST:
627 srcmasks[0] |= RC_MASK_Y | RC_MASK_Z;
628 srcmasks[1] |= RC_MASK_Y | RC_MASK_W;
629 break;
630 case RC_OPCODE_EXP:
631 case RC_OPCODE_LOG:
632 srcmasks[0] |= RC_MASK_XY;
633 break;
634 case RC_OPCODE_LIT:
635 srcmasks[0] |= RC_MASK_X | RC_MASK_Y | RC_MASK_W;
636 break;
637 default:
638 break;
639 }
640 }
641 }
642