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