Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / gallium / drivers / nv50 / nv50_pc_print.c
1 /*
2  * Copyright 2010 Christoph Bumiller
3  *
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:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
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
20  * SOFTWARE.
21  */
22
23 #include "nv50_context.h"
24 #include "nv50_pc.h"
25
26 #define NVXX_DEBUG 0
27
28 #define PRINT(args...) debug_printf(args)
29
30 #ifndef ARRAY_SIZE
31 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
32 #endif
33
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";
40
41 static const char *nv_opcode_names[NV_OP_COUNT + 1] = {
42    "phi",
43    "extract",
44    "combine",
45    "lda",
46    "sta",
47    "mov",
48    "add",
49    "sub",
50    "neg",
51    "mul",
52    "mad",
53    "cvt",
54    "sat",
55    "not",
56    "and",
57    "or",
58    "xor",
59    "shl",
60    "shr",
61    "rcp",
62    "undef",
63    "rsqrt",
64    "lg2",
65    "sin",
66    "cos",
67    "ex2",
68    "presin",
69    "preex2",
70    "min",
71    "max",
72    "set",
73    "sad",
74    "kil",
75    "bra",
76    "call",
77    "ret",
78    "break",
79    "breakaddr",
80    "joinat",
81    "tex",
82    "texbias",
83    "texlod",
84    "texfetch",
85    "texsize",
86    "dfdx",
87    "dfdy",
88    "quadop",
89    "linterp",
90    "pinterp",
91    "abs",
92    "ceil",
93    "floor",
94    "trunc",
95    "nop",
96    "select",
97    "export",
98    "join",
99    "BAD_OP"
100 };
101
102 static const char *nv_cond_names[] =
103 {
104    "never", "lt" , "eq" , "le" , "gt" , "ne" , "ge" , "",
105    "never", "ltu", "equ", "leu", "gtu", "neu", "geu", "",
106    "o", "c", "a", "s"
107 };
108
109 static const char *nv_modifier_strings[] =
110 {
111    "",
112    "neg",
113    "abs",
114    "neg abs",
115    "not",
116    "not neg"
117    "not abs",
118    "not neg abs",
119    "sat",
120    "BAD_MOD"
121 };
122
123 const char *
124 nv_opcode_name(uint opcode)
125 {
126    return nv_opcode_names[MIN2(opcode, ARRAY_SIZE(nv_opcode_names) - 1)];
127 }
128
129 static INLINE const char *
130 nv_type_name(ubyte type)
131 {
132    switch (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";
140    default:
141       return "BAD_TYPE";
142    }
143 }
144
145 static INLINE const char *
146 nv_cond_name(ubyte cc)
147 {
148    return nv_cond_names[MIN2(cc, 19)];
149 }
150
151 static INLINE const char *
152 nv_modifier_string(ubyte mod)
153 {
154    return nv_modifier_strings[MIN2(mod, 9)];
155 }
156
157 static INLINE int
158 nv_value_id(struct nv_value *value)
159 {
160    if (value->join->reg.id >= 0)
161       return value->join->reg.id;
162    return value->n;
163 }
164
165 static INLINE boolean
166 nv_value_allocated(struct nv_value *value)
167 {
168    return (value->reg.id >= 0) ? TRUE : FALSE;
169 }
170
171 static INLINE void
172 nv_print_address(const char c, int buf, struct nv_value *a, int offset)
173 {
174    const char ac =  (a && nv_value_allocated(a)) ? '$' : '%';
175
176    if (buf >= 0)
177       PRINT(" %s%c%i[", cyan, c, buf);
178    else
179       PRINT(" %s%c[", cyan, c);
180    if (a)
181       PRINT("%s%ca%i%s+", mgta, ac, nv_value_id(a), cyan);
182    PRINT("%s0x%x%s]", orng, offset, cyan);
183 }
184
185 static INLINE void
186 nv_print_cond(struct nv_instruction *nvi)
187 {
188    char pfx = nv_value_allocated(nvi->flags_src->value->join) ? '$' : '%';
189
190    PRINT("%s%s %s%cc%i ",
191          gree, nv_cond_name(nvi->cc),
192          mgta, pfx, nv_value_id(nvi->flags_src->value));
193 }
194
195 static INLINE void
196 nv_print_value(struct nv_value *value, struct nv_value *ind, ubyte type)
197 {
198    char reg_pfx = '$';
199
200    if (type == NV_TYPE_ANY)
201       type = value->reg.type;
202
203    if (value->reg.file != NV_FILE_FLAGS)
204       PRINT(" %s%s", gree, nv_type_name(type));
205
206    if (!nv_value_allocated(value->join))
207       reg_pfx = '%';
208
209    switch (value->reg.file) {
210    case NV_FILE_GPR:
211       PRINT(" %s%cr%i", blue, reg_pfx, nv_value_id(value));
212       break;
213    case NV_FILE_OUT:
214       PRINT(" %s%co%i", mgta, reg_pfx, nv_value_id(value));
215       break;
216    case NV_FILE_ADDR:
217       PRINT(" %s%ca%i", mgta, reg_pfx, nv_value_id(value));
218       break;
219    case NV_FILE_FLAGS:
220       PRINT(" %s%cc%i", mgta, reg_pfx, nv_value_id(value));
221       break;
222    case NV_FILE_MEM_L:
223       nv_print_address('l', -1, ind, nv_value_id(value));
224       break;
225    case NV_FILE_MEM_S:
226       nv_print_address('s', -1, ind, 4 * nv_value_id(value));
227       break;
228    case NV_FILE_MEM_P:
229       nv_print_address('p', -1, ind, 4 * nv_value_id(value));
230       break;
231    case NV_FILE_MEM_V:
232       nv_print_address('v', -1, ind, 4 * nv_value_id(value));
233       break;
234    case NV_FILE_IMM:
235       switch (type) {
236       case NV_TYPE_U16:
237       case NV_TYPE_S16:
238          PRINT(" %s0x%04x", orng, value->reg.imm.u32);
239          break;
240       case NV_TYPE_F32:
241          PRINT(" %s%f", orng, value->reg.imm.f32);
242          break;
243       case NV_TYPE_F64:
244          PRINT(" %s%f", orng, value->reg.imm.f64);
245          break;
246       case NV_TYPE_U32:
247       case NV_TYPE_S32:
248       case NV_TYPE_P32:
249          PRINT(" %s0x%08x", orng, value->reg.imm.u32);
250          break;
251       }
252       break;
253    default:
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);
258       else
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);
263       else
264          NOUVEAU_ERR(" BAD_FILE[%i]", nv_value_id(value));
265       break;
266    }
267 }
268
269 static INLINE void
270 nv_print_ref(struct nv_ref *ref, struct nv_value *ind)
271 {
272    nv_print_value(ref->value, ind, ref->typecast);
273 }
274
275 void
276 nv_print_instruction(struct nv_instruction *i)
277 {
278    int j;
279
280    PRINT("%i: ", i->serial);
281
282    if (i->flags_src)
283       nv_print_cond(i);
284
285    PRINT("%s", gree);
286    if (i->opcode == NV_OP_SET)
287       PRINT("set %s", nv_cond_name(i->set_cond));
288    else
289    if (i->saturate)
290       PRINT("sat %s", nv_opcode_name(i->opcode));
291    else
292       PRINT("%s", nv_opcode_name(i->opcode));
293
294    if (i->flags_def)
295       nv_print_value(i->flags_def, NULL, NV_TYPE_ANY);
296
297    /* Only STORE & STA can write to MEM, and they do not def
298     * anything, so the address is thus part of the source.
299     */
300    if (i->def[0])
301       nv_print_value(i->def[0], NULL, NV_TYPE_ANY);
302    else
303    if (i->target)
304       PRINT(" %s(BB:%i)", orng, i->target->id);
305    else
306       PRINT(" #");
307
308    for (j = 0; j < 4; ++j) {
309       if (!i->src[j])
310          continue;
311
312       if (i->src[j]->mod)
313          PRINT(" %s%s", gree, nv_modifier_string(i->src[j]->mod));
314
315       nv_print_ref(i->src[j],
316                    (j == nv50_indirect_opnd(i)) ?
317                    i->src[4]->value : NULL);
318    }
319    PRINT(" %s%c\n", norm, i->is_long ? 'l' : 's');
320 }