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