128745a575977afc2d8c55d6bad3bf9d3bdd439f
[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_CONTINUE,
390 .Name = "CONTINUE",
391 .IsFlowControl = 1,
392 .NumSrcRegs = 0
393 },
394 {
395 .Opcode = RC_OPCODE_REPL_ALPHA,
396 .Name = "REPL_ALPHA",
397 .HasDstReg = 1
398 },
399 {
400 .Opcode = RC_OPCODE_BEGIN_TEX,
401 .Name = "BEGIN_TEX"
402 }
403 };
404
405 void rc_compute_sources_for_writemask(
406 const struct rc_instruction *inst,
407 unsigned int writemask,
408 unsigned int *srcmasks)
409 {
410 const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
411 srcmasks[0] = 0;
412 srcmasks[1] = 0;
413 srcmasks[2] = 0;
414
415 if (opcode->Opcode == RC_OPCODE_KIL)
416 srcmasks[0] |= RC_MASK_XYZW;
417 else if (opcode->Opcode == RC_OPCODE_IF)
418 srcmasks[0] |= RC_MASK_X;
419
420 if (!writemask)
421 return;
422
423 if (opcode->IsComponentwise) {
424 for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src)
425 srcmasks[src] |= writemask;
426 } else if (opcode->IsStandardScalar) {
427 for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src)
428 srcmasks[src] |= RC_MASK_X;
429 } else {
430 switch(opcode->Opcode) {
431 case RC_OPCODE_ARL:
432 srcmasks[0] |= RC_MASK_X;
433 break;
434 case RC_OPCODE_DP3:
435 srcmasks[0] |= RC_MASK_XYZ;
436 srcmasks[1] |= RC_MASK_XYZ;
437 break;
438 case RC_OPCODE_DP4:
439 srcmasks[0] |= RC_MASK_XYZW;
440 srcmasks[1] |= RC_MASK_XYZW;
441 break;
442 case RC_OPCODE_TXB:
443 case RC_OPCODE_TXP:
444 srcmasks[0] |= RC_MASK_W;
445 /* Fall through */
446 case RC_OPCODE_TEX:
447 switch (inst->U.I.TexSrcTarget) {
448 case RC_TEXTURE_1D:
449 srcmasks[0] |= RC_MASK_X;
450 break;
451 case RC_TEXTURE_2D:
452 case RC_TEXTURE_RECT:
453 case RC_TEXTURE_1D_ARRAY:
454 srcmasks[0] |= RC_MASK_XY;
455 break;
456 case RC_TEXTURE_3D:
457 case RC_TEXTURE_CUBE:
458 case RC_TEXTURE_2D_ARRAY:
459 srcmasks[0] |= RC_MASK_XYZ;
460 break;
461 }
462 break;
463 case RC_OPCODE_DST:
464 srcmasks[0] |= RC_MASK_Y | RC_MASK_Z;
465 srcmasks[1] |= RC_MASK_Y | RC_MASK_W;
466 break;
467 case RC_OPCODE_EXP:
468 case RC_OPCODE_LOG:
469 srcmasks[0] |= RC_MASK_XY;
470 break;
471 case RC_OPCODE_LIT:
472 srcmasks[0] |= RC_MASK_X | RC_MASK_Y | RC_MASK_W;
473 break;
474 default:
475 break;
476 }
477 }
478 }