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] = {
101 static const char *nv_cond_names
[] =
103 "never", "lt" , "eq" , "le" , "gt" , "ne" , "ge" , "",
104 "never", "ltu", "equ", "leu", "gtu", "neu", "geu", ""
107 static const char *nv_modifier_strings
[] =
122 nv_opcode_name(uint opcode
)
124 return nv_opcode_names
[MIN2(opcode
, ARRAY_SIZE(nv_opcode_names
) - 1)];
127 static INLINE
const char *
128 nv_type_name(ubyte type
)
131 case NV_TYPE_U16
: return "u16";
132 case NV_TYPE_S16
: return "s16";
133 case NV_TYPE_F32
: return "f32";
134 case NV_TYPE_U32
: return "u32";
135 case NV_TYPE_S32
: return "s32";
136 case NV_TYPE_P32
: return "p32";
137 case NV_TYPE_F64
: return "f64";
143 static INLINE
const char *
144 nv_cond_name(ubyte cc
)
146 return nv_cond_names
[MIN2(cc
, 15)];
149 static INLINE
const char *
150 nv_modifier_string(ubyte mod
)
152 return nv_modifier_strings
[MIN2(mod
, 9)];
156 nv_value_id(struct nv_value
*value
)
158 if (value
->join
->reg
.id
>= 0)
159 return value
->join
->reg
.id
;
163 static INLINE boolean
164 nv_value_allocated(struct nv_value
*value
)
166 return (value
->reg
.id
>= 0) ? TRUE
: FALSE
;
170 nv_print_address(const char c
, int buf
, struct nv_value
*a
, int offset
)
173 PRINT(" %s%c%i[", cyan
, c
, buf
);
175 PRINT(" %s%c[", cyan
, c
);
177 PRINT("%s$a%i%s+", mgta
, nv_value_id(a
), cyan
);
178 PRINT("%s0x%x%s]", orng
, offset
, cyan
);
182 nv_print_cond(struct nv_instruction
*nvi
)
184 char pfx
= nv_value_allocated(nvi
->flags_src
->value
->join
) ? '$' : '%';
186 PRINT("%s%s %s%cc%i ",
187 gree
, nv_cond_name(nvi
->cc
),
188 mgta
, pfx
, nv_value_id(nvi
->flags_src
->value
));
192 nv_print_value(struct nv_value
*value
, struct nv_value
*ind
, ubyte type
)
196 if (type
== NV_TYPE_ANY
)
197 type
= value
->reg
.type
;
199 if (value
->reg
.file
!= NV_FILE_FLAGS
)
200 PRINT(" %s%s", gree
, nv_type_name(type
));
202 if (!nv_value_allocated(value
->join
))
205 switch (value
->reg
.file
) {
207 PRINT(" %s%cr%i", blue
, reg_pfx
, nv_value_id(value
));
210 PRINT(" %s%co%i", mgta
, reg_pfx
, nv_value_id(value
));
213 PRINT(" %s%ca%i", mgta
, reg_pfx
, nv_value_id(value
));
216 PRINT(" %s%cc%i", mgta
, reg_pfx
, nv_value_id(value
));
219 nv_print_address('s', -1, ind
, 4 * nv_value_id(value
));
222 nv_print_address('p', -1, ind
, 4 * nv_value_id(value
));
225 nv_print_address('v', -1, ind
, 4 * nv_value_id(value
));
231 PRINT(" %s0x%04x", orng
, value
->reg
.imm
.u32
);
234 PRINT(" %s%f", orng
, value
->reg
.imm
.f32
);
237 PRINT(" %s%f", orng
, value
->reg
.imm
.f64
);
242 PRINT(" %s0x%08x", orng
, value
->reg
.imm
.u32
);
247 if (value
->reg
.file
>= NV_FILE_MEM_G(0) &&
248 value
->reg
.file
<= NV_FILE_MEM_G(15))
249 nv_print_address('g', value
->reg
.file
- NV_FILE_MEM_G(0), ind
,
250 nv_value_id(value
) * 4);
252 if (value
->reg
.file
>= NV_FILE_MEM_C(0) &&
253 value
->reg
.file
<= NV_FILE_MEM_C(15))
254 nv_print_address('c', value
->reg
.file
- NV_FILE_MEM_C(0), ind
,
255 nv_value_id(value
) * 4);
257 NOUVEAU_ERR(" BAD_FILE[%i]", nv_value_id(value
));
263 nv_print_ref(struct nv_ref
*ref
, struct nv_value
*ind
)
265 nv_print_value(ref
->value
, ind
, ref
->typecast
);
269 nv_print_instruction(struct nv_instruction
*i
)
273 PRINT("%i: ", i
->serial
);
279 if (i
->opcode
== NV_OP_SET
)
280 PRINT("set %s", nv_cond_name(i
->set_cond
));
283 PRINT("sat %s", nv_opcode_name(i
->opcode
));
285 PRINT("%s", nv_opcode_name(i
->opcode
));
288 nv_print_value(i
->flags_def
, NULL
, NV_TYPE_ANY
);
290 /* Only STORE & STA can write to MEM, and they do not def
291 * anything, so the address is thus part of the source.
294 nv_print_value(i
->def
[0], NULL
, NV_TYPE_ANY
);
297 PRINT(" %s(BB:%i)", orng
, i
->target
->id
);
301 for (j
= 0; j
< 4; ++j
) {
306 PRINT(" %s%s", gree
, nv_modifier_string(i
->src
[j
]->mod
));
308 nv_print_ref(i
->src
[j
],
309 (j
== nv50_indirect_opnd(i
)) ?
310 i
->src
[4]->value
: NULL
);
312 PRINT(" %s%c\n", norm
, i
->is_long
? 'l' : 's');