ir_print_visitor: print the type of expressions.
[mesa.git] / ir_print_visitor.cpp
1 /*
2 * Copyright © 2010 Intel Corporation
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 (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23 #include <cstdio>
24 #include "ir_print_visitor.h"
25 #include "glsl_types.h"
26
27 static void
28 print_type(const glsl_type *t)
29 {
30 if (t->base_type == GLSL_TYPE_ARRAY) {
31 printf("(array ");
32 print_type(t->fields.array);
33 printf(" (%u))", t->length);
34 } else if (t->base_type == GLSL_TYPE_STRUCT) {
35 printf("(struct (%s %u ", t->name ? t->name : "@", t->length);
36 printf("(FINISHME: structure fields go here) ");
37 printf(")");
38 } else {
39 printf("%s", t->name);
40 }
41 }
42
43
44 void ir_print_visitor::visit(ir_variable *ir)
45 {
46 if (deref_depth) {
47 printf("(%s)", ir->name);
48 } else {
49 printf("(declare ");
50
51 const char *const cent = (ir->centroid) ? "centroid " : "";
52 const char *const inv = (ir->invariant) ? "invariant " : "";
53 const char *const mode[] = { "", "uniform ", "in ", "out ", "inout " };
54 const char *const interp[] = { "", "flat", "noperspective" };
55
56 printf("(%s%s%s%s) ",
57 cent, inv, mode[ir->mode], interp[ir->interpolation]);
58
59 print_type(ir->type);
60 printf("(%s)) ", ir->name);
61 }
62 }
63
64
65 void ir_print_visitor::visit(ir_function_signature *ir)
66 {
67 printf("(signature\n (parameters\n");
68 foreach_iter(exec_list_iterator, iter, ir->parameters) {
69 ir_variable *const inst = (ir_variable *) iter.get();
70
71 inst->accept(this);
72 printf("\n");
73 }
74 printf(" )\n(");
75
76 foreach_iter(exec_list_iterator, iter, ir->body) {
77 ir_instruction *const inst = (ir_instruction *) iter.get();
78
79 inst->accept(this);
80 printf("\n");
81 }
82 printf("))\n");
83 }
84
85
86 void ir_print_visitor::visit(ir_function *ir)
87 {
88 printf("(function %s\n", ir->name);
89 foreach_iter(exec_list_iterator, iter, *ir) {
90 ir_function_signature *const sig = (ir_function_signature *) iter.get();
91
92 sig->accept(this);
93 printf("\n");
94 }
95
96 printf(")\n");
97 }
98
99
100 void ir_print_visitor::visit(ir_expression *ir)
101 {
102 static const char *const operators[] = {
103 "~",
104 "!",
105 "-",
106 "abs",
107 "rcp",
108 "rsq",
109 "sqrt",
110 "exp",
111 "log",
112 "exp2",
113 "log2",
114 "f2i",
115 "i2f",
116 "f2b",
117 "b2f",
118 "i2b",
119 "b2i",
120 "u2f",
121 "trunc",
122 "ceil",
123 "floor",
124 "+",
125 "-",
126 "*",
127 "/",
128 "%",
129 "<",
130 ">",
131 "<=",
132 ">=",
133 "==",
134 "!=",
135 "<<",
136 ">>",
137 "&",
138 "^",
139 "|",
140 "&&",
141 "^^",
142 "||",
143 "dot",
144 "min",
145 "max",
146 "pow",
147 };
148
149 printf("(expression ");
150
151 print_type(ir->type);
152
153 assert((unsigned int)ir->operation <
154 sizeof(operators) / sizeof(operators[0]));
155
156 printf(" %s ", operators[ir->operation]);
157
158 printf("(");
159 if (ir->operands[0])
160 ir->operands[0]->accept(this);
161 printf(") ");
162
163 printf("(");
164 if (ir->operands[1])
165 ir->operands[1]->accept(this);
166 printf(")) ");
167 }
168
169
170 void ir_print_visitor::visit(ir_swizzle *ir)
171 {
172 const unsigned swiz[4] = {
173 ir->mask.x,
174 ir->mask.y,
175 ir->mask.z,
176 ir->mask.w,
177 };
178
179 printf("(swiz ");
180 for (unsigned i = 0; i < ir->mask.num_components; i++) {
181 printf("%c", "xyzw"[swiz[i]]);
182 }
183 printf(" ");
184 ir->val->accept(this);
185 printf(")");
186 }
187
188
189 void ir_print_visitor::visit(ir_dereference *ir)
190 {
191 deref_depth++;
192
193 switch (ir->mode) {
194 case ir_dereference::ir_reference_variable: {
195 printf("(var_ref ");
196 ir->var->accept(this);
197 printf(") ");
198 break;
199 }
200 case ir_dereference::ir_reference_array:
201 printf("(array_ref ");
202 ir->var->accept(this);
203 ir->selector.array_index->accept(this);
204 printf(") ");
205 break;
206 case ir_dereference::ir_reference_record:
207 printf("(record_ref ");
208 ir->var->accept(this);
209 printf("(%s)) ", ir->selector.field);
210 break;
211 }
212
213 deref_depth--;
214 }
215
216
217 void ir_print_visitor::visit(ir_assignment *ir)
218 {
219 printf("(assign (");
220
221 if (ir->condition)
222 ir->condition->accept(this);
223 else
224 printf("true");
225
226 printf(") (");
227
228 ir->lhs->accept(this);
229
230 printf(") (");
231
232 ir->rhs->accept(this);
233 printf(") ");
234 }
235
236
237 void ir_print_visitor::visit(ir_constant *ir)
238 {
239 const glsl_type *const base_type = ir->type->get_base_type();
240
241 printf("(constant ");
242 print_type(ir->type);
243 printf(" (");
244
245 for (unsigned i = 0; i < ir->type->components(); i++) {
246 if (i != 0)
247 printf(", ");
248
249 switch (base_type->base_type) {
250 case GLSL_TYPE_UINT: printf("%u", ir->value.u[i]); break;
251 case GLSL_TYPE_INT: printf("%d", ir->value.i[i]); break;
252 case GLSL_TYPE_FLOAT: printf("%f", ir->value.f[i]); break;
253 case GLSL_TYPE_BOOL: printf("%d", ir->value.b[i]); break;
254 default: assert(0);
255 }
256 }
257 printf(")) ");
258 }
259
260
261 void
262 ir_print_visitor::visit(ir_call *ir)
263 {
264 printf("(call (%s) ", ir->callee_name());
265 foreach_iter(exec_list_iterator, iter, *ir) {
266 ir_instruction *const inst = (ir_instruction *) iter.get();
267
268 inst->accept(this);
269 }
270 }
271
272
273 void
274 ir_print_visitor::visit(ir_return *ir)
275 {
276 printf("(return");
277
278 ir_rvalue *const value = ir->get_value();
279 if (value) {
280 printf(" ");
281 value->accept(this);
282 }
283
284 printf(")");
285 }
286
287
288 void
289 ir_print_visitor::visit(ir_if *ir)
290 {
291 printf("(if ");
292 ir->condition->accept(this);
293
294 printf("(\n");
295 foreach_iter(exec_list_iterator, iter, ir->then_instructions) {
296 ir_instruction *const inst = (ir_instruction *) iter.get();
297
298 inst->accept(this);
299 printf("\n");
300 }
301 printf(")\n");
302
303 printf("(\n");
304 foreach_iter(exec_list_iterator, iter, ir->else_instructions) {
305 ir_instruction *const inst = (ir_instruction *) iter.get();
306
307 inst->accept(this);
308 printf("\n");
309 }
310 printf("))\n");
311 }
312
313
314 void
315 ir_print_visitor::visit(ir_loop *ir)
316 {
317 printf("(loop (");
318 if (ir->counter != NULL)
319 ir->counter->accept(this);
320 printf(") (");
321 if (ir->from != NULL)
322 ir->from->accept(this);
323 printf(") (");
324 if (ir->to != NULL)
325 ir->to->accept(this);
326 printf(") (");
327 if (ir->increment != NULL)
328 ir->increment->accept(this);
329 printf(") (\n");
330 foreach_iter(exec_list_iterator, iter, ir->body_instructions) {
331 ir_instruction *const inst = (ir_instruction *) iter.get();
332
333 inst->accept(this);
334 printf("\n");
335 }
336 printf("))\n");
337 }
338
339
340 void
341 ir_print_visitor::visit(ir_loop_jump *ir)
342 {
343 printf("%s", ir->is_break() ? "break" : "continue");
344 }