2 * Copyright 2010 Christoph Bumiller
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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
23 #include "nv50_context.h"
28 #define PRINT(args...) debug_printf(args)
31 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
34 static const char *norm = "\x1b[00m";
35 static const char *gree = "\x1b[32m";
36 static const char *blue = "\x1b[34m";
37 static const char *cyan = "\x1b[36m";
38 static const char *orng = "\x1b[33m";
39 static const char *mgta = "\x1b[35m";
41 static const char *nv_opcode_names[NV_OP_COUNT + 1] = {
102 static const char *nv_cond_names[] =
104 "never", "lt" , "eq" , "le" , "gt" , "ne" , "ge" , "",
105 "never", "ltu", "equ", "leu", "gtu", "neu", "geu", "",
109 static const char *nv_modifier_strings[] =
124 nv_opcode_name(uint opcode)
126 return nv_opcode_names[MIN2(opcode, ARRAY_SIZE(nv_opcode_names) - 1)];
129 static INLINE const char *
130 nv_type_name(ubyte type)
133 case NV_TYPE_U16: return "u16";
134 case NV_TYPE_S16: return "s16";
135 case NV_TYPE_F32: return "f32";
136 case NV_TYPE_U32: return "u32";
137 case NV_TYPE_S32: return "s32";
138 case NV_TYPE_P32: return "p32";
139 case NV_TYPE_F64: return "f64";
145 static INLINE const char *
146 nv_cond_name(ubyte cc)
148 return nv_cond_names[MIN2(cc, 19)];
151 static INLINE const char *
152 nv_modifier_string(ubyte mod)
154 return nv_modifier_strings[MIN2(mod, 9)];
158 nv_value_id(struct nv_value *value)
160 if (value->join->reg.id >= 0)
161 return value->join->reg.id;
165 static INLINE boolean
166 nv_value_allocated(struct nv_value *value)
168 return (value->reg.id >= 0) ? TRUE : FALSE;
172 nv_print_address(const char c, int buf, struct nv_value *a, int offset)
174 const char ac = (a && nv_value_allocated(a)) ? '$' : '%';
177 PRINT(" %s%c%i[", cyan, c, buf);
179 PRINT(" %s%c[", cyan, c);
181 PRINT("%s%ca%i%s+", mgta, ac, nv_value_id(a), cyan);
182 PRINT("%s0x%x%s]", orng, offset, cyan);
186 nv_print_cond(struct nv_instruction *nvi)
188 char pfx = nv_value_allocated(nvi->flags_src->value->join) ? '$' : '%';
190 PRINT("%s%s %s%cc%i ",
191 gree, nv_cond_name(nvi->cc),
192 mgta, pfx, nv_value_id(nvi->flags_src->value));
196 nv_print_value(struct nv_value *value, struct nv_value *ind, ubyte type)
200 if (type == NV_TYPE_ANY)
201 type = value->reg.type;
203 if (value->reg.file != NV_FILE_FLAGS)
204 PRINT(" %s%s", gree, nv_type_name(type));
206 if (!nv_value_allocated(value->join))
209 switch (value->reg.file) {
211 PRINT(" %s%cr%i", blue, reg_pfx, nv_value_id(value));
214 PRINT(" %s%co%i", mgta, reg_pfx, nv_value_id(value));
217 PRINT(" %s%ca%i", mgta, reg_pfx, nv_value_id(value));
220 PRINT(" %s%cc%i", mgta, reg_pfx, nv_value_id(value));
223 nv_print_address('l', -1, ind, nv_value_id(value));
226 nv_print_address('s', -1, ind, 4 * nv_value_id(value));
229 nv_print_address('p', -1, ind, 4 * nv_value_id(value));
232 nv_print_address('v', -1, ind, 4 * nv_value_id(value));
238 PRINT(" %s0x%04x", orng, value->reg.imm.u32);
241 PRINT(" %s%f", orng, value->reg.imm.f32);
244 PRINT(" %s%f", orng, value->reg.imm.f64);
249 PRINT(" %s0x%08x", orng, value->reg.imm.u32);
254 if (value->reg.file >= NV_FILE_MEM_G(0) &&
255 value->reg.file <= NV_FILE_MEM_G(15))
256 nv_print_address('g', value->reg.file - NV_FILE_MEM_G(0), ind,
257 nv_value_id(value) * 4);
259 if (value->reg.file >= NV_FILE_MEM_C(0) &&
260 value->reg.file <= NV_FILE_MEM_C(15))
261 nv_print_address('c', value->reg.file - NV_FILE_MEM_C(0), ind,
262 nv_value_id(value) * 4);
264 NOUVEAU_ERR(" BAD_FILE[%i]", nv_value_id(value));
270 nv_print_ref(struct nv_ref *ref, struct nv_value *ind)
272 nv_print_value(ref->value, ind, ref->typecast);
276 nv_print_instruction(struct nv_instruction *i)
280 PRINT("%i: ", i->serial);
286 if (i->opcode == NV_OP_SET)
287 PRINT("set %s", nv_cond_name(i->set_cond));
290 PRINT("sat %s", nv_opcode_name(i->opcode));
292 PRINT("%s", nv_opcode_name(i->opcode));
295 nv_print_value(i->flags_def, NULL, NV_TYPE_ANY);
297 /* Only STORE & STA can write to MEM, and they do not def
298 * anything, so the address is thus part of the source.
301 nv_print_value(i->def[0], NULL, NV_TYPE_ANY);
304 PRINT(" %s(BB:%i)", orng, i->target->id);
308 for (j = 0; j < 4; ++j) {
313 PRINT(" %s%s", gree, nv_modifier_string(i->src[j]->mod));
315 nv_print_ref(i->src[j],
316 (j == nv50_indirect_opnd(i)) ?
317 i->src[4]->value : NULL);
319 PRINT(" %s%c\n", norm, i->is_long ? 'l' : 's');