1 /*
2 * sparse/show-parse.c
3 *
4 * Copyright (C) 2003 Transmeta Corp.
5 * 2003-2004 Linus Torvalds
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 *
25 * Print out results of parsing for debugging and testing.
26 */
27 #include <stdarg.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34
35 #include "lib.h"
36 #include "allocate.h"
37 #include "token.h"
38 #include "parse.h"
39 #include "symbol.h"
40 #include "scope.h"
41 #include "expression.h"
42 #include "target.h"
43
44 static int show_symbol_expr(struct symbol *sym);
45 static int show_string_expr(struct expression *expr);
46
47 static void do_debug_symbol(struct symbol *sym, int indent)
48 {
49 static const char indent_string[] = " ";
50 static const char *typestr[] = {
51 [SYM_UNINITIALIZED] = "none",
52 [SYM_PREPROCESSOR] = "cpp.",
53 [SYM_BASETYPE] = "base",
54 [SYM_NODE] = "node",
55 [SYM_PTR] = "ptr.",
56 [SYM_FN] = "fn..",
57 [SYM_ARRAY] = "arry",
58 [SYM_STRUCT] = "strt",
59 [SYM_UNION] = "unin",
60 [SYM_ENUM] = "enum",
61 [SYM_TYPEDEF] = "tdef",
62 [SYM_TYPEOF] = "tpof",
63 [SYM_MEMBER] = "memb",
64 [SYM_BITFIELD] = "bitf",
65 [SYM_LABEL] = "labl",
66 [SYM_RESTRICT] = "rstr",
67 [SYM_FOULED] = "foul",
68 [SYM_BAD] = "bad.",
69 };
70 struct context *context;
71 int i;
72
73 if (!sym)
74 return;
75 fprintf(stderr, "%.*s%s%3d:%lu %s %s (as: %d) %p (%s:%d:%d) %s\n",
76 indent, indent_string, typestr[sym->type],
77 sym->bit_size, sym->ctype.alignment,
78 modifier_string(sym->ctype.modifiers), show_ident(sym->ident), sym->ctype.as,
79 sym, stream_name(sym->pos.stream), sym->pos.line, sym->pos.pos,
80 builtin_typename(sym) ?: "");
81 i = 0;
82 FOR_EACH_PTR(sym->ctype.contexts, context) {
83 /* FIXME: should print context expression */
84 fprintf(stderr, "< context%d: in=%d, out=%d\n",
85 i, context->in, context->out);
86 fprintf(stderr, " end context%d >\n", i);
87 i++;
88 } END_FOR_EACH_PTR(context);
89 if (sym->type == SYM_FN) {
90 struct symbol *arg;
91 i = 0;
92 FOR_EACH_PTR(sym->arguments, arg) {
93 fprintf(stderr, "< arg%d:\n", i);
94 do_debug_symbol(arg, 0);
95 fprintf(stderr, " end arg%d >\n", i);
96 i++;
97 } END_FOR_EACH_PTR(arg);
98 }
99 do_debug_symbol(sym->ctype.base_type, indent+2);
100 }
101
102 void debug_symbol(struct symbol *sym)
103 {
104 do_debug_symbol(sym, 0);
105 }
106
107 /*
108 * Symbol type printout. The type system is by far the most
109 * complicated part of C - everything else is trivial.
110 */
111 const char *modifier_string(unsigned long mod)
112 {
113 static char buffer[100];
114 int len = 0;
115 int i;
116 struct mod_name {
117 unsigned long mod;
118 const char *name;
119 } *m;
120
121 static struct mod_name mod_names[] = {
122 {MOD_AUTO, "auto"},
123 {MOD_REGISTER, "register"},
124 {MOD_STATIC, "static"},
125 {MOD_EXTERN, "extern"},
126 {MOD_CONST, "const"},
127 {MOD_VOLATILE, "volatile"},
128 {MOD_SIGNED, "[signed]"},
129 {MOD_UNSIGNED, "[unsigned]"},
130 {MOD_CHAR, "[char]"},
131 {MOD_SHORT, "[short]"},
132 {MOD_LONG, "[long]"},
133 {MOD_LONGLONG, "[long long]"},
134 {MOD_LONGLONGLONG, "[long long long]"},
135 {MOD_TYPEDEF, "[typedef]"},
136 {MOD_TLS, "[tls]"},
137 {MOD_INLINE, "inline"},
138 {MOD_ADDRESSABLE, "[addressable]"},
139 {MOD_NOCAST, "[nocast]"},
140 {MOD_NODEREF, "[noderef]"},
141 {MOD_ACCESSED, "[accessed]"},
142 {MOD_TOPLEVEL, "[toplevel]"},
143 {MOD_ASSIGNED, "[assigned]"},
144 {MOD_TYPE, "[type]"},
145 {MOD_SAFE, "[safe]"},
146 {MOD_USERTYPE, "[usertype]"},
147 {MOD_NORETURN, "[noreturn]"},
148 {MOD_EXPLICITLY_SIGNED, "[explicitly-signed]"},
149 {MOD_BITWISE, "[bitwise]"},
150 {MOD_PURE, "[pure]"},
151 };
152
153 for (i = 0; i < ARRAY_SIZE(mod_names); i++) {
154 m = mod_names + i;
155 if (mod & m->mod) {
156 char c;
157 const char *name = m->name;
158 while ((c = *name++) != '\0' && len + 2 < sizeof buffer)
159 buffer[len++] = c;
160 buffer[len++] = ' ';
161 }
162 }
163 buffer[len] = 0;
164 return buffer;
165 }
166
167 static void show_struct_member(struct symbol *sym)
168 {
169 printf("\t%s:%d:%ld at offset %ld.%d", show_ident(sym->ident), sym->bit_size, sym->ctype.alignment, sym->offset, sym->bit_offset);
170 printf("\n");
171 }
172
173 void show_symbol_list(struct symbol_list *list, const char *sep)
174 {
175 struct symbol *sym;
176 const char *prepend = "";
177
178 FOR_EACH_PTR(list, sym) {
179 puts(prepend);
180 prepend = ", ";
181 show_symbol(sym);
182 } END_FOR_EACH_PTR(sym);
183 }
184
185 struct type_name {
186 char *start;
187 char *end;
188 };
189
190 static void FORMAT_ATTR(2) prepend(struct type_name *name, const char *fmt, ...)
191 {
192 static char buffer[512];
193 int n;
194
195 va_list args;
196 va_start(args, fmt);
197 n = vsprintf(buffer, fmt, args);
198 va_end(args);
199
200 name->start -= n;
201 memcpy(name->start, buffer, n);
202 }
203
204 static void FORMAT_ATTR(2) append(struct type_name *name, const char *fmt, ...)
205 {
206 static char buffer[512];
207 int n;
208
209 va_list args;
210 va_start(args, fmt);
211 n = vsprintf(buffer, fmt, args);
212 va_end(args);
213
214 memcpy(name->end, buffer, n);
215 name->end += n;
216 }
217
218 static struct ctype_name {
219 struct symbol *sym;
220 const char *name;
221 } typenames[] = {
222 { & char_ctype, "char" },
223 { &schar_ctype, "signed char" },
224 { &uchar_ctype, "unsigned char" },
225 { & short_ctype, "short" },
226 { &sshort_ctype, "signed short" },
227 { &ushort_ctype, "unsigned short" },
228 { & int_ctype, "int" },
229 { &sint_ctype, "signed int" },
230 { &uint_ctype, "unsigned int" },
231 { &slong_ctype, "signed long" },
232 { & long_ctype, "long" },
233 { &ulong_ctype, "unsigned long" },
234 { & llong_ctype, "long long" },
235 { &sllong_ctype, "signed long long" },
236 { &ullong_ctype, "unsigned long long" },
237 { & lllong_ctype, "long long long" },
238 { &slllong_ctype, "signed long long long" },
239 { &ulllong_ctype, "unsigned long long long" },
240
241 { &void_ctype, "void" },
242 { &bool_ctype, "bool" },
243 { &string_ctype, "string" },
244
245 { &float_ctype, "float" },
246 { &double_ctype, "double" },
247 { &ldouble_ctype,"long double" },
248 { &incomplete_ctype, "incomplete type" },
249 { &int_type, "abstract int" },
250 { &fp_type, "abstract fp" },
251 { &label_ctype, "label type" },
252 { &bad_ctype, "bad type" },
253 };
254
255 const char *builtin_typename(struct symbol *sym)
256 {
257 int i;
258
259 for (i = 0; i < ARRAY_SIZE(typenames); i++)
260 if (typenames[i].sym == sym)
261 return typenames[i].name;
262 return NULL;
263 }
264
265 const char *builtin_ctypename(struct ctype *ctype)
266 {
267 int i;
268
269 for (i = 0; i < ARRAY_SIZE(typenames); i++)
270 if (&typenames[i].sym->ctype == ctype)
271 return typenames[i].name;
272 return NULL;
273 }
274
275 static void do_show_type(struct symbol *sym, struct type_name *name)
276 {
277 const char *typename;
278 unsigned long mod = 0;
279 int as = 0;
280 int was_ptr = 0;
281 int restr = 0;
282 int fouled = 0;
283
284 deeper:
285 if (!sym || (sym->type != SYM_NODE && sym->type != SYM_ARRAY &&
286 sym->type != SYM_BITFIELD)) {
287 const char *s;
288 size_t len;
289
290 if (as)
291 prepend(name, "<asn:%d>", as);
292
293 s = modifier_string(mod);
294 len = strlen(s);
295 name->start -= len;
296 memcpy(name->start, s, len);
297 mod = 0;
298 as = 0;
299 }
300
301 if (!sym)
302 goto out;
303
304 if ((typename = builtin_typename(sym))) {
305 int len = strlen(typename);
306 if (name->start != name->end)
307 *--name->start = ' ';
308 name->start -= len;
309 memcpy(name->start, typename, len);
310 goto out;
311 }
312
313 /* Prepend */
314 switch (sym->type) {
315 case SYM_PTR:
316 prepend(name, "*");
317 mod = sym->ctype.modifiers;
318 as = sym->ctype.as;
319 was_ptr = 1;
320 break;
321
322 case SYM_FN:
323 if (was_ptr) {
324 prepend(name, "( ");
325 append(name, " )");
326 was_ptr = 0;
327 }
328 append(name, "( ... )");
329 break;
330
331 case SYM_STRUCT:
332 if (name->start != name->end)
333 *--name->start = ' ';
334 prepend(name, "struct %s", show_ident(sym->ident));
335 goto out;
336
337 case SYM_UNION:
338 if (name->start != name->end)
339 *--name->start = ' ';
340 prepend(name, "union %s", show_ident(sym->ident));
341 goto out;
342
343 case SYM_ENUM:
344 prepend(name, "enum %s ", show_ident(sym->ident));
345 break;
346
347 case SYM_NODE:
348 append(name, "%s", show_ident(sym->ident));
349 mod |= sym->ctype.modifiers;
350 as |= sym->ctype.as;
351 break;
352
353 case SYM_BITFIELD:
354 mod |= sym->ctype.modifiers;
355 as |= sym->ctype.as;
356 append(name, ":%d", sym->bit_size);
357 break;
358
359 case SYM_LABEL:
360 append(name, "label(%s:%p)", show_ident(sym->ident), sym);
361 return;
362
363 case SYM_ARRAY:
364 mod |= sym->ctype.modifiers;
365 as |= sym->ctype.as;
366 if (was_ptr) {
367 prepend(name, "( ");
368 append(name, " )");
369 was_ptr = 0;
370 }
371 append(name, "[%lld]", get_expression_value(sym->array_size));
372 break;
373
374 case SYM_RESTRICT:
375 if (!sym->ident) {
376 restr = 1;
377 break;
378 }
379 if (name->start != name->end)
380 *--name->start = ' ';
381 prepend(name, "restricted %s", show_ident(sym->ident));
382 goto out;
383
384 case SYM_FOULED:
385 fouled = 1;
386 break;
387
388 default:
389 if (name->start != name->end)
390 *--name->start = ' ';
391 prepend(name, "unknown type %d", sym->type);
392 goto out;
393 }
394
395 sym = sym->ctype.base_type;
396 goto deeper;
397
398 out:
399 if (restr)
400 prepend(name, "restricted ");
401 if (fouled)
402 prepend(name, "fouled ");
403 }
404
405 void show_type(struct symbol *sym)
406 {
407 char array[200];
408 struct type_name name;
409
410 name.start = name.end = array+100;
411 do_show_type(sym, &name);
412 *name.end = 0;
413 printf("%s", name.start);
414 }
415
416 const char *show_typename(struct symbol *sym)
417 {
418 static char array[200];
419 struct type_name name;
420
421 name.start = name.end = array+100;
422 do_show_type(sym, &name);
423 *name.end = 0;
424 return name.start;
425 }
426
427 void show_symbol(struct symbol *sym)
428 {
429 struct symbol *type;
430
431 if (!sym)
432 return;
433
434 if (sym->ctype.alignment)
435 printf(".align %ld\n", sym->ctype.alignment);
436
437 show_type(sym);
438 type = sym->ctype.base_type;
439 if (!type) {
440 printf("\n");
441 return;
442 }
443
444 /*
445 * Show actual implementation information
446 */
447 switch (type->type) {
448 struct symbol *member;
449
450 case SYM_STRUCT:
451 case SYM_UNION:
452 printf(" {\n");
453 FOR_EACH_PTR(type->symbol_list, member) {
454 show_struct_member(member);
455 } END_FOR_EACH_PTR(member);
456 printf("}\n");
457 break;
458
459 case SYM_FN: {
460 struct statement *stmt = type->stmt;
461 printf("\n");
462 if (stmt) {
463 int val;
464 val = show_statement(stmt);
465 if (val)
466 printf("\tmov.%d\t\tretval,%d\n", stmt->ret->bit_size, val);
467 printf("\tret\n");
468 }
469 break;
470 }
471
472 default:
473 printf("\n");
474 break;
475 }
476
477 if (sym->initializer) {
478 printf(" = \n");
479 show_expression(sym->initializer);
480 }
481 }
482
483 static int show_symbol_init(struct symbol *sym);
484
485 static int new_pseudo(void)
486 {
487 static int nr = 0;
488 return ++nr;
489 }
490
491 static int new_label(void)
492 {
493 static int label = 0;
494 return ++label;
495 }
496
497 static void show_switch_statement(struct statement *stmt)
498 {
499 int val = show_expression(stmt->switch_expression);
500 struct symbol *sym;
501 printf("\tswitch v%d\n", val);
502
503 /*
504 * Debugging only: Check that the case list is correct
505 * by printing it out.
506 *
507 * This is where a _real_ back-end would go through the
508 * cases to decide whether to use a lookup table or a
509 * series of comparisons etc
510 */
511 printf("# case table:\n");
512 FOR_EACH_PTR(stmt->switch_case->symbol_list, sym) {
513 struct statement *case_stmt = sym->stmt;
514 struct expression *expr = case_stmt->case_expression;
515 struct expression *to = case_stmt->case_to;
516
517 if (!expr) {
518 printf(" default");
519 } else {
520 if (expr->type == EXPR_VALUE) {
521 printf(" case %lld", expr->value);
522 if (to) {
523 if (to->type == EXPR_VALUE) {
524 printf(" .. %lld", to->value);
525 } else {
526 printf(" .. what?");
527 }
528 }
529 } else
530 printf(" what?");
531 }
532 printf(": .L%p\n", sym);
533 } END_FOR_EACH_PTR(sym);
534 printf("# end case table\n");
535
536 show_statement(stmt->switch_statement);
537
538 if (stmt->switch_break->used)
539 printf(".L%p:\n", stmt->switch_break);
540 }
541
542 static void show_symbol_decl(struct symbol_list *syms)
543 {
544 struct symbol *sym;
545 FOR_EACH_PTR(syms, sym) {
546 show_symbol_init(sym);
547 } END_FOR_EACH_PTR(sym);
548 }
549
550 static int show_return_stmt(struct statement *stmt);
551
552 /*
553 * Print out a statement
554 */
555 int show_statement(struct statement *stmt)
556 {
557 if (!stmt)
558 return 0;
559 switch (stmt->type) {
560 case STMT_DECLARATION:
561 show_symbol_decl(stmt->declaration);
562 return 0;
563 case STMT_RETURN:
564 return show_return_stmt(stmt);
565 case STMT_COMPOUND: {
566 struct statement *s;
567 int last = 0;
568
569 if (stmt->inline_fn) {
570 show_statement(stmt->args);
571 printf("\tbegin_inline \t%s\n", show_ident(stmt->inline_fn->ident));
572 }
573 FOR_EACH_PTR(stmt->stmts, s) {
574 last = show_statement(s);
575 } END_FOR_EACH_PTR(s);
576 if (stmt->ret) {
577 int addr, bits;
578 printf(".L%p:\n", stmt->ret);
579 addr = show_symbol_expr(stmt->ret);
580 bits = stmt->ret->bit_size;
581 last = new_pseudo();
582 printf("\tld.%d\t\tv%d,[v%d]\n", bits, last, addr);
583 }
584 if (stmt->inline_fn)
585 printf("\tend_inlined\t%s\n", show_ident(stmt->inline_fn->ident));
586 return last;
587 }
588
589 case STMT_EXPRESSION:
590 return show_expression(stmt->expression);
591 case STMT_IF: {
592 int val, target;
593 struct expression *cond = stmt->if_conditional;
594
595 /* This is only valid if nobody can jump into the "dead" statement */
596 #if 0
597 if (cond->type == EXPR_VALUE) {
598 struct statement *s = stmt->if_true;
599 if (!cond->value)
600 s = stmt->if_false;
601 show_statement(s);
602 break;
603 }
604 #endif
605 val = show_expression(cond);
606 target = new_label();
607 printf("\tje\t\tv%d,.L%d\n", val, target);
608 show_statement(stmt->if_true);
609 if (stmt->if_false) {
610 int last = new_label();
611 printf("\tjmp\t\t.L%d\n", last);
612 printf(".L%d:\n", target);
613 target = last;
614 show_statement(stmt->if_false);
615 }
616 printf(".L%d:\n", target);
617 break;
618 }
619 case STMT_SWITCH:
620 show_switch_statement(stmt);
621 break;
622
623 case STMT_CASE:
624 printf(".L%p:\n", stmt->case_label);
625 show_statement(stmt->case_statement);
626 break;
627
628 case STMT_ITERATOR: {
629 struct statement *pre_statement = stmt->iterator_pre_statement;
630 struct expression *pre_condition = stmt->iterator_pre_condition;
631 struct statement *statement = stmt->iterator_statement;
632 struct statement *post_statement = stmt->iterator_post_statement;
633 struct expression *post_condition = stmt->iterator_post_condition;
634 int val, loop_top = 0, loop_bottom = 0;
635
636 show_symbol_decl(stmt->iterator_syms);
637 show_statement(pre_statement);
638 if (pre_condition) {
639 if (pre_condition->type == EXPR_VALUE) {
640 if (!pre_condition->value) {
641 loop_bottom = new_label();
642 printf("\tjmp\t\t.L%d\n", loop_bottom);
643 }
644 } else {
645 loop_bottom = new_label();
646 val = show_expression(pre_condition);
647 printf("\tje\t\tv%d, .L%d\n", val, loop_bottom);
648 }
649 }
650 if (!post_condition || post_condition->type != EXPR_VALUE || post_condition->value) {
651 loop_top = new_label();
652 printf(".L%d:\n", loop_top);
653 }
654 show_statement(statement);
655 if (stmt->iterator_continue->used)
656 printf(".L%p:\n", stmt->iterator_continue);
657 show_statement(post_statement);
658 if (!post_condition) {
659 printf("\tjmp\t\t.L%d\n", loop_top);
660 } else if (post_condition->type == EXPR_VALUE) {
661 if (post_condition->value)
662 printf("\tjmp\t\t.L%d\n", loop_top);
663 } else {
664 val = show_expression(post_condition);
665 printf("\tjne\t\tv%d, .L%d\n", val, loop_top);
666 }
667 if (stmt->iterator_break->used)
668 printf(".L%p:\n", stmt->iterator_break);
669 if (loop_bottom)
670 printf(".L%d:\n", loop_bottom);
671 break;
672 }
673 case STMT_NONE:
674 break;
675
676 case STMT_LABEL:
677 printf(".L%p:\n", stmt->label_identifier);
678 show_statement(stmt->label_statement);
679 break;
680
681 case STMT_GOTO:
682 if (stmt->goto_expression) {
683 int val = show_expression(stmt->goto_expression);
684 printf("\tgoto\t\t*v%d\n", val);
685 } else {
686 printf("\tgoto\t\t.L%p\n", stmt->goto_label);
687 }
688 break;
689 case STMT_ASM:
690 printf("\tasm( .... )\n");
691 break;
692 case STMT_CONTEXT: {
693 int val = show_expression(stmt->expression);
694 printf("\tcontext( %d )\n", val);
695 break;
696 }
697 case STMT_RANGE: {
698 int val = show_expression(stmt->range_expression);
699 int low = show_expression(stmt->range_low);
700 int high = show_expression(stmt->range_high);
701 printf("\trange( %d %d-%d)\n", val, low, high);
702 break;
703 }
704 }
705 return 0;
706 }
707
708 static int show_call_expression(struct expression *expr)
709 {
710 struct symbol *direct;
711 struct expression *arg, *fn;
712 int fncall, retval;
713 int framesize;
714
715 if (!expr->ctype) {
716 warning(expr->pos, "\tcall with no type!");
717 return 0;
718 }
719
720 framesize = 0;
721 FOR_EACH_PTR_REVERSE(expr->args, arg) {
722 int new = show_expression(arg);
723 int size = arg->ctype->bit_size;
724 printf("\tpush.%d\t\tv%d\n", size, new);
725 framesize += bits_to_bytes(size);
726 } END_FOR_EACH_PTR_REVERSE(arg);
727
728 fn = expr->fn;
729
730 /* Remove dereference, if any */
731 direct = NULL;
732 if (fn->type == EXPR_PREOP) {
733 if (fn->unop->type == EXPR_SYMBOL) {
734 struct symbol *sym = fn->unop->symbol;
735 if (sym->ctype.base_type->type == SYM_FN)
736 direct = sym;
737 }
738 }
739 if (direct) {
740 printf("\tcall\t\t%s\n", show_ident(direct->ident));
741 } else {
742 fncall = show_expression(fn);
743 printf("\tcall\t\t*v%d\n", fncall);
744 }
745 if (framesize)
746 printf("\tadd.%d\t\tvSP,vSP,$%d\n", bits_in_pointer, framesize);
747
748 retval = new_pseudo();
749 printf("\tmov.%d\t\tv%d,retval\n", expr->ctype->bit_size, retval);
750 return retval;
751 }
752
753 static int show_comma(struct expression *expr)
754 {
755 show_expression(expr->left);
756 return show_expression(expr->right);
757 }
758
759 static int show_binop(struct expression *expr)
760 {
761 int left = show_expression(expr->left);
762 int right = show_expression(expr->right);
763 int new = new_pseudo();
764 const char *opname;
765 static const char *name[] = {
766 ['+'] = "add", ['-'] = "sub",
767 ['*'] = "mul", ['/'] = "div",
768 ['%'] = "mod", ['&'] = "and",
769 ['|'] = "lor", ['^'] = "xor"
770 };
771 unsigned int op = expr->op;
772
773 opname = show_special(op);
774 if (op < ARRAY_SIZE(name))
775 opname = name[op];
776 printf("\t%s.%d\t\tv%d,v%d,v%d\n", opname,
777 expr->ctype->bit_size,
778 new, left, right);
779 return new;
780 }
781
782 static int show_slice(struct expression *expr)
783 {
784 int target = show_expression(expr->base);
785 int new = new_pseudo();
786 printf("\tslice.%d\t\tv%d,v%d,%d\n", expr->r_nrbits, target, new, expr->r_bitpos);
787 return new;
788 }
789
790 static int show_regular_preop(struct expression *expr)
791 {
792 int target = show_expression(expr->unop);
793 int new = new_pseudo();
794 static const char *name[] = {
795 ['!'] = "nonzero", ['-'] = "neg",
796 ['~'] = "not",
797 };
798 unsigned int op = expr->op;
799 const char *opname;
800
801 opname = show_special(op);
802 if (op < ARRAY_SIZE(name))
803 opname = name[op];
804 printf("\t%s.%d\t\tv%d,v%d\n", opname, expr->ctype->bit_size, new, target);
805 return new;
806 }
807
808 /*
809 * FIXME! Not all accesses are memory loads. We should
810 * check what kind of symbol is behind the dereference.
811 */
812 static int show_address_gen(struct expression *expr)
813 {
814 return show_expression(expr->unop);
815 }
816
817 static int show_load_gen(int bits, struct expression *expr, int addr)
818 {
819 int new = new_pseudo();
820
821 printf("\tld.%d\t\tv%d,[v%d]\n", bits, new, addr);
822 return new;
823 }
824
825 static void show_store_gen(int bits, int value, struct expression *expr, int addr)
826 {
827 /* FIXME!!! Bitfield store! */
828 printf("\tst.%d\t\tv%d,[v%d]\n", bits, value, addr);
829 }
830
831 static int show_assignment(struct expression *expr)
832 {
833 struct expression *target = expr->left;
834 int val, addr, bits;
835
836 if (!expr->ctype)
837 return 0;
838
839 bits = expr->ctype->bit_size;
840 val = show_expression(expr->right);
841 addr = show_address_gen(target);
842 show_store_gen(bits, val, target, addr);
843 return val;
844 }
845
846 static int show_return_stmt(struct statement *stmt)
847 {
848 struct expression *expr = stmt->ret_value;
849 struct symbol *target = stmt->ret_target;
850
851 if (expr && expr->ctype) {
852 int val = show_expression(expr);
853 int bits = expr->ctype->bit_size;
854 int addr = show_symbol_expr(target);
855 show_store_gen(bits, val, NULL, addr);
856 }
857 printf("\tret\t\t(%p)\n", target);
858 return 0;
859 }
860
861 static int show_initialization(struct symbol *sym, struct expression *expr)
862 {
863 int val, addr, bits;
864
865 if (!expr->ctype)
866 return 0;
867
868 bits = expr->ctype->bit_size;
869 val = show_expression(expr);
870 addr = show_symbol_expr(sym);
871 // FIXME! The "target" expression is for bitfield store information.
872 // Leave it NULL, which works fine.
873 show_store_gen(bits, val, NULL, addr);
874 return 0;
875 }
876
877 static int show_access(struct expression *expr)
878 {
879 int addr = show_address_gen(expr);
880 return show_load_gen(expr->ctype->bit_size, expr, addr);
881 }
882
883 static int show_inc_dec(struct expression *expr, int postop)
884 {
885 int addr = show_address_gen(expr->unop);
886 int retval, new;
887 const char *opname = expr->op == SPECIAL_INCREMENT ? "add" : "sub";
888 int bits = expr->ctype->bit_size;
889
890 retval = show_load_gen(bits, expr->unop, addr);
891 new = retval;
892 if (postop)
893 new = new_pseudo();
894 printf("\t%s.%d\t\tv%d,v%d,$1\n", opname, bits, new, retval);
895 show_store_gen(bits, new, expr->unop, addr);
896 return retval;
897 }
898
899 static int show_preop(struct expression *expr)
900 {
901 /*
902 * '*' is an lvalue access, and is fundamentally different
903 * from an arithmetic operation. Maybe it should have an
904 * expression type of its own..
905 */
906 if (expr->op == '*')
907 return show_access(expr);
908 if (expr->op == SPECIAL_INCREMENT || expr->op == SPECIAL_DECREMENT)
909 return show_inc_dec(expr, 0);
910 return show_regular_preop(expr);
911 }
912
913 static int show_postop(struct expression *expr)
914 {
915 return show_inc_dec(expr, 1);
916 }
917
918 static int show_symbol_expr(struct symbol *sym)
919 {
920 int new = new_pseudo();
921
922 if (sym->initializer && sym->initializer->type == EXPR_STRING)
923 return show_string_expr(sym->initializer);
924
925 if (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_EXTERN | MOD_STATIC)) {
926 printf("\tmovi.%d\t\tv%d,$%s\n", bits_in_pointer, new, show_ident(sym->ident));
927 return new;
928 }
929 if (sym->ctype.modifiers & MOD_ADDRESSABLE) {
930 printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer, new, sym->value);
931 return new;
932 }
933 printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer, new, show_ident(sym->ident), sym);
934 return new;
935 }
936
937 static int show_symbol_init(struct symbol *sym)
938 {
939 struct expression *expr = sym->initializer;
940
941 if (expr) {
942 int val, addr, bits;
943
944 bits = expr->ctype->bit_size;
945 val = show_expression(expr);
946 addr = show_symbol_expr(sym);
947 show_store_gen(bits, val, NULL, addr);
948 }
949 return 0;
950 }
951
952 static int type_is_signed(struct symbol *sym)
953 {
954 if (sym->type == SYM_NODE)
955 sym = sym->ctype.base_type;
956 if (sym->type == SYM_PTR)
957 return 0;
958 return !(sym->ctype.modifiers & MOD_UNSIGNED);
959 }
960
961 static int show_cast_expr(struct expression *expr)
962 {
963 struct symbol *old_type, *new_type;
964 int op = show_expression(expr->cast_expression);
965 int oldbits, newbits;
966 int new, is_signed;
967
968 old_type = expr->cast_expression->ctype;
969 new_type = expr->cast_type;
970
971 oldbits = old_type->bit_size;
972 newbits = new_type->bit_size;
973 if (oldbits >= newbits)
974 return op;
975 new = new_pseudo();
976 is_signed = type_is_signed(old_type);
977 if (is_signed) {
978 printf("\tsext%d.%d\tv%d,v%d\n", oldbits, newbits, new, op);
979 } else {
980 printf("\tandl.%d\t\tv%d,v%d,$%lu\n", newbits, new, op, (1UL << oldbits)-1);
981 }
982 return new;
983 }
984
985 static int show_value(struct expression *expr)
986 {
987 int new = new_pseudo();
988 unsigned long long value = expr->value;
989
990 printf("\tmovi.%d\t\tv%d,$%llu\n", expr->ctype->bit_size, new, value);
991 return new;
992 }
993
994 static int show_fvalue(struct expression *expr)
995 {
996 int new = new_pseudo();
997 long double value = expr->fvalue;
998
999 printf("\tmovf.%d\t\tv%d,$%Lf\n", expr->ctype->bit_size, new, value);
1000 return new;
1001 }
1002
1003 static int show_string_expr(struct expression *expr)
1004 {
1005 int new = new_pseudo();
1006
1007 printf("\tmovi.%d\t\tv%d,&%s\n", bits_in_pointer, new, show_string(expr->string));
1008 return new;
1009 }
1010
1011 static int show_label_expr(struct expression *expr)
1012 {
1013 int new = new_pseudo();
1014 printf("\tmovi.%d\t\tv%d,.L%p\n",bits_in_pointer, new, expr->label_symbol);
1015 return new;
1016 }
1017
1018 static int show_conditional_expr(struct expression *expr)
1019 {
1020 int cond = show_expression(expr->conditional);
1021 int true = show_expression(expr->cond_true);
1022 int false = show_expression(expr->cond_false);
1023 int new = new_pseudo();
1024
1025 printf("[v%d]\tcmov.%d\t\tv%d,v%d,v%d\n", cond, expr->ctype->bit_size, new, true, false);
1026 return new;
1027 }
1028
1029 static int show_statement_expr(struct expression *expr)
1030 {
1031 return show_statement(expr->statement);
1032 }
1033
1034 static int show_position_expr(struct expression *expr, struct symbol *base)
1035 {
1036 int new = show_expression(expr->init_expr);
1037 struct symbol *ctype = expr->init_expr->ctype;
1038 int bit_offset;
1039
1040 bit_offset = ctype ? ctype->bit_offset : -1;
1041
1042 printf("\tinsert v%d at [%d:%d] of %s\n", new,
1043 expr->init_offset, bit_offset,
1044 show_ident(base->ident));
1045 return 0;
1046 }
1047
1048 static int show_initializer_expr(struct expression *expr, struct symbol *ctype)
1049 {
1050 struct expression *entry;
1051
1052 FOR_EACH_PTR(expr->expr_list, entry) {
1053
1054 again:
1055 // Nested initializers have their positions already
1056 // recursively calculated - just output them too
1057 if (entry->type == EXPR_INITIALIZER) {
1058 show_initializer_expr(entry, ctype);
1059 continue;
1060 }
1061
1062 // Initializer indexes and identifiers should
1063 // have been evaluated to EXPR_POS
1064 if (entry->type == EXPR_IDENTIFIER) {
1065 printf(" AT '%s':\n", show_ident(entry->expr_ident));
1066 entry = entry->ident_expression;
1067 goto again;
1068 }
1069
1070 if (entry->type == EXPR_INDEX) {
1071 printf(" AT '%d..%d:\n", entry->idx_from, entry->idx_to);
1072 entry = entry->idx_expression;
1073 goto again;
1074 }
1075 if (entry->type == EXPR_POS) {
1076 show_position_expr(entry, ctype);
1077 continue;
1078 }
1079 show_initialization(ctype, entry);
1080 } END_FOR_EACH_PTR(entry);
1081 return 0;
1082 }
1083
1084 int show_symbol_expr_init(struct symbol *sym)
1085 {
1086 struct expression *expr = sym->initializer;
1087
1088 if (expr)
1089 show_expression(expr);
1090 return show_symbol_expr(sym);
1091 }
1092
1093 /*
1094 * Print out an expression. Return the pseudo that contains the
1095 * variable.
1096 */
1097 int show_expression(struct expression *expr)
1098 {
1099 if (!expr)
1100 return 0;
1101
1102 if (!expr->ctype) {
1103 struct position *pos = &expr->pos;
1104 printf("\tno type at %s:%d:%d\n",
1105 stream_name(pos->stream),
1106 pos->line, pos->pos);
1107 return 0;
1108 }
1109
1110 switch (expr->type) {
1111 case EXPR_CALL:
1112 return show_call_expression(expr);
1113
1114 case EXPR_ASSIGNMENT:
1115 return show_assignment(expr);
1116
1117 case EXPR_COMMA:
1118 return show_comma(expr);
1119 case EXPR_BINOP:
1120 case EXPR_COMPARE:
1121 case EXPR_LOGICAL:
1122 return show_binop(expr);
1123 case EXPR_PREOP:
1124 return show_preop(expr);
1125 case EXPR_POSTOP:
1126 return show_postop(expr);
1127 case EXPR_SYMBOL:
1128 return show_symbol_expr(expr->symbol);
1129 case EXPR_DEREF:
1130 case EXPR_SIZEOF:
1131 case EXPR_PTRSIZEOF:
1132 case EXPR_ALIGNOF:
1133 case EXPR_OFFSETOF:
1134 warning(expr->pos, "invalid expression after evaluation");
1135 return 0;
1136 case EXPR_CAST:
1137 case EXPR_FORCE_CAST:
1138 case EXPR_IMPLIED_CAST:
1139 return show_cast_expr(expr);
1140 case EXPR_VALUE:
1141 return show_value(expr);
1142 case EXPR_FVALUE:
1143 return show_fvalue(expr);
1144 case EXPR_STRING:
1145 return show_string_expr(expr);
1146 case EXPR_INITIALIZER:
1147 return show_initializer_expr(expr, expr->ctype);
1148 case EXPR_SELECT:
1149 case EXPR_CONDITIONAL:
1150 return show_conditional_expr(expr);
1151 case EXPR_STATEMENT:
1152 return show_statement_expr(expr);
1153 case EXPR_LABEL:
1154 return show_label_expr(expr);
1155 case EXPR_SLICE:
1156 return show_slice(expr);
1157
1158 // None of these should exist as direct expressions: they are only
1159 // valid as sub-expressions of initializers.
1160 case EXPR_POS:
1161 warning(expr->pos, "unable to show plain initializer position expression");
1162 return 0;
1163 case EXPR_IDENTIFIER:
1164 warning(expr->pos, "unable to show identifier expression");
1165 return 0;
1166 case EXPR_INDEX:
1167 warning(expr->pos, "unable to show index expression");
1168 return 0;
1169 case EXPR_TYPE:
1170 warning(expr->pos, "unable to show type expression");
1171 return 0;
1172 }
1173 return 0;
1174 }