nvc0: switch to the proper constants upload path
[mesa.git] / src / gallium / drivers / nvc0 / nvc0_pc_print.c
1 /*
2 * Copyright 2010 Christoph Bumiller
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23 #include "nvc0_pc.h"
24
25 #define PRINT(args...) debug_printf(args)
26
27 #ifndef ARRAY_SIZE
28 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
29 #endif
30
31 static const char *norm = "\x1b[00m";
32 static const char *gree = "\x1b[32m";
33 static const char *blue = "\x1b[34m";
34 static const char *cyan = "\x1b[36m";
35 static const char *yllw = "\x1b[33m";
36 static const char *mgta = "\x1b[35m";
37
38 static const char *nv_cond_names[] =
39 {
40 "never", "lt" , "eq" , "le" , "gt" , "ne" , "ge" , "",
41 "never", "ltu", "equ", "leu", "gtu", "neu", "geu", "",
42 "o", "c", "a", "s"
43 };
44
45 static const char *nv_modifier_strings[] =
46 {
47 "",
48 "neg",
49 "abs",
50 "neg abs",
51 "not",
52 "not neg"
53 "not abs",
54 "not neg abs",
55 "sat",
56 "BAD_MOD"
57 };
58
59 const char *
60 nvc0_opcode_name(uint opcode)
61 {
62 return nvc0_op_info_table[MIN2(opcode, NV_OP_COUNT)].name;
63 }
64
65 static INLINE const char *
66 nv_type_name(ubyte type, ubyte size)
67 {
68 switch (type) {
69 case NV_TYPE_U16: return "u16";
70 case NV_TYPE_S16: return "s16";
71 case NV_TYPE_F32: return "f32";
72 case NV_TYPE_U32: return "u32";
73 case NV_TYPE_S32: return "s32";
74 case NV_TYPE_P32: return "p32";
75 case NV_TYPE_F64: return "f64";
76 case NV_TYPE_ANY:
77 {
78 switch (size) {
79 case 1: return "b8";
80 case 2: return "b16";
81 case 4: return "b32";
82 case 8: return "b64";
83 case 12: return "b96";
84 case 16: return "b128";
85 default:
86 return "BAD_SIZE";
87 }
88 }
89 default:
90 return "BAD_TYPE";
91 }
92 }
93
94 static INLINE const char *
95 nv_cond_name(ubyte cc)
96 {
97 return nv_cond_names[MIN2(cc, 19)];
98 }
99
100 static INLINE const char *
101 nv_modifier_string(ubyte mod)
102 {
103 return nv_modifier_strings[MIN2(mod, 9)];
104 }
105
106 static INLINE int
107 nv_value_id(struct nv_value *value)
108 {
109 if (value->join->reg.id >= 0)
110 return value->join->reg.id;
111 return value->n;
112 }
113
114 static INLINE boolean
115 nv_value_allocated(struct nv_value *value)
116 {
117 return (value->reg.id >= 0) ? TRUE : FALSE;
118 }
119
120 static INLINE void
121 nv_print_address(const char c, int buf, struct nv_value *a, int offset)
122 {
123 const char ac = (a && nv_value_allocated(a)) ? '$' : '%';
124 char sg;
125
126 if (offset < 0) {
127 sg = '-';
128 offset = -offset;
129 } else {
130 sg = '+';
131 }
132
133 if (buf >= 0)
134 PRINT(" %s%c%i[", cyan, c, buf);
135 else
136 PRINT(" %s%c[", cyan, c);
137 if (a)
138 PRINT("%s%ca%i%s%c", mgta, ac, nv_value_id(a), cyan, sg);
139 PRINT("%s0x%x%s]", yllw, offset, cyan);
140 }
141
142 static INLINE void
143 nv_print_value(struct nv_value *value, struct nv_value *indir, ubyte type)
144 {
145 char reg_pfx = nv_value_allocated(value->join) ? '$' : '%';
146
147 if (value->reg.file != NV_FILE_PRED)
148 PRINT(" %s%s", gree, nv_type_name(type, value->reg.size));
149
150 switch (value->reg.file) {
151 case NV_FILE_GPR:
152 PRINT(" %s%cr%i", blue, reg_pfx, nv_value_id(value));
153 if (value->reg.size == 8)
154 PRINT("d");
155 if (value->reg.size == 16)
156 PRINT("q");
157 break;
158 case NV_FILE_PRED:
159 PRINT(" %s%cp%i", mgta, reg_pfx, nv_value_id(value));
160 break;
161 case NV_FILE_COND:
162 PRINT(" %s%cc%i", mgta, reg_pfx, nv_value_id(value));
163 break;
164 case NV_FILE_MEM_L:
165 nv_print_address('l', -1, indir, value->reg.address);
166 break;
167 case NV_FILE_MEM_G:
168 nv_print_address('g', -1, indir, value->reg.address);
169 break;
170 case NV_FILE_MEM_A:
171 nv_print_address('a', -1, indir, value->reg.address);
172 break;
173 case NV_FILE_MEM_V:
174 nv_print_address('v', -1, indir, value->reg.address);
175 break;
176 case NV_FILE_IMM:
177 switch (type) {
178 case NV_TYPE_U16:
179 case NV_TYPE_S16:
180 PRINT(" %s0x%04x", yllw, value->reg.imm.u32);
181 break;
182 case NV_TYPE_F32:
183 PRINT(" %s%f", yllw, value->reg.imm.f32);
184 break;
185 case NV_TYPE_F64:
186 PRINT(" %s%f", yllw, value->reg.imm.f64);
187 break;
188 case NV_TYPE_U32:
189 case NV_TYPE_S32:
190 case NV_TYPE_P32:
191 case NV_TYPE_ANY:
192 PRINT(" %s0x%08x", yllw, value->reg.imm.u32);
193 break;
194 }
195 break;
196 default:
197 if (value->reg.file >= NV_FILE_MEM_C(0) &&
198 value->reg.file <= NV_FILE_MEM_C(15))
199 nv_print_address('c', value->reg.file - NV_FILE_MEM_C(0), indir,
200 value->reg.address);
201 else
202 NOUVEAU_ERR(" BAD_FILE[%i]", nv_value_id(value));
203 break;
204 }
205 }
206
207 static INLINE void
208 nv_print_ref(struct nv_ref *ref, struct nv_value *indir, ubyte type)
209 {
210 nv_print_value(ref->value, indir, type);
211 }
212
213 void
214 nvc0_print_instruction(struct nv_instruction *i)
215 {
216 int s;
217
218 PRINT("%i: ", i->serial);
219
220 if (i->predicate >= 0) {
221 PRINT("%s%s", gree, i->cc ? "fl" : "tr");
222 nv_print_ref(i->src[i->predicate], NULL, NV_TYPE_U8);
223 PRINT(" ");
224 }
225
226 PRINT("%s", gree);
227 if (NV_BASEOP(i->opcode) == NV_OP_SET)
228 PRINT("set %s", nv_cond_name(i->set_cond));
229 else
230 if (i->saturate)
231 PRINT("sat %s", nvc0_opcode_name(i->opcode));
232 else
233 PRINT("%s", nvc0_opcode_name(i->opcode));
234
235 if (i->opcode == NV_OP_CVT)
236 nv_print_value(i->def[0], NULL, i->ext.cvt.d);
237 else
238 if (i->def[0])
239 nv_print_value(i->def[0], NULL, NV_OPTYPE(i->opcode));
240 else
241 if (i->target)
242 PRINT(" %s(BB:%i)", yllw, i->target->id);
243 else
244 PRINT(" #");
245
246 for (s = 1; s < 4 && i->def[s]; ++s)
247 nv_print_value(i->def[s], NULL, NV_OPTYPE(i->opcode));
248 if (s > 1)
249 PRINT("%s ,", norm);
250
251 for (s = 0; s < 6 && i->src[s]; ++s) {
252 ubyte type;
253 if (s == i->indirect || s == i->predicate)
254 continue;
255 if (i->opcode == NV_OP_CVT)
256 type = i->ext.cvt.s;
257 else
258 type = NV_OPTYPE(i->opcode);
259
260 if (i->src[s]->mod)
261 PRINT(" %s%s", gree, nv_modifier_string(i->src[s]->mod));
262
263 if (i->indirect >= 0 &&
264 NV_IS_MEMORY_FILE(i->src[s]->value->reg.file))
265 nv_print_ref(i->src[s], i->src[i->indirect]->value, type);
266 else
267 nv_print_ref(i->src[s], NULL, type);
268 }
269 PRINT(" %s\n", norm);
270 }
271
272 #define NV_MOD_SGN NV_MOD_ABS | NV_MOD_NEG
273
274 struct nv_op_info nvc0_op_info_table[NV_OP_COUNT + 1] =
275 {
276 { NV_OP_UNDEF, "undef", NV_TYPE_ANY, 0, /* fcvpoi */ 0, 0, 0, 0, 1, 0, 0 },
277 { NV_OP_BIND, "bind", NV_TYPE_ANY, 0, /* fcvpoi */ 0, 0, 1, 0, 1, 0, 0 },
278 { NV_OP_MERGE, "merge", NV_TYPE_ANY, 0, /* fcvpoi */ 0, 0, 1, 0, 1, 0, 0 },
279 { NV_OP_PHI, "phi", NV_TYPE_ANY, 0, /* fcvpoi */ 0, 0, 0, 0, 1, 0, 0 },
280 { NV_OP_SELECT, "select", NV_TYPE_ANY, 0, /* fcvpoi */ 0, 0, 0, 0, 1, 0, 0 },
281 { NV_OP_NOP, "nop", NV_TYPE_ANY, 0, /* fcvpoi */ 0, 0, 0, 0, 0, 0, 0 },
282
283 { NV_OP_LD, "ld", NV_TYPE_ANY, 0, 0, 0, 0, 0, 0, 0, 0 },
284 { NV_OP_ST, "st", NV_TYPE_ANY, 0, 0, 0, 0, 0, 0, 0, 0 },
285 { NV_OP_MOV, "mov", NV_TYPE_ANY, 0, 0, 0, 0, 1, 0, 1, 0 },
286 { NV_OP_AND, "and", NV_TYPE_U32, NV_MOD_NOT, 0, 1, 0, 1, 0, 1, 0 },
287 { NV_OP_OR, "or", NV_TYPE_U32, NV_MOD_NOT, 0, 1, 0, 1, 0, 1, 0 },
288 { NV_OP_XOR, "xor", NV_TYPE_U32, NV_MOD_NOT, 0, 1, 0, 1, 0, 1, 0 },
289 { NV_OP_SHL, "shl", NV_TYPE_U32, 0, 0, 0, 0, 1, 0, 1, 0 },
290 { NV_OP_SHR, "shr", NV_TYPE_U32, 0, 0, 0, 0, 1, 0, 1, 0 },
291 { NV_OP_NOT, "not", NV_TYPE_U32, 0, 0, 0, 0, 1, 0, 0, 0 },
292 { NV_OP_SET, "set", NV_TYPE_ANY, NV_MOD_SGN, 0, 0, 0, 1, 0, 0, 0 },
293 { NV_OP_ADD, "add", NV_TYPE_F32, NV_MOD_SGN, 0, 1, 0, 1, 0, 1, 2 },
294 { NV_OP_SUB, "sub", NV_TYPE_F32, NV_MOD_SGN, 0, 0, 0, 1, 0, 1, 2 },
295 { NV_OP_MUL, "mul", NV_TYPE_F32, NV_MOD_SGN, 0, 1, 0, 1, 0, 1, 2 },
296 { NV_OP_MAD, "mad", NV_TYPE_F32, NV_MOD_SGN, 0, 1, 0, 1, 0, 0, 2 },
297 { NV_OP_ABS, "abs", NV_TYPE_F32, 0, 0, 0, 0, 1, 0, 0, 0 },
298 { NV_OP_NEG, "neg", NV_TYPE_F32, NV_MOD_ABS, 0, 0, 0, 1, 0, 0, 0 },
299 { NV_OP_MAX, "max", NV_TYPE_F32, NV_MOD_SGN, 0, 1, 0, 1, 0, 0, 2 },
300 { NV_OP_MIN, "min", NV_TYPE_F32, NV_MOD_SGN, 0, 1, 0, 1, 0, 0, 2 },
301 { NV_OP_CVT, "cvt", NV_TYPE_ANY, NV_MOD_SGN, 0, 0, 0, 1, 0, 0, 0 },
302
303 { NV_OP_CEIL, "ceil", NV_TYPE_F32, NV_MOD_SGN, 0, 0, 0, 1, 0, 0, 0 },
304 { NV_OP_FLOOR, "floor", NV_TYPE_F32, NV_MOD_SGN, 0, 0, 0, 1, 0, 0, 0 },
305 { NV_OP_TRUNC, "floor", NV_TYPE_F32, NV_MOD_SGN, 0, 0, 0, 1, 0, 0, 0 },
306
307 { NV_OP_SAD, "sad", NV_TYPE_S32, 0, 0, 1, 0, 1, 0, 0, 0 },
308
309 { NV_OP_VFETCH, "vfetch", NV_TYPE_ANY, 0, 0, 0, 1, 1, 0, 0, 0 },
310 { NV_OP_PFETCH, "pfetch", NV_TYPE_U32, 0, 0, 0, 0, 1, 0, 0, 0 },
311 { NV_OP_EXPORT, "export", NV_TYPE_ANY, 0, 0, 0, 1, 1, 0, 0, 0 },
312 { NV_OP_LINTERP, "linterp", NV_TYPE_F32, 0, 0, 0, 0, 1, 0, 0, 0 },
313 { NV_OP_PINTERP, "pinterp", NV_TYPE_F32, 0, 0, 0, 0, 1, 0, 0, 0 },
314 { NV_OP_EMIT, "emit", NV_TYPE_ANY, 0, 0, 0, 0, 1, 0, 0, 0 },
315 { NV_OP_RESTART, "restart", NV_TYPE_ANY, 0, 0, 0, 0, 1, 0, 0, 0 },
316
317 { NV_OP_TEX, "tex", NV_TYPE_F32, 0, 0, 0, 1, 1, 0, 0, 0 },
318 { NV_OP_TXB, "texbias", NV_TYPE_F32, 0, 0, 0, 1, 1, 0, 0, 0 },
319 { NV_OP_TXL, "texlod", NV_TYPE_F32, 0, 0, 0, 1, 1, 0, 0, 0 },
320 { NV_OP_TXF, "texfetch", NV_TYPE_U32, 0, 0, 0, 1, 1, 0, 0, 0 },
321 { NV_OP_TXQ, "texquery", NV_TYPE_U32, 0, 0, 0, 1, 1, 0, 0, 0 },
322
323 { NV_OP_QUADOP, "quadop", NV_TYPE_F32, 0, 0, 0, 0, 1, 0, 0, 0 },
324 { NV_OP_DFDX, "dfdx", NV_TYPE_F32, 0, 0, 0, 0, 1, 0, 0, 0 },
325 { NV_OP_DFDY, "dfdy", NV_TYPE_F32, 0, 0, 0, 0, 1, 0, 0, 0 },
326
327 { NV_OP_KIL, "kil", NV_TYPE_ANY, 0, 0, 0, 0, 1, 0, 0, 0 },
328 { NV_OP_BRA, "bra", NV_TYPE_ANY, 0, 1, 0, 0, 1, 0, 0, 0 },
329 { NV_OP_CALL, "call", NV_TYPE_ANY, 0, 1, 0, 0, 1, 0, 0, 0 },
330 { NV_OP_RET, "ret", NV_TYPE_ANY, 0, 1, 0, 0, 1, 0, 0, 0 },
331 { NV_OP_RET, "exit", NV_TYPE_ANY, 0, 1, 0, 0, 1, 0, 0, 0 },
332 { NV_OP_NOP, "ud", NV_TYPE_ANY, 0, 1, 0, 0, 1, 0, 0, 0 },
333 { NV_OP_NOP, "ud", NV_TYPE_ANY, 0, 1, 0, 0, 1, 0, 0, 0 },
334
335 { NV_OP_JOINAT, "joinat", NV_TYPE_ANY, 0, 1, 0, 0, 1, 0, 0, 0 },
336 { NV_OP_JOIN, "join", NV_TYPE_ANY, 0, 1, 0, 0, 1, 0, 0, 0 },
337
338 { NV_OP_ADD, "add", NV_TYPE_S32, 0, 0, 1, 0, 1, 0, 1, 0 },
339 { NV_OP_MUL, "mul", NV_TYPE_S32, 0, 0, 1, 0, 1, 0, 1, 0 },
340 { NV_OP_ABS, "abs", NV_TYPE_S32, 0, 0, 0, 0, 1, 0, 0, 0 },
341 { NV_OP_NEG, "neg", NV_TYPE_S32, 0, 0, 0, 0, 1, 0, 0, 0 },
342 { NV_OP_MAX, "max", NV_TYPE_S32, 0, 0, 1, 0, 1, 0, 0, 0 },
343 { NV_OP_MIN, "max", NV_TYPE_U32, 0, 0, 1, 0, 1, 0, 0, 0 },
344 { NV_OP_MAX, "min", NV_TYPE_S32, 0, 0, 1, 0, 1, 0, 0, 0 },
345 { NV_OP_MIN, "min", NV_TYPE_U32, 0, 0, 1, 0, 1, 0, 0, 0 },
346 { NV_OP_SET, "set", NV_TYPE_F32, NV_MOD_SGN, 0, 0, 0, 1, 0, 0, 2 },
347 { NV_OP_SET, "set", NV_TYPE_S32, 0, 0, 0, 0, 1, 0, 0, 0 },
348 { NV_OP_SET, "set", NV_TYPE_U32, 0, 0, 0, 0, 1, 0, 0, 0 },
349 { NV_OP_SHR, "sar", NV_TYPE_S32, 0, 0, 0, 0, 1, 0, 1, 0 },
350 { NV_OP_RCP, "rcp", NV_TYPE_F32, NV_MOD_SGN, 0, 0, 0, 0, 0, 0, 0 },
351 { NV_OP_RSQ, "rsqrt", NV_TYPE_F32, NV_MOD_SGN, 0, 0, 0, 0, 0, 0, 0 },
352 { NV_OP_LG2, "lg2", NV_TYPE_F32, NV_MOD_SGN, 0, 0, 0, 0, 0, 0, 0 },
353 { NV_OP_SIN, "sin", NV_TYPE_F32, 0, 0, 0, 0, 0, 0, 0, 0 },
354 { NV_OP_COS, "cos", NV_TYPE_F32, 0, 0, 0, 0, 0, 0, 0, 0 },
355 { NV_OP_EX2, "ex2", NV_TYPE_F32, 0, 0, 0, 0, 0, 0, 0, 0 },
356 { NV_OP_PRESIN, "presin", NV_TYPE_F32, NV_MOD_SGN, 0, 0, 0, 0, 0, 0, 0 },
357 { NV_OP_PREEX2, "preex2", NV_TYPE_F32, NV_MOD_SGN, 0, 0, 0, 0, 0, 0, 0 },
358 { NV_OP_SAT, "sat", NV_TYPE_F32, 0, 0, 0, 0, 1, 0, 0, 0 },
359
360 { NV_OP_SET_F32_AND, "and set", NV_TYPE_F32, 0, 0, 0, 0, 1, 0, 0, 0 },
361 { NV_OP_SET_F32_OR, "or set", NV_TYPE_F32, 0, 0, 0, 0, 1, 0, 0, 0 },
362 { NV_OP_SET_F32_XOR, "xor set", NV_TYPE_F32, 0, 0, 0, 0, 1, 0, 0, 0 },
363
364 { NV_OP_SELP, "selp", NV_TYPE_U32, 0, 0, 0, 0, 1, 0, 0, 0 },
365
366 { NV_OP_SLCT_F32, "slct", NV_TYPE_F32, 0, 0, 0, 0, 1, 0, 0, 0 },
367 { NV_OP_SLCT_F32, "slct", NV_TYPE_S32, 0, 0, 0, 0, 1, 0, 0, 0 },
368 { NV_OP_SLCT_F32, "slct", NV_TYPE_U32, 0, 0, 0, 0, 1, 0, 0, 0 },
369
370 { NV_OP_ADD, "sub", NV_TYPE_F32, 0, 0, 0, 0, 1, 0, 1, 0 },
371
372 { NV_OP_FSET_F32, "fset", NV_TYPE_F32, NV_MOD_SGN, 0, 0, 0, 1, 0, 0, 2 },
373
374 { NV_OP_UNDEF, "BAD_OP", NV_TYPE_ANY, 0, 0, 0, 0, 0, 0, 0, 0 }
375 };