st/xa: Fix crosscompile builds with nonstandard ld locations
[mesa.git] / src / glsl / 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
24 #include "ir_print_visitor.h"
25 #include "glsl_types.h"
26 #include "glsl_parser_extras.h"
27
28 extern "C" {
29 #include "program/hash_table.h"
30 }
31
32 static void print_type(const glsl_type *t);
33
34 void
35 ir_instruction::print(void) const
36 {
37 ir_instruction *deconsted = const_cast<ir_instruction *>(this);
38
39 ir_print_visitor v;
40 deconsted->accept(&v);
41 }
42
43 void
44 _mesa_print_ir(exec_list *instructions,
45 struct _mesa_glsl_parse_state *state)
46 {
47 if (state) {
48 for (unsigned i = 0; i < state->num_user_structures; i++) {
49 const glsl_type *const s = state->user_structures[i];
50
51 printf("(structure (%s) (%s@%p) (%u) (\n",
52 s->name, s->name, (void *) s, s->length);
53
54 for (unsigned j = 0; j < s->length; j++) {
55 printf("\t((");
56 print_type(s->fields.structure[j].type);
57 printf(")(%s))\n", s->fields.structure[j].name);
58 }
59
60 printf(")\n");
61 }
62 }
63
64 printf("(\n");
65 foreach_iter(exec_list_iterator, iter, *instructions) {
66 ir_instruction *ir = (ir_instruction *)iter.get();
67 ir->print();
68 if (ir->ir_type != ir_type_function)
69 printf("\n");
70 }
71 printf("\n)");
72 }
73
74 ir_print_visitor::ir_print_visitor()
75 {
76 indentation = 0;
77 printable_names =
78 hash_table_ctor(32, hash_table_pointer_hash, hash_table_pointer_compare);
79 symbols = _mesa_symbol_table_ctor();
80 mem_ctx = ralloc_context(NULL);
81 }
82
83 ir_print_visitor::~ir_print_visitor()
84 {
85 hash_table_dtor(printable_names);
86 _mesa_symbol_table_dtor(symbols);
87 ralloc_free(mem_ctx);
88 }
89
90 void ir_print_visitor::indent(void)
91 {
92 for (int i = 0; i < indentation; i++)
93 printf(" ");
94 }
95
96 const char *
97 ir_print_visitor::unique_name(ir_variable *var)
98 {
99 /* Do we already have a name for this variable? */
100 const char *name = (const char *) hash_table_find(this->printable_names, var);
101 if (name != NULL)
102 return name;
103
104 /* If there's no conflict, just use the original name */
105 if (_mesa_symbol_table_find_symbol(this->symbols, -1, var->name) == NULL) {
106 name = var->name;
107 } else {
108 static unsigned i = 1;
109 name = ralloc_asprintf(this->mem_ctx, "%s@%u", var->name, ++i);
110 }
111 hash_table_insert(this->printable_names, (void *) name, var);
112 _mesa_symbol_table_add_symbol(this->symbols, -1, name, var);
113 return name;
114 }
115
116 static void
117 print_type(const glsl_type *t)
118 {
119 if (t->base_type == GLSL_TYPE_ARRAY) {
120 printf("(array ");
121 print_type(t->fields.array);
122 printf(" %u)", t->length);
123 } else if ((t->base_type == GLSL_TYPE_STRUCT)
124 && (strncmp("gl_", t->name, 3) != 0)) {
125 printf("%s@%p", t->name, (void *) t);
126 } else {
127 printf("%s", t->name);
128 }
129 }
130
131
132 void ir_print_visitor::visit(ir_variable *ir)
133 {
134 printf("(declare ");
135
136 const char *const cent = (ir->centroid) ? "centroid " : "";
137 const char *const inv = (ir->invariant) ? "invariant " : "";
138 const char *const mode[] = { "", "uniform ", "in ", "out ", "inout ",
139 "const_in ", "sys ", "temporary " };
140 const char *const interp[] = { "", "flat", "noperspective" };
141
142 printf("(%s%s%s%s) ",
143 cent, inv, mode[ir->mode], interp[ir->interpolation]);
144
145 print_type(ir->type);
146 printf(" %s)", unique_name(ir));
147 }
148
149
150 void ir_print_visitor::visit(ir_function_signature *ir)
151 {
152 _mesa_symbol_table_push_scope(symbols);
153 printf("(signature ");
154 indentation++;
155
156 print_type(ir->return_type);
157 printf("\n");
158 indent();
159
160 printf("(parameters\n");
161 indentation++;
162
163 foreach_iter(exec_list_iterator, iter, ir->parameters) {
164 ir_variable *const inst = (ir_variable *) iter.get();
165
166 indent();
167 inst->accept(this);
168 printf("\n");
169 }
170 indentation--;
171
172 indent();
173 printf(")\n");
174
175 indent();
176
177 printf("(\n");
178 indentation++;
179
180 foreach_iter(exec_list_iterator, iter, ir->body) {
181 ir_instruction *const inst = (ir_instruction *) iter.get();
182
183 indent();
184 inst->accept(this);
185 printf("\n");
186 }
187 indentation--;
188 indent();
189 printf("))\n");
190 indentation--;
191 _mesa_symbol_table_pop_scope(symbols);
192 }
193
194
195 void ir_print_visitor::visit(ir_function *ir)
196 {
197 printf("(function %s\n", ir->name);
198 indentation++;
199 foreach_iter(exec_list_iterator, iter, *ir) {
200 ir_function_signature *const sig = (ir_function_signature *) iter.get();
201 indent();
202 sig->accept(this);
203 printf("\n");
204 }
205 indentation--;
206 indent();
207 printf(")\n\n");
208 }
209
210
211 void ir_print_visitor::visit(ir_expression *ir)
212 {
213 printf("(expression ");
214
215 print_type(ir->type);
216
217 printf(" %s ", ir->operator_string());
218
219 for (unsigned i = 0; i < ir->get_num_operands(); i++) {
220 ir->operands[i]->accept(this);
221 }
222
223 printf(") ");
224 }
225
226
227 void ir_print_visitor::visit(ir_texture *ir)
228 {
229 printf("(%s ", ir->opcode_string());
230
231 print_type(ir->type);
232 printf(" ");
233
234 ir->sampler->accept(this);
235 printf(" ");
236
237 ir->coordinate->accept(this);
238
239 printf(" ");
240
241 if (ir->offset != NULL) {
242 ir->offset->accept(this);
243 } else {
244 printf("0");
245 }
246
247 printf(" ");
248
249 if (ir->op != ir_txf) {
250 if (ir->projector)
251 ir->projector->accept(this);
252 else
253 printf("1");
254
255 if (ir->shadow_comparitor) {
256 printf(" ");
257 ir->shadow_comparitor->accept(this);
258 } else {
259 printf(" ()");
260 }
261 }
262
263 printf(" ");
264 switch (ir->op)
265 {
266 case ir_tex:
267 break;
268 case ir_txb:
269 ir->lod_info.bias->accept(this);
270 break;
271 case ir_txl:
272 case ir_txf:
273 ir->lod_info.lod->accept(this);
274 break;
275 case ir_txd:
276 printf("(");
277 ir->lod_info.grad.dPdx->accept(this);
278 printf(" ");
279 ir->lod_info.grad.dPdy->accept(this);
280 printf(")");
281 break;
282 };
283 printf(")");
284 }
285
286
287 void ir_print_visitor::visit(ir_swizzle *ir)
288 {
289 const unsigned swiz[4] = {
290 ir->mask.x,
291 ir->mask.y,
292 ir->mask.z,
293 ir->mask.w,
294 };
295
296 printf("(swiz ");
297 for (unsigned i = 0; i < ir->mask.num_components; i++) {
298 printf("%c", "xyzw"[swiz[i]]);
299 }
300 printf(" ");
301 ir->val->accept(this);
302 printf(")");
303 }
304
305
306 void ir_print_visitor::visit(ir_dereference_variable *ir)
307 {
308 ir_variable *var = ir->variable_referenced();
309 printf("(var_ref %s) ", unique_name(var));
310 }
311
312
313 void ir_print_visitor::visit(ir_dereference_array *ir)
314 {
315 printf("(array_ref ");
316 ir->array->accept(this);
317 ir->array_index->accept(this);
318 printf(") ");
319 }
320
321
322 void ir_print_visitor::visit(ir_dereference_record *ir)
323 {
324 printf("(record_ref ");
325 ir->record->accept(this);
326 printf(" %s) ", ir->field);
327 }
328
329
330 void ir_print_visitor::visit(ir_assignment *ir)
331 {
332 printf("(assign ");
333
334 if (ir->condition)
335 ir->condition->accept(this);
336
337 char mask[5];
338 unsigned j = 0;
339
340 for (unsigned i = 0; i < 4; i++) {
341 if ((ir->write_mask & (1 << i)) != 0) {
342 mask[j] = "xyzw"[i];
343 j++;
344 }
345 }
346 mask[j] = '\0';
347
348 printf(" (%s) ", mask);
349
350 ir->lhs->accept(this);
351
352 printf(" ");
353
354 ir->rhs->accept(this);
355 printf(") ");
356 }
357
358
359 void ir_print_visitor::visit(ir_constant *ir)
360 {
361 const glsl_type *const base_type = ir->type->get_base_type();
362
363 printf("(constant ");
364 print_type(ir->type);
365 printf(" (");
366
367 if (ir->type->is_array()) {
368 for (unsigned i = 0; i < ir->type->length; i++)
369 ir->get_array_element(i)->accept(this);
370 } else if (ir->type->is_record()) {
371 ir_constant *value = (ir_constant *) ir->components.get_head();
372 for (unsigned i = 0; i < ir->type->length; i++) {
373 printf("(%s ", ir->type->fields.structure[i].name);
374 value->accept(this);
375 printf(")");
376
377 value = (ir_constant *) value->next;
378 }
379 } else {
380 for (unsigned i = 0; i < ir->type->components(); i++) {
381 if (i != 0)
382 printf(" ");
383 switch (base_type->base_type) {
384 case GLSL_TYPE_UINT: printf("%u", ir->value.u[i]); break;
385 case GLSL_TYPE_INT: printf("%d", ir->value.i[i]); break;
386 case GLSL_TYPE_FLOAT: printf("%f", ir->value.f[i]); break;
387 case GLSL_TYPE_BOOL: printf("%d", ir->value.b[i]); break;
388 default: assert(0);
389 }
390 }
391 }
392 printf(")) ");
393 }
394
395
396 void
397 ir_print_visitor::visit(ir_call *ir)
398 {
399 printf("(call %s (", ir->callee_name());
400 foreach_iter(exec_list_iterator, iter, *ir) {
401 ir_instruction *const inst = (ir_instruction *) iter.get();
402
403 inst->accept(this);
404 }
405 printf("))\n");
406 }
407
408
409 void
410 ir_print_visitor::visit(ir_return *ir)
411 {
412 printf("(return");
413
414 ir_rvalue *const value = ir->get_value();
415 if (value) {
416 printf(" ");
417 value->accept(this);
418 }
419
420 printf(")");
421 }
422
423
424 void
425 ir_print_visitor::visit(ir_discard *ir)
426 {
427 printf("(discard ");
428
429 if (ir->condition != NULL) {
430 printf(" ");
431 ir->condition->accept(this);
432 }
433
434 printf(")");
435 }
436
437
438 void
439 ir_print_visitor::visit(ir_if *ir)
440 {
441 printf("(if ");
442 ir->condition->accept(this);
443
444 printf("(\n");
445 indentation++;
446
447 foreach_iter(exec_list_iterator, iter, ir->then_instructions) {
448 ir_instruction *const inst = (ir_instruction *) iter.get();
449
450 indent();
451 inst->accept(this);
452 printf("\n");
453 }
454
455 indentation--;
456 indent();
457 printf(")\n");
458
459 indent();
460 if (!ir->else_instructions.is_empty()) {
461 printf("(\n");
462 indentation++;
463
464 foreach_iter(exec_list_iterator, iter, ir->else_instructions) {
465 ir_instruction *const inst = (ir_instruction *) iter.get();
466
467 indent();
468 inst->accept(this);
469 printf("\n");
470 }
471 indentation--;
472 indent();
473 printf("))\n");
474 } else {
475 printf("())\n");
476 }
477 }
478
479
480 void
481 ir_print_visitor::visit(ir_loop *ir)
482 {
483 printf("(loop (");
484 if (ir->counter != NULL)
485 ir->counter->accept(this);
486 printf(") (");
487 if (ir->from != NULL)
488 ir->from->accept(this);
489 printf(") (");
490 if (ir->to != NULL)
491 ir->to->accept(this);
492 printf(") (");
493 if (ir->increment != NULL)
494 ir->increment->accept(this);
495 printf(") (\n");
496 indentation++;
497
498 foreach_iter(exec_list_iterator, iter, ir->body_instructions) {
499 ir_instruction *const inst = (ir_instruction *) iter.get();
500
501 indent();
502 inst->accept(this);
503 printf("\n");
504 }
505 indentation--;
506 indent();
507 printf("))\n");
508 }
509
510
511 void
512 ir_print_visitor::visit(ir_loop_jump *ir)
513 {
514 printf("%s", ir->is_break() ? "break" : "continue");
515 }