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