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