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