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