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');