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