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
)
185 gree
, nv_cond_name(nvi
->cc
),
186 mgta
, nv_value_id(nvi
->flags_src
->value
));
190 nv_print_value(struct nv_value
*value
, struct nv_value
*ind
, ubyte type
)
194 if (type
== NV_TYPE_ANY
)
195 type
= value
->reg
.type
;
197 if (value
->reg
.file
!= NV_FILE_FLAGS
)
198 PRINT(" %s%s", gree
, nv_type_name(type
));
200 if (!nv_value_allocated(value
))
203 switch (value
->reg
.file
) {
205 PRINT(" %s%cr%i", blue
, reg_pfx
, nv_value_id(value
));
208 PRINT(" %s%co%i", mgta
, reg_pfx
, nv_value_id(value
));
211 PRINT(" %s%ca%i", mgta
, reg_pfx
, nv_value_id(value
));
214 PRINT(" %s%cc%i", mgta
, reg_pfx
, nv_value_id(value
));
217 nv_print_address('s', -1, ind
, 4 * nv_value_id(value
));
220 nv_print_address('p', -1, ind
, 4 * nv_value_id(value
));
223 nv_print_address('v', -1, ind
, 4 * nv_value_id(value
));
229 PRINT(" %s0x%04x", orng
, value
->reg
.imm
.u32
);
232 PRINT(" %s%f", orng
, value
->reg
.imm
.f32
);
235 PRINT(" %s%f", orng
, value
->reg
.imm
.f64
);
240 PRINT(" %s0x%08x", orng
, value
->reg
.imm
.u32
);
245 if (value
->reg
.file
>= NV_FILE_MEM_G(0) &&
246 value
->reg
.file
<= NV_FILE_MEM_G(15))
247 nv_print_address('g', value
->reg
.file
- NV_FILE_MEM_G(0), ind
,
248 nv_value_id(value
) * 4);
250 if (value
->reg
.file
>= NV_FILE_MEM_C(0) &&
251 value
->reg
.file
<= NV_FILE_MEM_C(15))
252 nv_print_address('c', value
->reg
.file
- NV_FILE_MEM_C(0), ind
,
253 nv_value_id(value
) * 4);
255 NOUVEAU_ERR(" BAD_FILE[%i]", nv_value_id(value
));
261 nv_print_ref(struct nv_ref
*ref
, struct nv_value
*ind
)
263 nv_print_value(ref
->value
, ind
, ref
->typecast
);
267 nv_print_instruction(struct nv_instruction
*i
)
275 if (i
->opcode
== NV_OP_SET
)
276 PRINT("set %s", nv_cond_name(i
->set_cond
));
279 PRINT("sat %s", nv_opcode_name(i
->opcode
));
281 PRINT("%s", nv_opcode_name(i
->opcode
));
284 nv_print_value(i
->flags_def
, NULL
, NV_TYPE_ANY
);
286 /* Only STORE & STA can write to MEM, and they do not def
287 * anything, so the address is thus part of the source.
290 nv_print_value(i
->def
[0], NULL
, NV_TYPE_ANY
);
294 for (j
= 0; j
< 4; ++j
) {
299 PRINT(" %s", nv_modifier_string(i
->src
[j
]->mod
));
301 nv_print_ref(i
->src
[j
],
302 (j
== nv50_indirect_opnd(i
)) ?
303 i
->src
[4]->value
: NULL
);