bogus_address_param: warn about passing a bogus address
[smatch.git] / show-parse.c
blobe2fc18bb4b3dd009e5229f0859da9a622cf71c9c
1 /*
2 * sparse/show-parse.c
4 * Copyright (C) 2003 Transmeta Corp.
5 * 2003-2004 Linus Torvalds
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:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
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.
25 * Print out results of parsing for debugging and testing.
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>
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"
44 static int show_symbol_expr(struct symbol *sym);
45 static int show_string_expr(struct expression *expr);
47 static void do_debug_symbol(struct symbol *sym, int indent)
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_TYPEOF] = "tpof",
62 [SYM_BITFIELD] = "bitf",
63 [SYM_LABEL] = "labl",
64 [SYM_RESTRICT] = "rstr",
65 [SYM_FOULED] = "foul",
66 [SYM_BAD] = "bad.",
68 struct context *context;
69 int i;
71 if (!sym)
72 return;
73 fprintf(stderr, "%.*s%s%3d:%lu %s%s (as: %s) %p (%s:%d:%d) %s\n",
74 indent, indent_string, typestr[sym->type],
75 sym->bit_size, sym->ctype.alignment,
76 modifier_string(sym->ctype.modifiers), show_ident(sym->ident),
77 show_as(sym->ctype.as),
78 sym, stream_name(sym->pos.stream), sym->pos.line, sym->pos.pos,
79 builtin_typename(sym) ?: "");
80 i = 0;
81 FOR_EACH_PTR(sym->ctype.contexts, context) {
82 /* FIXME: should print context expression */
83 fprintf(stderr, "< context%d: in=%d, out=%d\n",
84 i, context->in, context->out);
85 fprintf(stderr, " end context%d >\n", i);
86 i++;
87 } END_FOR_EACH_PTR(context);
88 if (sym->type == SYM_FN) {
89 struct symbol *arg;
90 i = 0;
91 FOR_EACH_PTR(sym->arguments, arg) {
92 fprintf(stderr, "< arg%d:\n", i);
93 do_debug_symbol(arg, 0);
94 fprintf(stderr, " end arg%d >\n", i);
95 i++;
96 } END_FOR_EACH_PTR(arg);
98 do_debug_symbol(sym->ctype.base_type, indent+2);
101 void debug_symbol(struct symbol *sym)
103 do_debug_symbol(sym, 0);
107 * Symbol type printout. The type system is by far the most
108 * complicated part of C - everything else is trivial.
110 static const char *show_modifiers(unsigned long mod, int term)
112 static char buffer[100];
113 int len = 0;
114 int i;
115 struct mod_name {
116 unsigned long mod;
117 const char *name;
118 } *m;
120 static struct mod_name mod_names[] = {
121 {MOD_AUTO, "auto"},
122 {MOD_EXTERN, "extern"},
123 {MOD_REGISTER, "register"},
124 {MOD_STATIC, "static"},
125 {MOD_INLINE, "inline"},
126 {MOD_CONST, "const"},
127 {MOD_RESTRICT, "restrict"},
128 {MOD_VOLATILE, "volatile"},
129 {MOD_ADDRESSABLE, "[addressable]"},
130 {MOD_ASSIGNED, "[assigned]"},
131 {MOD_ATOMIC, "[atomic]"},
132 {MOD_BITWISE, "[bitwise]"},
133 {MOD_EXPLICITLY_SIGNED, "[explicitly-signed]"},
134 {MOD_GNU_INLINE, "[gnu_inline]"},
135 {MOD_NOCAST, "[nocast]"},
136 {MOD_NODEREF, "[noderef]"},
137 {MOD_NORETURN, "[noreturn]"},
138 {MOD_PURE, "[pure]"},
139 {MOD_SAFE, "[safe]"},
140 {MOD_SIGNED, "[signed]"},
141 {MOD_TLS, "[tls]"},
142 {MOD_TOPLEVEL, "[toplevel]"},
143 {MOD_UNSIGNED, "[unsigned]"},
144 {MOD_UNUSED, "[unused]"},
145 {MOD_USERTYPE, "[usertype]"},
148 for (i = 0; i < ARRAY_SIZE(mod_names); i++) {
149 m = mod_names + i;
150 if (mod & m->mod) {
151 char c;
152 const char *name = m->name;
153 while ((c = *name++) != '\0' && len + 2 < sizeof buffer)
154 buffer[len++] = c;
155 buffer[len++] = ' ';
158 if (len && !term) // strip the trailing space
159 --len;
160 buffer[len] = 0;
161 return buffer;
165 // show the modifiers, terminated by a space if not empty
166 const char *modifier_string(unsigned long mod)
168 return show_modifiers(mod, 1);
172 // show the modifiers, without an ending space
173 const char *modifier_name(unsigned long mod)
175 return show_modifiers(mod, 0);
178 static void show_struct_member(struct symbol *sym)
180 printf("\t%s:%d:%ld at offset %ld.%d", show_ident(sym->ident), sym->bit_size, sym->ctype.alignment, sym->offset, sym->bit_offset);
181 printf("\n");
184 void show_symbol_list(struct symbol_list *list)
186 struct symbol *sym;
187 const char *prepend = "";
189 FOR_EACH_PTR(list, sym) {
190 puts(prepend);
191 prepend = ", ";
192 show_symbol(sym);
193 } END_FOR_EACH_PTR(sym);
196 const char *show_as(struct ident *as)
198 if (!as)
199 return "";
200 return show_ident(as);
203 struct type_name {
204 char *start;
205 char *end;
208 static void FORMAT_ATTR(2) prepend(struct type_name *name, const char *fmt, ...)
210 static char buffer[512];
211 int n;
213 va_list args;
214 va_start(args, fmt);
215 n = vsprintf(buffer, fmt, args);
216 va_end(args);
218 name->start -= n;
219 memcpy(name->start, buffer, n);
222 static void FORMAT_ATTR(2) append(struct type_name *name, const char *fmt, ...)
224 static char buffer[512];
225 int n;
227 va_list args;
228 va_start(args, fmt);
229 n = vsprintf(buffer, fmt, args);
230 va_end(args);
232 memcpy(name->end, buffer, n);
233 name->end += n;
236 static struct ctype_name {
237 struct symbol *sym;
238 const char *name;
239 const char *suffix;
240 } typenames[] = {
241 { & char_ctype, "char", "" },
242 { &schar_ctype, "signed char", "" },
243 { &uchar_ctype, "unsigned char", "" },
244 { & short_ctype, "short", "" },
245 { &sshort_ctype, "signed short", "" },
246 { &ushort_ctype, "unsigned short", "" },
247 { & int_ctype, "int", "" },
248 { &sint_ctype, "signed int", "" },
249 { &uint_ctype, "unsigned int", "U" },
250 { & long_ctype, "long", "L" },
251 { &slong_ctype, "signed long", "L" },
252 { &ulong_ctype, "unsigned long", "UL" },
253 { & llong_ctype, "long long", "LL" },
254 { &sllong_ctype, "signed long long", "LL" },
255 { &ullong_ctype, "unsigned long long", "ULL" },
256 { & int128_ctype, "__int128", "" },
257 { &sint128_ctype, "signed __int128", "" },
258 { &uint128_ctype, "unsigned __int128", "" },
260 { &void_ctype, "void", "" },
261 { &bool_ctype, "bool", "" },
263 { &float_ctype, "float", "F" },
264 { &double_ctype, "double", "" },
265 { &ldouble_ctype,"long double", "L" },
266 { &incomplete_ctype, "incomplete type", "" },
267 { &int_type, "abstract int", "" },
268 { &fp_type, "abstract fp", "" },
269 { &label_ctype, "label type", "" },
270 { &bad_ctype, "bad type", "" },
273 const char *builtin_typename(struct symbol *sym)
275 int i;
277 for (i = 0; i < ARRAY_SIZE(typenames); i++)
278 if (typenames[i].sym == sym)
279 return typenames[i].name;
280 return NULL;
283 const char *builtin_type_suffix(struct symbol *sym)
285 int i;
287 for (i = 0; i < ARRAY_SIZE(typenames); i++)
288 if (typenames[i].sym == sym)
289 return typenames[i].suffix;
290 return NULL;
293 const char *builtin_ctypename(struct ctype *ctype)
295 int i;
297 for (i = 0; i < ARRAY_SIZE(typenames); i++)
298 if (&typenames[i].sym->ctype == ctype)
299 return typenames[i].name;
300 return NULL;
303 static void do_show_type(struct symbol *sym, struct type_name *name)
305 const char *typename;
306 unsigned long mod = 0;
307 struct ident *as = NULL;
308 int was_ptr = 0;
309 int restr = 0;
310 int fouled = 0;
312 deeper:
313 if (sym && (sym->type != SYM_NODE && sym->type != SYM_ARRAY &&
314 sym->type != SYM_BITFIELD)) {
315 const char *s;
316 size_t len;
318 if (as)
319 prepend(name, "%s ", show_as(as));
321 if (sym && (sym->type == SYM_BASETYPE || sym->type == SYM_ENUM))
322 mod &= ~MOD_SPECIFIER;
323 s = modifier_string(mod);
324 len = strlen(s);
325 name->start -= len;
326 memcpy(name->start, s, len);
327 mod = 0;
328 as = NULL;
331 if (!sym)
332 goto out;
334 if ((typename = builtin_typename(sym))) {
335 int len = strlen(typename);
336 if (name->start != name->end)
337 *--name->start = ' ';
338 name->start -= len;
339 memcpy(name->start, typename, len);
340 goto out;
343 /* Prepend */
344 switch (sym->type) {
345 case SYM_PTR:
346 prepend(name, "*");
347 mod = sym->ctype.modifiers;
348 as = sym->ctype.as;
349 was_ptr = 1;
350 examine_pointer_target(sym);
351 break;
353 case SYM_FN:
354 if (was_ptr) {
355 prepend(name, "( ");
356 append(name, " )");
357 was_ptr = 0;
359 append(name, "( ... )");
360 break;
362 case SYM_STRUCT:
363 if (name->start != name->end)
364 *--name->start = ' ';
365 prepend(name, "struct %s", show_ident(sym->ident));
366 goto out;
368 case SYM_UNION:
369 if (name->start != name->end)
370 *--name->start = ' ';
371 prepend(name, "union %s", show_ident(sym->ident));
372 goto out;
374 case SYM_ENUM:
375 prepend(name, "enum %s ", show_ident(sym->ident));
376 break;
378 case SYM_NODE:
379 if (sym->ident)
380 append(name, "%s", show_ident(sym->ident));
381 mod |= sym->ctype.modifiers;
382 combine_address_space(sym->pos, &as, sym->ctype.as);
383 break;
385 case SYM_BITFIELD:
386 mod |= sym->ctype.modifiers;
387 combine_address_space(sym->pos, &as, sym->ctype.as);
388 append(name, ":%d", sym->bit_size);
389 break;
391 case SYM_LABEL:
392 append(name, "label(%s:%p)", show_ident(sym->ident), sym);
393 return;
395 case SYM_ARRAY:
396 mod |= sym->ctype.modifiers;
397 combine_address_space(sym->pos, &as, sym->ctype.as);
398 if (was_ptr) {
399 prepend(name, "( ");
400 append(name, " )");
401 was_ptr = 0;
403 append(name, "[%lld]", get_expression_value(sym->array_size));
404 break;
406 case SYM_RESTRICT:
407 if (!sym->ident) {
408 restr = 1;
409 break;
411 if (name->start != name->end)
412 *--name->start = ' ';
413 prepend(name, "restricted %s", show_ident(sym->ident));
414 goto out;
416 case SYM_FOULED:
417 fouled = 1;
418 break;
420 default:
421 if (name->start != name->end)
422 *--name->start = ' ';
423 prepend(name, "unknown type %d", sym->type);
424 goto out;
427 sym = sym->ctype.base_type;
428 goto deeper;
430 out:
431 if (restr)
432 prepend(name, "restricted ");
433 if (fouled)
434 prepend(name, "fouled ");
436 // strip trailing space
437 if (name->end > name->start && name->end[-1] == ' ')
438 name->end--;
441 void show_type(struct symbol *sym)
443 char array[200];
444 struct type_name name;
446 name.start = name.end = array+100;
447 do_show_type(sym, &name);
448 *name.end = 0;
449 printf("%s", name.start);
452 const char *show_typename(struct symbol *sym)
454 static char array[200];
455 struct type_name name;
457 name.start = name.end = array+100;
458 do_show_type(sym, &name);
459 *name.end = 0;
460 return name.start;
463 void show_symbol(struct symbol *sym)
465 struct symbol *type;
467 if (!sym)
468 return;
470 if (sym->ctype.alignment)
471 printf(".align %ld\n", sym->ctype.alignment);
473 show_type(sym);
474 type = sym->ctype.base_type;
475 if (!type) {
476 printf("\n");
477 return;
481 * Show actual implementation information
483 switch (type->type) {
484 struct symbol *member;
486 case SYM_STRUCT:
487 case SYM_UNION:
488 printf(" {\n");
489 FOR_EACH_PTR(type->symbol_list, member) {
490 show_struct_member(member);
491 } END_FOR_EACH_PTR(member);
492 printf("}\n");
493 break;
495 case SYM_FN: {
496 struct statement *stmt = type->stmt;
497 printf("\n");
498 if (stmt) {
499 int val;
500 val = show_statement(stmt);
501 if (val)
502 printf("\tmov.%d\t\tretval,%d\n", stmt->ret->bit_size, val);
503 printf("\tret\n");
505 break;
508 default:
509 printf("\n");
510 break;
513 if (sym->initializer) {
514 printf(" = \n");
515 show_expression(sym->initializer);
519 static int show_symbol_init(struct symbol *sym);
521 static int new_pseudo(void)
523 static int nr = 0;
524 return ++nr;
527 static int new_label(void)
529 static int label = 0;
530 return ++label;
533 static void show_switch_statement(struct statement *stmt)
535 int val = show_expression(stmt->switch_expression);
536 struct symbol *sym;
537 printf("\tswitch v%d\n", val);
540 * Debugging only: Check that the case list is correct
541 * by printing it out.
543 * This is where a _real_ back-end would go through the
544 * cases to decide whether to use a lookup table or a
545 * series of comparisons etc
547 printf("# case table:\n");
548 FOR_EACH_PTR(stmt->switch_case->symbol_list, sym) {
549 struct statement *case_stmt = sym->stmt;
550 struct expression *expr = case_stmt->case_expression;
551 struct expression *to = case_stmt->case_to;
553 if (!expr) {
554 printf(" default");
555 } else {
556 if (expr->type == EXPR_VALUE) {
557 printf(" case %lld", expr->value);
558 if (to) {
559 if (to->type == EXPR_VALUE) {
560 printf(" .. %lld", to->value);
561 } else {
562 printf(" .. what?");
565 } else
566 printf(" what?");
568 printf(": .L%p\n", sym);
569 } END_FOR_EACH_PTR(sym);
570 printf("# end case table\n");
572 show_statement(stmt->switch_statement);
574 if (stmt->switch_break->used)
575 printf(".L%p:\n", stmt->switch_break);
578 static void show_symbol_decl(struct symbol_list *syms)
580 struct symbol *sym;
581 FOR_EACH_PTR(syms, sym) {
582 show_symbol_init(sym);
583 } END_FOR_EACH_PTR(sym);
586 static int show_return_stmt(struct statement *stmt);
589 * Print out a statement
591 int show_statement(struct statement *stmt)
593 if (!stmt)
594 return 0;
595 switch (stmt->type) {
596 case STMT_DECLARATION:
597 show_symbol_decl(stmt->declaration);
598 return 0;
599 case STMT_RETURN:
600 return show_return_stmt(stmt);
601 case STMT_COMPOUND: {
602 struct statement *s;
603 int last = 0;
605 if (stmt->inline_fn) {
606 show_statement(stmt->args);
607 printf("\tbegin_inline \t%s\n", show_ident(stmt->inline_fn->ident));
609 FOR_EACH_PTR(stmt->stmts, s) {
610 last = show_statement(s);
611 } END_FOR_EACH_PTR(s);
612 if (stmt->ret) {
613 int addr, bits;
614 printf(".L%p:\n", stmt->ret);
615 addr = show_symbol_expr(stmt->ret);
616 bits = stmt->ret->bit_size;
617 last = new_pseudo();
618 printf("\tld.%d\t\tv%d,[v%d]\n", bits, last, addr);
620 if (stmt->inline_fn)
621 printf("\tend_inlined\t%s\n", show_ident(stmt->inline_fn->ident));
622 return last;
625 case STMT_EXPRESSION:
626 return show_expression(stmt->expression);
627 case STMT_IF: {
628 int val, target;
629 struct expression *cond = stmt->if_conditional;
631 /* This is only valid if nobody can jump into the "dead" statement */
632 #if 0
633 if (cond->type == EXPR_VALUE) {
634 struct statement *s = stmt->if_true;
635 if (!cond->value)
636 s = stmt->if_false;
637 show_statement(s);
638 break;
640 #endif
641 val = show_expression(cond);
642 target = new_label();
643 printf("\tje\t\tv%d,.L%d\n", val, target);
644 show_statement(stmt->if_true);
645 if (stmt->if_false) {
646 int last = new_label();
647 printf("\tjmp\t\t.L%d\n", last);
648 printf(".L%d:\n", target);
649 target = last;
650 show_statement(stmt->if_false);
652 printf(".L%d:\n", target);
653 break;
655 case STMT_SWITCH:
656 show_switch_statement(stmt);
657 break;
659 case STMT_CASE:
660 printf(".L%p:\n", stmt->case_label);
661 show_statement(stmt->case_statement);
662 break;
664 case STMT_ITERATOR: {
665 struct statement *pre_statement = stmt->iterator_pre_statement;
666 struct expression *pre_condition = stmt->iterator_pre_condition;
667 struct statement *statement = stmt->iterator_statement;
668 struct statement *post_statement = stmt->iterator_post_statement;
669 struct expression *post_condition = stmt->iterator_post_condition;
670 int val, loop_top = 0, loop_bottom = 0;
672 show_symbol_decl(stmt->iterator_syms);
673 show_statement(pre_statement);
674 if (pre_condition) {
675 if (pre_condition->type == EXPR_VALUE) {
676 if (!pre_condition->value) {
677 loop_bottom = new_label();
678 printf("\tjmp\t\t.L%d\n", loop_bottom);
680 } else {
681 loop_bottom = new_label();
682 val = show_expression(pre_condition);
683 printf("\tje\t\tv%d, .L%d\n", val, loop_bottom);
686 if (!post_condition || post_condition->type != EXPR_VALUE || post_condition->value) {
687 loop_top = new_label();
688 printf(".L%d:\n", loop_top);
690 show_statement(statement);
691 if (stmt->iterator_continue->used)
692 printf(".L%p:\n", stmt->iterator_continue);
693 show_statement(post_statement);
694 if (!post_condition) {
695 printf("\tjmp\t\t.L%d\n", loop_top);
696 } else if (post_condition->type == EXPR_VALUE) {
697 if (post_condition->value)
698 printf("\tjmp\t\t.L%d\n", loop_top);
699 } else {
700 val = show_expression(post_condition);
701 printf("\tjne\t\tv%d, .L%d\n", val, loop_top);
703 if (stmt->iterator_break->used)
704 printf(".L%p:\n", stmt->iterator_break);
705 if (loop_bottom)
706 printf(".L%d:\n", loop_bottom);
707 break;
709 case STMT_NONE:
710 break;
712 case STMT_LABEL:
713 printf(".L%p:\n", stmt->label_identifier);
714 show_statement(stmt->label_statement);
715 break;
717 case STMT_GOTO:
718 if (stmt->goto_expression) {
719 int val = show_expression(stmt->goto_expression);
720 printf("\tgoto\t\t*v%d\n", val);
721 } else {
722 printf("\tgoto\t\t.L%p\n", stmt->goto_label);
724 break;
725 case STMT_ASM:
726 printf("\tasm( .... )\n");
727 break;
728 case STMT_CONTEXT: {
729 int val = show_expression(stmt->expression);
730 printf("\tcontext( %d )\n", val);
731 break;
733 case STMT_RANGE: {
734 int val = show_expression(stmt->range_expression);
735 int low = show_expression(stmt->range_low);
736 int high = show_expression(stmt->range_high);
737 printf("\trange( %d %d-%d)\n", val, low, high);
738 break;
741 return 0;
744 static int show_call_expression(struct expression *expr)
746 struct symbol *direct;
747 struct expression *arg, *fn;
748 int fncall, retval;
749 int framesize;
751 if (!expr->ctype) {
752 warning(expr->pos, "\tcall with no type!");
753 return 0;
756 framesize = 0;
757 FOR_EACH_PTR_REVERSE(expr->args, arg) {
758 int new = show_expression(arg);
759 int size = arg->ctype->bit_size;
760 printf("\tpush.%d\t\tv%d\n", size, new);
761 framesize += bits_to_bytes(size);
762 } END_FOR_EACH_PTR_REVERSE(arg);
764 fn = expr->fn;
766 /* Remove dereference, if any */
767 direct = NULL;
768 if (fn->type == EXPR_PREOP) {
769 if (fn->unop->type == EXPR_SYMBOL) {
770 struct symbol *sym = fn->unop->symbol;
771 if (sym->ctype.base_type->type == SYM_FN)
772 direct = sym;
775 if (direct) {
776 printf("\tcall\t\t%s\n", show_ident(direct->ident));
777 } else {
778 fncall = show_expression(fn);
779 printf("\tcall\t\t*v%d\n", fncall);
781 if (framesize)
782 printf("\tadd.%d\t\tvSP,vSP,$%d\n", bits_in_pointer, framesize);
784 retval = new_pseudo();
785 printf("\tmov.%d\t\tv%d,retval\n", expr->ctype->bit_size, retval);
786 return retval;
789 static int show_comma(struct expression *expr)
791 show_expression(expr->left);
792 return show_expression(expr->right);
795 static int show_binop(struct expression *expr)
797 int left = show_expression(expr->left);
798 int right = show_expression(expr->right);
799 int new = new_pseudo();
800 const char *opname;
801 static const char *name[] = {
802 ['+'] = "add", ['-'] = "sub",
803 ['*'] = "mul", ['/'] = "div",
804 ['%'] = "mod", ['&'] = "and",
805 ['|'] = "lor", ['^'] = "xor"
807 unsigned int op = expr->op;
809 opname = show_special(op);
810 if (op < ARRAY_SIZE(name))
811 opname = name[op];
812 printf("\t%s.%d\t\tv%d,v%d,v%d\n", opname,
813 expr->ctype->bit_size,
814 new, left, right);
815 return new;
818 static int show_slice(struct expression *expr)
820 int target = show_expression(expr->base);
821 int new = new_pseudo();
822 printf("\tslice.%d\t\tv%d,v%d,%d\n", expr->ctype->bit_size, target, new, expr->r_bitpos);
823 return new;
826 static int show_regular_preop(struct expression *expr)
828 int target = show_expression(expr->unop);
829 int new = new_pseudo();
830 static const char *name[] = {
831 ['!'] = "nonzero", ['-'] = "neg",
832 ['~'] = "not",
834 unsigned int op = expr->op;
835 const char *opname;
837 opname = show_special(op);
838 if (op < ARRAY_SIZE(name))
839 opname = name[op];
840 printf("\t%s.%d\t\tv%d,v%d\n", opname, expr->ctype->bit_size, new, target);
841 return new;
845 * FIXME! Not all accesses are memory loads. We should
846 * check what kind of symbol is behind the dereference.
848 static int show_address_gen(struct expression *expr)
850 return show_expression(expr->unop);
853 static int show_load_gen(int bits, struct expression *expr, int addr)
855 int new = new_pseudo();
857 printf("\tld.%d\t\tv%d,[v%d]\n", bits, new, addr);
858 return new;
861 static void show_store_gen(int bits, int value, struct expression *expr, int addr)
863 /* FIXME!!! Bitfield store! */
864 printf("\tst.%d\t\tv%d,[v%d]\n", bits, value, addr);
867 static int show_assignment(struct expression *expr)
869 struct expression *target = expr->left;
870 int val, addr, bits;
872 if (!expr->ctype)
873 return 0;
875 bits = expr->ctype->bit_size;
876 val = show_expression(expr->right);
877 addr = show_address_gen(target);
878 show_store_gen(bits, val, target, addr);
879 return val;
882 static int show_return_stmt(struct statement *stmt)
884 struct expression *expr = stmt->ret_value;
885 struct symbol *target = stmt->ret_target;
887 if (expr && expr->ctype) {
888 int val = show_expression(expr);
889 int bits = expr->ctype->bit_size;
890 int addr = show_symbol_expr(target);
891 show_store_gen(bits, val, NULL, addr);
893 printf("\tret\t\t(%p)\n", target);
894 return 0;
897 static int show_initialization(struct symbol *sym, struct expression *expr)
899 int val, addr, bits;
901 if (!expr->ctype)
902 return 0;
904 bits = expr->ctype->bit_size;
905 val = show_expression(expr);
906 addr = show_symbol_expr(sym);
907 // FIXME! The "target" expression is for bitfield store information.
908 // Leave it NULL, which works fine.
909 show_store_gen(bits, val, NULL, addr);
910 return 0;
913 static int show_access(struct expression *expr)
915 int addr = show_address_gen(expr);
916 return show_load_gen(expr->ctype->bit_size, expr, addr);
919 static int show_inc_dec(struct expression *expr, int postop)
921 int addr = show_address_gen(expr->unop);
922 int retval, new;
923 const char *opname = expr->op == SPECIAL_INCREMENT ? "add" : "sub";
924 int bits = expr->ctype->bit_size;
926 retval = show_load_gen(bits, expr->unop, addr);
927 new = retval;
928 if (postop)
929 new = new_pseudo();
930 printf("\t%s.%d\t\tv%d,v%d,$1\n", opname, bits, new, retval);
931 show_store_gen(bits, new, expr->unop, addr);
932 return retval;
935 static int show_preop(struct expression *expr)
938 * '*' is an lvalue access, and is fundamentally different
939 * from an arithmetic operation. Maybe it should have an
940 * expression type of its own..
942 if (expr->op == '*')
943 return show_access(expr);
944 if (expr->op == SPECIAL_INCREMENT || expr->op == SPECIAL_DECREMENT)
945 return show_inc_dec(expr, 0);
946 return show_regular_preop(expr);
949 static int show_postop(struct expression *expr)
951 return show_inc_dec(expr, 1);
954 static int show_symbol_expr(struct symbol *sym)
956 int new = new_pseudo();
958 if (sym->initializer && sym->initializer->type == EXPR_STRING)
959 return show_string_expr(sym->initializer);
961 if (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_EXTERN | MOD_STATIC)) {
962 printf("\tmovi.%d\t\tv%d,$%s\n", bits_in_pointer, new, show_ident(sym->ident));
963 return new;
965 if (sym->ctype.modifiers & MOD_ADDRESSABLE) {
966 printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer, new, 0LL);
967 return new;
969 printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer, new, show_ident(sym->ident), sym);
970 return new;
973 static int show_symbol_init(struct symbol *sym)
975 struct expression *expr = sym->initializer;
977 if (expr) {
978 int val, addr, bits;
980 bits = expr->ctype->bit_size;
981 val = show_expression(expr);
982 addr = show_symbol_expr(sym);
983 show_store_gen(bits, val, NULL, addr);
985 return 0;
988 static int show_cast_expr(struct expression *expr)
990 struct symbol *old_type, *new_type;
991 int op = show_expression(expr->cast_expression);
992 int oldbits, newbits;
993 int new, is_signed;
995 old_type = expr->cast_expression->ctype;
996 new_type = expr->cast_type;
998 oldbits = old_type->bit_size;
999 newbits = new_type->bit_size;
1000 if (oldbits >= newbits)
1001 return op;
1002 new = new_pseudo();
1003 is_signed = is_signed_type(old_type);
1004 if (is_signed) {
1005 printf("\tsext%d.%d\tv%d,v%d\n", oldbits, newbits, new, op);
1006 } else {
1007 printf("\tandl.%d\t\tv%d,v%d,$%lu\n", newbits, new, op, (1UL << oldbits)-1);
1009 return new;
1012 static int show_value(struct expression *expr)
1014 int new = new_pseudo();
1015 unsigned long long value = expr->value;
1017 printf("\tmovi.%d\t\tv%d,$%llu\n", expr->ctype->bit_size, new, value);
1018 return new;
1021 static int show_fvalue(struct expression *expr)
1023 int new = new_pseudo();
1024 long double value = expr->fvalue;
1026 printf("\tmovf.%d\t\tv%d,$%Le\n", expr->ctype->bit_size, new, value);
1027 return new;
1030 static int show_string_expr(struct expression *expr)
1032 int new = new_pseudo();
1034 printf("\tmovi.%d\t\tv%d,&%s\n", bits_in_pointer, new, show_string(expr->string));
1035 return new;
1038 static int show_label_expr(struct expression *expr)
1040 int new = new_pseudo();
1041 printf("\tmovi.%d\t\tv%d,.L%p\n",bits_in_pointer, new, expr->label_symbol);
1042 return new;
1045 static int show_conditional_expr(struct expression *expr)
1047 int cond = show_expression(expr->conditional);
1048 int valt = show_expression(expr->cond_true);
1049 int valf = show_expression(expr->cond_false);
1050 int new = new_pseudo();
1052 printf("[v%d]\tcmov.%d\t\tv%d,v%d,v%d\n", cond, expr->ctype->bit_size, new, valt, valf);
1053 return new;
1056 static int show_statement_expr(struct expression *expr)
1058 return show_statement(expr->statement);
1061 static int show_position_expr(struct expression *expr, struct symbol *base)
1063 int new = show_expression(expr->init_expr);
1064 struct symbol *ctype = expr->init_expr->ctype;
1065 int bit_offset;
1067 bit_offset = ctype ? ctype->bit_offset : -1;
1069 printf("\tinsert v%d at [%d:%d] of %s\n", new,
1070 expr->init_offset, bit_offset,
1071 show_ident(base->ident));
1072 return 0;
1075 static int show_initializer_expr(struct expression *expr, struct symbol *ctype)
1077 struct expression *entry;
1079 FOR_EACH_PTR(expr->expr_list, entry) {
1081 again:
1082 // Nested initializers have their positions already
1083 // recursively calculated - just output them too
1084 if (entry->type == EXPR_INITIALIZER) {
1085 show_initializer_expr(entry, ctype);
1086 continue;
1089 // Initializer indexes and identifiers should
1090 // have been evaluated to EXPR_POS
1091 if (entry->type == EXPR_IDENTIFIER) {
1092 printf(" AT '%s':\n", show_ident(entry->expr_ident));
1093 entry = entry->ident_expression;
1094 goto again;
1097 if (entry->type == EXPR_INDEX) {
1098 printf(" AT '%d..%d:\n", entry->idx_from, entry->idx_to);
1099 entry = entry->idx_expression;
1100 goto again;
1102 if (entry->type == EXPR_POS) {
1103 show_position_expr(entry, ctype);
1104 continue;
1106 show_initialization(ctype, entry);
1107 } END_FOR_EACH_PTR(entry);
1108 return 0;
1111 int show_symbol_expr_init(struct symbol *sym)
1113 struct expression *expr = sym->initializer;
1115 if (expr)
1116 show_expression(expr);
1117 return show_symbol_expr(sym);
1121 * Print out an expression. Return the pseudo that contains the
1122 * variable.
1124 int show_expression(struct expression *expr)
1126 if (!expr)
1127 return 0;
1129 if (!expr->ctype) {
1130 struct position *pos = &expr->pos;
1131 printf("\tno type at %s:%d:%d\n",
1132 stream_name(pos->stream),
1133 pos->line, pos->pos);
1134 return 0;
1137 switch (expr->type) {
1138 case EXPR_CALL:
1139 return show_call_expression(expr);
1141 case EXPR_ASSIGNMENT:
1142 return show_assignment(expr);
1144 case EXPR_COMMA:
1145 return show_comma(expr);
1146 case EXPR_BINOP:
1147 case EXPR_COMPARE:
1148 case EXPR_LOGICAL:
1149 return show_binop(expr);
1150 case EXPR_PREOP:
1151 return show_preop(expr);
1152 case EXPR_POSTOP:
1153 return show_postop(expr);
1154 case EXPR_SYMBOL:
1155 return show_symbol_expr(expr->symbol);
1156 case EXPR_DEREF:
1157 case EXPR_SIZEOF:
1158 case EXPR_PTRSIZEOF:
1159 case EXPR_ALIGNOF:
1160 case EXPR_OFFSETOF:
1161 warning(expr->pos, "invalid expression after evaluation");
1162 return 0;
1163 case EXPR_CAST:
1164 case EXPR_FORCE_CAST:
1165 case EXPR_IMPLIED_CAST:
1166 return show_cast_expr(expr);
1167 case EXPR_VALUE:
1168 return show_value(expr);
1169 case EXPR_FVALUE:
1170 return show_fvalue(expr);
1171 case EXPR_STRING:
1172 return show_string_expr(expr);
1173 case EXPR_INITIALIZER:
1174 return show_initializer_expr(expr, expr->ctype);
1175 case EXPR_SELECT:
1176 case EXPR_CONDITIONAL:
1177 return show_conditional_expr(expr);
1178 case EXPR_STATEMENT:
1179 return show_statement_expr(expr);
1180 case EXPR_LABEL:
1181 return show_label_expr(expr);
1182 case EXPR_SLICE:
1183 return show_slice(expr);
1185 // None of these should exist as direct expressions: they are only
1186 // valid as sub-expressions of initializers.
1187 case EXPR_POS:
1188 warning(expr->pos, "unable to show plain initializer position expression");
1189 return 0;
1190 case EXPR_IDENTIFIER:
1191 warning(expr->pos, "unable to show identifier expression");
1192 return 0;
1193 case EXPR_INDEX:
1194 warning(expr->pos, "unable to show index expression");
1195 return 0;
1196 case EXPR_TYPE:
1197 warning(expr->pos, "unable to show type expression");
1198 return 0;
1199 case EXPR_GENERIC:
1200 warning(expr->pos, "unable to show generic expression");
1201 return 0;
1203 return 0;