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