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