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