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