Move compiler.h and imports.h/c from src/mesa/main into src/util
[mesa.git] / src / mesa / drivers / dri / i915 / i915_debug_fp.c
1 /**************************************************************************
2 *
3 * Copyright 2003 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * 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, sub license, 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 portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include <stdio.h>
29
30 #include "i915_reg.h"
31 #include "i915_debug.h"
32 #include "util/imports.h"
33 #include "main/glheader.h"
34
35 static const char *opcodes[0x20] = {
36 "NOP",
37 "ADD",
38 "MOV",
39 "MUL",
40 "MAD",
41 "DP2ADD",
42 "DP3",
43 "DP4",
44 "FRC",
45 "RCP",
46 "RSQ",
47 "EXP",
48 "LOG",
49 "CMP",
50 "MIN",
51 "MAX",
52 "FLR",
53 "MOD",
54 "TRC",
55 "SGE",
56 "SLT",
57 "TEXLD",
58 "TEXLDP",
59 "TEXLDB",
60 "TEXKILL",
61 "DCL",
62 "0x1a",
63 "0x1b",
64 "0x1c",
65 "0x1d",
66 "0x1e",
67 "0x1f",
68 };
69
70
71 static const int args[0x20] = {
72 0, /* 0 nop */
73 2, /* 1 add */
74 1, /* 2 mov */
75 2, /* 3 m ul */
76 3, /* 4 mad */
77 3, /* 5 dp2add */
78 2, /* 6 dp3 */
79 2, /* 7 dp4 */
80 1, /* 8 frc */
81 1, /* 9 rcp */
82 1, /* a rsq */
83 1, /* b exp */
84 1, /* c log */
85 3, /* d cmp */
86 2, /* e min */
87 2, /* f max */
88 1, /* 10 flr */
89 1, /* 11 mod */
90 1, /* 12 trc */
91 2, /* 13 sge */
92 2, /* 14 slt */
93 1,
94 1,
95 1,
96 1,
97 0,
98 0,
99 0,
100 0,
101 0,
102 0,
103 0,
104 };
105
106
107 static const char *regname[0x8] = {
108 "R",
109 "T",
110 "CONST",
111 "S",
112 "OC",
113 "OD",
114 "U",
115 "UNKNOWN",
116 };
117
118 static void
119 print_reg_type_nr(GLuint type, GLuint nr)
120 {
121 switch (type) {
122 case REG_TYPE_T:
123 switch (nr) {
124 case T_DIFFUSE:
125 printf("T_DIFFUSE");
126 return;
127 case T_SPECULAR:
128 printf("T_SPECULAR");
129 return;
130 case T_FOG_W:
131 printf("T_FOG_W");
132 return;
133 default:
134 printf("T_TEX%d", nr);
135 return;
136 }
137 case REG_TYPE_OC:
138 if (nr == 0) {
139 printf("oC");
140 return;
141 }
142 break;
143 case REG_TYPE_OD:
144 if (nr == 0) {
145 printf("oD");
146 return;
147 }
148 break;
149 default:
150 break;
151 }
152
153 printf("%s[%d]", regname[type], nr);
154 }
155
156 #define REG_SWIZZLE_MASK 0x7777
157 #define REG_NEGATE_MASK 0x8888
158
159 #define REG_SWIZZLE_XYZW ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) | \
160 (SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) | \
161 (SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) | \
162 (SRC_W << A2_SRC2_CHANNEL_W_SHIFT))
163
164
165 static void
166 print_reg_neg_swizzle(GLuint reg)
167 {
168 int i;
169
170 if ((reg & REG_SWIZZLE_MASK) == REG_SWIZZLE_XYZW &&
171 (reg & REG_NEGATE_MASK) == 0)
172 return;
173
174 printf(".");
175
176 for (i = 3; i >= 0; i--) {
177 if (reg & (1 << ((i * 4) + 3)))
178 printf("-");
179
180 switch ((reg >> (i * 4)) & 0x7) {
181 case 0:
182 printf("x");
183 break;
184 case 1:
185 printf("y");
186 break;
187 case 2:
188 printf("z");
189 break;
190 case 3:
191 printf("w");
192 break;
193 case 4:
194 printf("0");
195 break;
196 case 5:
197 printf("1");
198 break;
199 default:
200 printf("?");
201 break;
202 }
203 }
204 }
205
206
207 static void
208 print_src_reg(GLuint dword)
209 {
210 GLuint nr = (dword >> A2_SRC2_NR_SHIFT) & REG_NR_MASK;
211 GLuint type = (dword >> A2_SRC2_TYPE_SHIFT) & REG_TYPE_MASK;
212 print_reg_type_nr(type, nr);
213 print_reg_neg_swizzle(dword);
214 }
215
216
217 static void
218 print_dest_reg(GLuint dword)
219 {
220 GLuint nr = (dword >> A0_DEST_NR_SHIFT) & REG_NR_MASK;
221 GLuint type = (dword >> A0_DEST_TYPE_SHIFT) & REG_TYPE_MASK;
222 print_reg_type_nr(type, nr);
223 if ((dword & A0_DEST_CHANNEL_ALL) == A0_DEST_CHANNEL_ALL)
224 return;
225 printf(".");
226 if (dword & A0_DEST_CHANNEL_X)
227 printf("x");
228 if (dword & A0_DEST_CHANNEL_Y)
229 printf("y");
230 if (dword & A0_DEST_CHANNEL_Z)
231 printf("z");
232 if (dword & A0_DEST_CHANNEL_W)
233 printf("w");
234 }
235
236
237 #define GET_SRC0_REG(r0, r1) ((r0<<14)|(r1>>A1_SRC0_CHANNEL_W_SHIFT))
238 #define GET_SRC1_REG(r0, r1) ((r0<<8)|(r1>>A2_SRC1_CHANNEL_W_SHIFT))
239 #define GET_SRC2_REG(r) (r)
240
241
242 static void
243 print_arith_op(GLuint opcode, const GLuint * program)
244 {
245 if (opcode != A0_NOP) {
246 print_dest_reg(program[0]);
247 if (program[0] & A0_DEST_SATURATE)
248 printf(" = SATURATE ");
249 else
250 printf(" = ");
251 }
252
253 printf("%s ", opcodes[opcode]);
254
255 print_src_reg(GET_SRC0_REG(program[0], program[1]));
256 if (args[opcode] == 1) {
257 printf("\n");
258 return;
259 }
260
261 printf(", ");
262 print_src_reg(GET_SRC1_REG(program[1], program[2]));
263 if (args[opcode] == 2) {
264 printf("\n");
265 return;
266 }
267
268 printf(", ");
269 print_src_reg(GET_SRC2_REG(program[2]));
270 printf("\n");
271 return;
272 }
273
274
275 static void
276 print_tex_op(GLuint opcode, const GLuint * program)
277 {
278 print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL);
279 printf(" = ");
280
281 printf("%s ", opcodes[opcode]);
282
283 printf("S[%d],", program[0] & T0_SAMPLER_NR_MASK);
284
285 print_reg_type_nr((program[1] >> T1_ADDRESS_REG_TYPE_SHIFT) &
286 REG_TYPE_MASK,
287 (program[1] >> T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK);
288 printf("\n");
289 }
290
291 static void
292 print_dcl_op(GLuint opcode, const GLuint * program)
293 {
294 printf("%s ", opcodes[opcode]);
295 print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL);
296 printf("\n");
297 }
298
299
300 void
301 i915_disassemble_program(const GLuint * program, GLuint sz)
302 {
303 GLint i;
304
305 printf("\t\tBEGIN\n");
306
307 assert((program[0] & 0x1ff) + 2 == sz);
308
309 program++;
310 for (i = 1; i < sz; i += 3, program += 3) {
311 GLuint opcode = program[0] & (0x1f << 24);
312
313 printf("\t\t");
314
315 if ((GLint) opcode >= A0_NOP && opcode <= A0_SLT)
316 print_arith_op(opcode >> 24, program);
317 else if (opcode >= T0_TEXLD && opcode <= T0_TEXKILL)
318 print_tex_op(opcode >> 24, program);
319 else if (opcode == D0_DCL)
320 print_dcl_op(opcode >> 24, program);
321 else
322 printf("Unknown opcode 0x%x\n", opcode);
323 }
324
325 printf("\t\tEND\n\n");
326 }
327
328