1 /*
2  * Copyright (C) 2005 Ben Skeggs.
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 "r300_fragprog.h"
29 
30 #include <stdio.h>
31 
32 #include "../r300_reg.h"
33 
presub_string(char out[10],unsigned int inst)34 static void presub_string(char out[10], unsigned int inst)
35 {
36 	switch(inst & 0x600000){
37 	case R300_ALU_SRCP_1_MINUS_2_SRC0:
38 		sprintf(out, "bias");
39 		break;
40 	case R300_ALU_SRCP_SRC1_MINUS_SRC0:
41 		sprintf(out, "sub");
42 		break;
43 	case R300_ALU_SRCP_SRC1_PLUS_SRC0:
44 		sprintf(out, "add");
45 		break;
46 	case R300_ALU_SRCP_1_MINUS_SRC0:
47 		sprintf(out, "inv ");
48 		break;
49 	}
50 }
51 
get_msb(unsigned int bit,unsigned int r400_ext_addr)52 static int get_msb(unsigned int bit, unsigned int r400_ext_addr)
53 {
54 	return (r400_ext_addr & bit) ? 1 << 5 : 0;
55 }
56 
57 /* just some random things... */
r300FragmentProgramDump(struct radeon_compiler * c,void * user)58 void r300FragmentProgramDump(struct radeon_compiler *c, void *user)
59 {
60 	struct r300_fragment_program_compiler *compiler = (struct r300_fragment_program_compiler*)c;
61 	struct r300_fragment_program_code *code = &compiler->code->code.r300;
62 	int n, i, j;
63 	static int pc = 0;
64 
65 	fprintf(stderr, "pc=%d*************************************\n", pc++);
66 
67 	fprintf(stderr, "Hardware program\n");
68 	fprintf(stderr, "----------------\n");
69 	if (c->is_r400) {
70 		fprintf(stderr, "code_offset_ext: %08x\n", code->r400_code_offset_ext);
71 	}
72 
73 	for (n = 0; n <= (code->config & 3); n++) {
74 		uint32_t code_addr = code->code_addr[3 - (code->config & 3) + n];
75 		unsigned int alu_offset = ((code_addr & R300_ALU_START_MASK) >> R300_ALU_START_SHIFT) +
76 				(((code->r400_code_offset_ext >> (24 - (n * 6))) & 0x7) << 6);
77 		unsigned int alu_end = ((code_addr & R300_ALU_SIZE_MASK) >> R300_ALU_SIZE_SHIFT) +
78 				(((code->r400_code_offset_ext >> (27 - (n * 6))) & 0x7) << 6);
79 		int tex_offset = (code_addr & R300_TEX_START_MASK) >> R300_TEX_START_SHIFT;
80 		int tex_end = (code_addr & R300_TEX_SIZE_MASK) >> R300_TEX_SIZE_SHIFT;
81 
82 		fprintf(stderr, "NODE %d: alu_offset: %u, tex_offset: %d, "
83 			"alu_end: %u, tex_end: %d  (code_addr: %08x)\n", n,
84 			alu_offset, tex_offset, alu_end, tex_end, code_addr);
85 
86 		if (n > 0 || (code->config & R300_PFS_CNTL_FIRST_NODE_HAS_TEX)) {
87 			fprintf(stderr, "  TEX:\n");
88 			for (i = tex_offset;
89 			     i <= tex_offset + tex_end;
90 			     ++i) {
91 				const char *instr;
92 
93 				switch ((code->tex.
94 					 inst[i] >> R300_TEX_INST_SHIFT) &
95 					15) {
96 				case R300_TEX_OP_LD:
97 					instr = "TEX";
98 					break;
99 				case R300_TEX_OP_KIL:
100 					instr = "KIL";
101 					break;
102 				case R300_TEX_OP_TXP:
103 					instr = "TXP";
104 					break;
105 				case R300_TEX_OP_TXB:
106 					instr = "TXB";
107 					break;
108 				default:
109 					instr = "UNKNOWN";
110 				}
111 
112 				fprintf(stderr,
113 					"    %s t%i, %c%i, texture[%i]   (%08x)\n",
114 					instr,
115 					(code->tex.
116 					 inst[i] >> R300_DST_ADDR_SHIFT) & 31,
117 					't',
118 					(code->tex.
119 					 inst[i] >> R300_SRC_ADDR_SHIFT) & 31,
120 					(code->tex.
121 					 inst[i] & R300_TEX_ID_MASK) >>
122 					R300_TEX_ID_SHIFT,
123 					code->tex.inst[i]);
124 			}
125 		}
126 
127 		for (i = alu_offset;
128 		     i <= alu_offset + alu_end; ++i) {
129 			char srcc[4][10], dstc[20];
130 			char srca[4][10], dsta[20];
131 			char argc[3][20];
132 			char arga[3][20];
133 			char flags[5], tmp[10];
134 
135 			for (j = 0; j < 3; ++j) {
136 				int regc = code->alu.inst[i].rgb_addr >> (j * 6);
137 				int rega = code->alu.inst[i].alpha_addr >> (j * 6);
138 				int msbc = get_msb(R400_ADDR_EXT_RGB_MSB_BIT(j),
139 					code->alu.inst[i].r400_ext_addr);
140 				int msba = get_msb(R400_ADDR_EXT_A_MSB_BIT(j),
141 					code->alu.inst[i].r400_ext_addr);
142 
143 				sprintf(srcc[j], "%c%i",
144 					(regc & 32) ? 'c' : 't', (regc & 31) | msbc);
145 				sprintf(srca[j], "%c%i",
146 					(rega & 32) ? 'c' : 't', (rega & 31) | msba);
147 			}
148 
149 			dstc[0] = 0;
150 			sprintf(flags, "%s%s%s",
151 				(code->alu.inst[i].
152 				 rgb_addr & R300_ALU_DSTC_REG_X) ? "x" : "",
153 				(code->alu.inst[i].
154 				 rgb_addr & R300_ALU_DSTC_REG_Y) ? "y" : "",
155 				(code->alu.inst[i].
156 				 rgb_addr & R300_ALU_DSTC_REG_Z) ? "z" : "");
157 			if (flags[0] != 0) {
158 				unsigned int msb = get_msb(
159 					R400_ADDRD_EXT_RGB_MSB_BIT,
160 					code->alu.inst[i].r400_ext_addr);
161 
162 				sprintf(dstc, "t%i.%s ",
163 					((code->alu.inst[i].
164 					 rgb_addr >> R300_ALU_DSTC_SHIFT)
165 					 & 31) | msb,
166 					flags);
167 			}
168 			sprintf(flags, "%s%s%s",
169 				(code->alu.inst[i].
170 				 rgb_addr & R300_ALU_DSTC_OUTPUT_X) ? "x" : "",
171 				(code->alu.inst[i].
172 				 rgb_addr & R300_ALU_DSTC_OUTPUT_Y) ? "y" : "",
173 				(code->alu.inst[i].
174 				 rgb_addr & R300_ALU_DSTC_OUTPUT_Z) ? "z" : "");
175 			if (flags[0] != 0) {
176 				sprintf(tmp, "o%i.%s",
177 					(code->alu.inst[i].
178 					 rgb_addr >> 29) & 3,
179 					flags);
180 				strcat(dstc, tmp);
181 			}
182 			/* Presub */
183 			presub_string(srcc[3], code->alu.inst[i].rgb_inst);
184 			presub_string(srca[3], code->alu.inst[i].alpha_inst);
185 
186 			dsta[0] = 0;
187 			if (code->alu.inst[i].alpha_addr & R300_ALU_DSTA_REG) {
188 				unsigned int msb = get_msb(
189 					R400_ADDRD_EXT_A_MSB_BIT,
190 					code->alu.inst[i].r400_ext_addr);
191 				sprintf(dsta, "t%i.w ",
192 					((code->alu.inst[i].
193 					 alpha_addr >> R300_ALU_DSTA_SHIFT) & 31)
194 					 | msb);
195 			}
196 			if (code->alu.inst[i].alpha_addr & R300_ALU_DSTA_OUTPUT) {
197 				sprintf(tmp, "o%i.w ",
198 					(code->alu.inst[i].
199 					 alpha_addr >> 25) & 3);
200 				strcat(dsta, tmp);
201 			}
202 			if (code->alu.inst[i].alpha_addr & R300_ALU_DSTA_DEPTH) {
203 				strcat(dsta, "Z");
204 			}
205 
206 			fprintf(stderr,
207 				"%3i: xyz: %3s %3s %3s %5s-> %-20s (%08x)\n"
208 				"       w: %3s %3s %3s %5s-> %-20s (%08x)\n", i,
209 				srcc[0], srcc[1], srcc[2], srcc[3], dstc,
210 				code->alu.inst[i].rgb_addr, srca[0], srca[1],
211 				srca[2], srca[3], dsta,
212 				code->alu.inst[i].alpha_addr);
213 
214 			for (j = 0; j < 3; ++j) {
215 				int regc = code->alu.inst[i].rgb_inst >> (j * 7);
216 				int rega = code->alu.inst[i].alpha_inst >> (j * 7);
217 				int d;
218 				char buf[20];
219 
220 				d = regc & 31;
221 				if (d < 12) {
222 					switch (d % 4) {
223 					case R300_ALU_ARGC_SRC0C_XYZ:
224 						sprintf(buf, "%s.xyz",
225 							srcc[d / 4]);
226 						break;
227 					case R300_ALU_ARGC_SRC0C_XXX:
228 						sprintf(buf, "%s.xxx",
229 							srcc[d / 4]);
230 						break;
231 					case R300_ALU_ARGC_SRC0C_YYY:
232 						sprintf(buf, "%s.yyy",
233 							srcc[d / 4]);
234 						break;
235 					case R300_ALU_ARGC_SRC0C_ZZZ:
236 						sprintf(buf, "%s.zzz",
237 							srcc[d / 4]);
238 						break;
239 					}
240 				} else if (d < 15) {
241 					sprintf(buf, "%s.www", srca[d - 12]);
242 				} else if (d < 20 ) {
243 					switch(d) {
244 					case R300_ALU_ARGC_SRCP_XYZ:
245 						sprintf(buf, "srcp.xyz");
246 						break;
247 					case R300_ALU_ARGC_SRCP_XXX:
248 						sprintf(buf, "srcp.xxx");
249 						break;
250 					case R300_ALU_ARGC_SRCP_YYY:
251 						sprintf(buf, "srcp.yyy");
252 						break;
253 					case R300_ALU_ARGC_SRCP_ZZZ:
254 						sprintf(buf, "srcp.zzz");
255 						break;
256 					case R300_ALU_ARGC_SRCP_WWW:
257 						sprintf(buf, "srcp.www");
258 						break;
259 					}
260 				} else if (d == 20) {
261 					sprintf(buf, "0.0");
262 				} else if (d == 21) {
263 					sprintf(buf, "1.0");
264 				} else if (d == 22) {
265 					sprintf(buf, "0.5");
266 				} else if (d >= 23 && d < 32) {
267 					d -= 23;
268 					switch (d / 3) {
269 					case 0:
270 						sprintf(buf, "%s.yzx",
271 							srcc[d % 3]);
272 						break;
273 					case 1:
274 						sprintf(buf, "%s.zxy",
275 							srcc[d % 3]);
276 						break;
277 					case 2:
278 						sprintf(buf, "%s.Wzy",
279 							srcc[d % 3]);
280 						break;
281 					}
282 				} else {
283 					sprintf(buf, "%i", d);
284 				}
285 
286 				sprintf(argc[j], "%s%s%s%s",
287 					(regc & 32) ? "-" : "",
288 					(regc & 64) ? "|" : "",
289 					buf, (regc & 64) ? "|" : "");
290 
291 				d = rega & 31;
292 				if (d < 9) {
293 					sprintf(buf, "%s.%c", srcc[d / 3],
294 						'x' + (char)(d % 3));
295 				} else if (d < 12) {
296 					sprintf(buf, "%s.w", srca[d - 9]);
297 				} else if (d < 16) {
298 					switch(d) {
299 					case R300_ALU_ARGA_SRCP_X:
300 						sprintf(buf, "srcp.x");
301 						break;
302 					case R300_ALU_ARGA_SRCP_Y:
303 						sprintf(buf, "srcp.y");
304 						break;
305 					case R300_ALU_ARGA_SRCP_Z:
306 						sprintf(buf, "srcp.z");
307 						break;
308 					case R300_ALU_ARGA_SRCP_W:
309 						sprintf(buf, "srcp.w");
310 						break;
311 					}
312 				} else if (d == 16) {
313 					sprintf(buf, "0.0");
314 				} else if (d == 17) {
315 					sprintf(buf, "1.0");
316 				} else if (d == 18) {
317 					sprintf(buf, "0.5");
318 				} else {
319 					sprintf(buf, "%i", d);
320 				}
321 
322 				sprintf(arga[j], "%s%s%s%s",
323 					(rega & 32) ? "-" : "",
324 					(rega & 64) ? "|" : "",
325 					buf, (rega & 64) ? "|" : "");
326 			}
327 
328 			fprintf(stderr, "     xyz: %8s %8s %8s    op: %08x %s\n"
329 				"       w: %8s %8s %8s    op: %08x\n",
330 				argc[0], argc[1], argc[2],
331 				code->alu.inst[i].rgb_inst,
332 				code->alu.inst[i].rgb_inst & R300_ALU_INSERT_NOP ?
333 				"NOP" : "",
334 				arga[0], arga[1],arga[2],
335 				code->alu.inst[i].alpha_inst);
336 		}
337 	}
338 }
339