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", ""
108 static const char *nv_modifier_strings
[] =
123 nv_opcode_name(uint opcode
)
125 return nv_opcode_names
[MIN2(opcode
, ARRAY_SIZE(nv_opcode_names
) - 1)];
128 static INLINE
const char *
129 nv_type_name(ubyte type
)
132 case NV_TYPE_U16
: return "u16";
133 case NV_TYPE_S16
: return "s16";
134 case NV_TYPE_F32
: return "f32";
135 case NV_TYPE_U32
: return "u32";
136 case NV_TYPE_S32
: return "s32";
137 case NV_TYPE_P32
: return "p32";
138 case NV_TYPE_F64
: return "f64";
144 static INLINE
const char *
145 nv_cond_name(ubyte cc
)
147 return nv_cond_names
[MIN2(cc
, 15)];
150 static INLINE
const char *
151 nv_modifier_string(ubyte mod
)
153 return nv_modifier_strings
[MIN2(mod
, 9)];
157 nv_value_id(struct nv_value
*value
)
159 if (value
->join
->reg
.id
>= 0)
160 return value
->join
->reg
.id
;
164 static INLINE boolean
165 nv_value_allocated(struct nv_value
*value
)
167 return (value
->reg
.id
>= 0) ? TRUE
: FALSE
;
171 nv_print_address(const char c
, int buf
, struct nv_value
*a
, int offset
)
174 PRINT(" %s%c%i[", cyan
, c
, buf
);
176 PRINT(" %s%c[", cyan
, c
);
178 PRINT("%s$a%i%s+", mgta
, nv_value_id(a
), cyan
);
179 PRINT("%s0x%x%s]", orng
, offset
, cyan
);
183 nv_print_cond(struct nv_instruction
*nvi
)
185 char pfx
= nv_value_allocated(nvi
->flags_src
->value
->join
) ? '$' : '%';
187 PRINT("%s%s %s%cc%i ",
188 gree
, nv_cond_name(nvi
->cc
),
189 mgta
, pfx
, nv_value_id(nvi
->flags_src
->value
));
193 nv_print_value(struct nv_value
*value
, struct nv_value
*ind
, ubyte type
)
197 if (type
== NV_TYPE_ANY
)
198 type
= value
->reg
.type
;
200 if (value
->reg
.file
!= NV_FILE_FLAGS
)
201 PRINT(" %s%s", gree
, nv_type_name(type
));
203 if (!nv_value_allocated(value
->join
))
206 switch (value
->reg
.file
) {
208 PRINT(" %s%cr%i", blue
, reg_pfx
, nv_value_id(value
));
211 PRINT(" %s%co%i", mgta
, reg_pfx
, nv_value_id(value
));
214 PRINT(" %s%ca%i", mgta
, reg_pfx
, nv_value_id(value
));
217 PRINT(" %s%cc%i", mgta
, reg_pfx
, nv_value_id(value
));
220 nv_print_address('s', -1, ind
, 4 * nv_value_id(value
));
223 nv_print_address('p', -1, ind
, 4 * nv_value_id(value
));
226 nv_print_address('v', -1, ind
, 4 * nv_value_id(value
));
232 PRINT(" %s0x%04x", orng
, value
->reg
.imm
.u32
);
235 PRINT(" %s%f", orng
, value
->reg
.imm
.f32
);
238 PRINT(" %s%f", orng
, value
->reg
.imm
.f64
);
243 PRINT(" %s0x%08x", orng
, value
->reg
.imm
.u32
);
248 if (value
->reg
.file
>= NV_FILE_MEM_G(0) &&
249 value
->reg
.file
<= NV_FILE_MEM_G(15))
250 nv_print_address('g', value
->reg
.file
- NV_FILE_MEM_G(0), ind
,
251 nv_value_id(value
) * 4);
253 if (value
->reg
.file
>= NV_FILE_MEM_C(0) &&
254 value
->reg
.file
<= NV_FILE_MEM_C(15))
255 nv_print_address('c', value
->reg
.file
- NV_FILE_MEM_C(0), ind
,
256 nv_value_id(value
) * 4);
258 NOUVEAU_ERR(" BAD_FILE[%i]", nv_value_id(value
));
264 nv_print_ref(struct nv_ref
*ref
, struct nv_value
*ind
)
266 nv_print_value(ref
->value
, ind
, ref
->typecast
);
270 nv_print_instruction(struct nv_instruction
*i
)
274 PRINT("%i: ", i
->serial
);
280 if (i
->opcode
== NV_OP_SET
)
281 PRINT("set %s", nv_cond_name(i
->set_cond
));
284 PRINT("sat %s", nv_opcode_name(i
->opcode
));
286 PRINT("%s", nv_opcode_name(i
->opcode
));
289 nv_print_value(i
->flags_def
, NULL
, NV_TYPE_ANY
);
291 /* Only STORE & STA can write to MEM, and they do not def
292 * anything, so the address is thus part of the source.
295 nv_print_value(i
->def
[0], NULL
, NV_TYPE_ANY
);
298 PRINT(" %s(BB:%i)", orng
, i
->target
->id
);
302 for (j
= 0; j
< 4; ++j
) {
307 PRINT(" %s%s", gree
, nv_modifier_string(i
->src
[j
]->mod
));
309 nv_print_ref(i
->src
[j
],
310 (j
== nv50_indirect_opnd(i
)) ?
311 i
->src
[4]->value
: NULL
);
313 PRINT(" %s%c\n", norm
, i
->is_long
? 'l' : 's');