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