buf_size: fix handling of unknown flexible array sizes
[smatch.git] / show-parse.c
blob3aa06e47cf8f15320788004d8b1653b3a857de8d
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_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.",
70 struct context *context;
71 int i;
73 if (!sym)
74 return;
75 fprintf(stderr, "%.*s%s%3d:%lu %s %s (as: %s) %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),
79 show_as(sym->ctype.as),
80 sym, stream_name(sym->pos.stream), sym->pos.line, sym->pos.pos,
81 builtin_typename(sym) ?: "");
82 i = 0;
83 FOR_EACH_PTR(sym->ctype.contexts, context) {
84 /* FIXME: should print context expression */
85 fprintf(stderr, "< context%d: in=%d, out=%d\n",
86 i, context->in, context->out);
87 fprintf(stderr, " end context%d >\n", i);
88 i++;
89 } END_FOR_EACH_PTR(context);
90 if (sym->type == SYM_FN) {
91 struct symbol *arg;
92 i = 0;
93 FOR_EACH_PTR(sym->arguments, arg) {
94 fprintf(stderr, "< arg%d:\n", i);
95 do_debug_symbol(arg, 0);
96 fprintf(stderr, " end arg%d >\n", i);
97 i++;
98 } END_FOR_EACH_PTR(arg);
100 do_debug_symbol(sym->ctype.base_type, indent+2);
103 void debug_symbol(struct symbol *sym)
105 do_debug_symbol(sym, 0);
109 * Symbol type printout. The type system is by far the most
110 * complicated part of C - everything else is trivial.
112 const char *modifier_string(unsigned long mod)
114 static char buffer[100];
115 int len = 0;
116 int i;
117 struct mod_name {
118 unsigned long mod;
119 const char *name;
120 } *m;
122 static struct mod_name mod_names[] = {
123 {MOD_AUTO, "auto"},
124 {MOD_REGISTER, "register"},
125 {MOD_STATIC, "static"},
126 {MOD_EXTERN, "extern"},
127 {MOD_CONST, "const"},
128 {MOD_VOLATILE, "volatile"},
129 {MOD_RESTRICT, "restrict"},
130 {MOD_ATOMIC, "[atomic]"},
131 {MOD_SIGNED, "[signed]"},
132 {MOD_UNSIGNED, "[unsigned]"},
133 {MOD_CHAR, "[char]"},
134 {MOD_SHORT, "[short]"},
135 {MOD_LONG, "[long]"},
136 {MOD_LONGLONG, "[long long]"},
137 {MOD_LONGLONGLONG, "[long long long]"},
138 {MOD_TLS, "[tls]"},
139 {MOD_INLINE, "inline"},
140 {MOD_ADDRESSABLE, "[addressable]"},
141 {MOD_NOCAST, "[nocast]"},
142 {MOD_NODEREF, "[noderef]"},
143 {MOD_TOPLEVEL, "[toplevel]"},
144 {MOD_ASSIGNED, "[assigned]"},
145 {MOD_TYPE, "[type]"},
146 {MOD_SAFE, "[safe]"},
147 {MOD_USERTYPE, "[usertype]"},
148 {MOD_NORETURN, "[noreturn]"},
149 {MOD_EXPLICITLY_SIGNED, "[explicitly-signed]"},
150 {MOD_BITWISE, "[bitwise]"},
151 {MOD_PURE, "[pure]"},
154 for (i = 0; i < ARRAY_SIZE(mod_names); i++) {
155 m = mod_names + i;
156 if (mod & m->mod) {
157 char c;
158 const char *name = m->name;
159 while ((c = *name++) != '\0' && len + 2 < sizeof buffer)
160 buffer[len++] = c;
161 buffer[len++] = ' ';
164 buffer[len] = 0;
165 return buffer;
168 static void show_struct_member(struct symbol *sym)
170 printf("\t%s:%d:%ld at offset %ld.%d", show_ident(sym->ident), sym->bit_size, sym->ctype.alignment, sym->offset, sym->bit_offset);
171 printf("\n");
174 void show_symbol_list(struct symbol_list *list, const char *sep)
176 struct symbol *sym;
177 const char *prepend = "";
179 FOR_EACH_PTR(list, sym) {
180 puts(prepend);
181 prepend = ", ";
182 show_symbol(sym);
183 } END_FOR_EACH_PTR(sym);
186 const char *show_as(struct ident *as)
188 if (!as)
189 return "";
190 return show_ident(as);
193 struct type_name {
194 char *start;
195 char *end;
198 static void FORMAT_ATTR(2) prepend(struct type_name *name, const char *fmt, ...)
200 static char buffer[512];
201 int n;
203 va_list args;
204 va_start(args, fmt);
205 n = vsprintf(buffer, fmt, args);
206 va_end(args);
208 name->start -= n;
209 memcpy(name->start, buffer, n);
212 static void FORMAT_ATTR(2) append(struct type_name *name, const char *fmt, ...)
214 static char buffer[512];
215 int n;
217 va_list args;
218 va_start(args, fmt);
219 n = vsprintf(buffer, fmt, args);
220 va_end(args);
222 memcpy(name->end, buffer, n);
223 name->end += n;
226 static struct ctype_name {
227 struct symbol *sym;
228 const char *name;
229 const char *suffix;
230 } typenames[] = {
231 { & char_ctype, "char", "" },
232 { &schar_ctype, "signed char", "" },
233 { &uchar_ctype, "unsigned char", "" },
234 { & short_ctype, "short", "" },
235 { &sshort_ctype, "signed short", "" },
236 { &ushort_ctype, "unsigned short", "" },
237 { & int_ctype, "int", "" },
238 { &sint_ctype, "signed int", "" },
239 { &uint_ctype, "unsigned int", "U" },
240 { & long_ctype, "long", "L" },
241 { &slong_ctype, "signed long", "L" },
242 { &ulong_ctype, "unsigned long", "UL" },
243 { & llong_ctype, "long long", "LL" },
244 { &sllong_ctype, "signed long long", "LL" },
245 { &ullong_ctype, "unsigned long long", "ULL" },
246 { & lllong_ctype, "long long long", "LLL" },
247 { &slllong_ctype, "signed long long long", "LLL" },
248 { &ulllong_ctype, "unsigned long long long", "ULLL" },
250 { &void_ctype, "void", "" },
251 { &bool_ctype, "bool", "" },
253 { &float_ctype, "float", "F" },
254 { &double_ctype, "double", "" },
255 { &ldouble_ctype,"long double", "L" },
256 { &incomplete_ctype, "incomplete type", "" },
257 { &int_type, "abstract int", "" },
258 { &fp_type, "abstract fp", "" },
259 { &label_ctype, "label type", "" },
260 { &bad_ctype, "bad type", "" },
263 const char *builtin_typename(struct symbol *sym)
265 int i;
267 for (i = 0; i < ARRAY_SIZE(typenames); i++)
268 if (typenames[i].sym == sym)
269 return typenames[i].name;
270 return NULL;
273 const char *builtin_type_suffix(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].suffix;
280 return NULL;
283 const char *builtin_ctypename(struct ctype *ctype)
285 int i;
287 for (i = 0; i < ARRAY_SIZE(typenames); i++)
288 if (&typenames[i].sym->ctype == ctype)
289 return typenames[i].name;
290 return NULL;
293 static void do_show_type(struct symbol *sym, struct type_name *name)
295 const char *typename;
296 unsigned long mod = 0;
297 struct ident *as = NULL;
298 int was_ptr = 0;
299 int restr = 0;
300 int fouled = 0;
302 deeper:
303 if (!sym || (sym->type != SYM_NODE && sym->type != SYM_ARRAY &&
304 sym->type != SYM_BITFIELD)) {
305 const char *s;
306 size_t len;
308 if (as)
309 prepend(name, "%s ", show_as(as));
311 if (sym->type == SYM_BASETYPE || sym->type == SYM_ENUM)
312 mod &= ~MOD_SPECIFIER;
313 s = modifier_string(mod);
314 len = strlen(s);
315 name->start -= len;
316 memcpy(name->start, s, len);
317 mod = 0;
318 as = NULL;
321 if (!sym)
322 goto out;
324 if ((typename = builtin_typename(sym))) {
325 int len = strlen(typename);
326 if (name->start != name->end)
327 *--name->start = ' ';
328 name->start -= len;
329 memcpy(name->start, typename, len);
330 goto out;
333 /* Prepend */
334 switch (sym->type) {
335 case SYM_PTR:
336 prepend(name, "*");
337 mod = sym->ctype.modifiers;
338 as = sym->ctype.as;
339 was_ptr = 1;
340 break;
342 case SYM_FN:
343 if (was_ptr) {
344 prepend(name, "( ");
345 append(name, " )");
346 was_ptr = 0;
348 append(name, "( ... )");
349 break;
351 case SYM_STRUCT:
352 if (name->start != name->end)
353 *--name->start = ' ';
354 prepend(name, "struct %s", show_ident(sym->ident));
355 goto out;
357 case SYM_UNION:
358 if (name->start != name->end)
359 *--name->start = ' ';
360 prepend(name, "union %s", show_ident(sym->ident));
361 goto out;
363 case SYM_ENUM:
364 prepend(name, "enum %s ", show_ident(sym->ident));
365 break;
367 case SYM_NODE:
368 if (sym->ident)
369 append(name, "%s", show_ident(sym->ident));
370 mod |= sym->ctype.modifiers;
371 combine_address_space(sym->pos, &as, sym->ctype.as);
372 break;
374 case SYM_BITFIELD:
375 mod |= sym->ctype.modifiers;
376 combine_address_space(sym->pos, &as, sym->ctype.as);
377 append(name, ":%d", sym->bit_size);
378 break;
380 case SYM_LABEL:
381 append(name, "label(%s:%p)", show_ident(sym->ident), sym);
382 return;
384 case SYM_ARRAY:
385 mod |= sym->ctype.modifiers;
386 combine_address_space(sym->pos, &as, sym->ctype.as);
387 if (was_ptr) {
388 prepend(name, "( ");
389 append(name, " )");
390 was_ptr = 0;
392 append(name, "[%lld]", get_expression_value(sym->array_size));
393 break;
395 case SYM_RESTRICT:
396 if (!sym->ident) {
397 restr = 1;
398 break;
400 if (name->start != name->end)
401 *--name->start = ' ';
402 prepend(name, "restricted %s", show_ident(sym->ident));
403 goto out;
405 case SYM_FOULED:
406 fouled = 1;
407 break;
409 default:
410 if (name->start != name->end)
411 *--name->start = ' ';
412 prepend(name, "unknown type %d", sym->type);
413 goto out;
416 sym = sym->ctype.base_type;
417 goto deeper;
419 out:
420 if (restr)
421 prepend(name, "restricted ");
422 if (fouled)
423 prepend(name, "fouled ");
425 // strip trailing space
426 if (name->end > name->start && name->end[-1] == ' ')
427 name->end--;
430 void show_type(struct symbol *sym)
432 char array[200];
433 struct type_name name;
435 name.start = name.end = array+100;
436 do_show_type(sym, &name);
437 *name.end = 0;
438 printf("%s", name.start);
441 const char *show_typename(struct symbol *sym)
443 static 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 return name.start;
452 void show_symbol(struct symbol *sym)
454 struct symbol *type;
456 if (!sym)
457 return;
459 if (sym->ctype.alignment)
460 printf(".align %ld\n", sym->ctype.alignment);
462 show_type(sym);
463 type = sym->ctype.base_type;
464 if (!type) {
465 printf("\n");
466 return;
470 * Show actual implementation information
472 switch (type->type) {
473 struct symbol *member;
475 case SYM_STRUCT:
476 case SYM_UNION:
477 printf(" {\n");
478 FOR_EACH_PTR(type->symbol_list, member) {
479 show_struct_member(member);
480 } END_FOR_EACH_PTR(member);
481 printf("}\n");
482 break;
484 case SYM_FN: {
485 struct statement *stmt = type->stmt;
486 printf("\n");
487 if (stmt) {
488 int val;
489 val = show_statement(stmt);
490 if (val)
491 printf("\tmov.%d\t\tretval,%d\n", stmt->ret->bit_size, val);
492 printf("\tret\n");
494 break;
497 default:
498 printf("\n");
499 break;
502 if (sym->initializer) {
503 printf(" = \n");
504 show_expression(sym->initializer);
508 static int show_symbol_init(struct symbol *sym);
510 static int new_pseudo(void)
512 static int nr = 0;
513 return ++nr;
516 static int new_label(void)
518 static int label = 0;
519 return ++label;
522 static void show_switch_statement(struct statement *stmt)
524 int val = show_expression(stmt->switch_expression);
525 struct symbol *sym;
526 printf("\tswitch v%d\n", val);
529 * Debugging only: Check that the case list is correct
530 * by printing it out.
532 * This is where a _real_ back-end would go through the
533 * cases to decide whether to use a lookup table or a
534 * series of comparisons etc
536 printf("# case table:\n");
537 FOR_EACH_PTR(stmt->switch_case->symbol_list, sym) {
538 struct statement *case_stmt = sym->stmt;
539 struct expression *expr = case_stmt->case_expression;
540 struct expression *to = case_stmt->case_to;
542 if (!expr) {
543 printf(" default");
544 } else {
545 if (expr->type == EXPR_VALUE) {
546 printf(" case %lld", expr->value);
547 if (to) {
548 if (to->type == EXPR_VALUE) {
549 printf(" .. %lld", to->value);
550 } else {
551 printf(" .. what?");
554 } else
555 printf(" what?");
557 printf(": .L%p\n", sym);
558 } END_FOR_EACH_PTR(sym);
559 printf("# end case table\n");
561 show_statement(stmt->switch_statement);
563 if (stmt->switch_break->used)
564 printf(".L%p:\n", stmt->switch_break);
567 static void show_symbol_decl(struct symbol_list *syms)
569 struct symbol *sym;
570 FOR_EACH_PTR(syms, sym) {
571 show_symbol_init(sym);
572 } END_FOR_EACH_PTR(sym);
575 static int show_return_stmt(struct statement *stmt);
578 * Print out a statement
580 int show_statement(struct statement *stmt)
582 if (!stmt)
583 return 0;
584 switch (stmt->type) {
585 case STMT_DECLARATION:
586 show_symbol_decl(stmt->declaration);
587 return 0;
588 case STMT_RETURN:
589 return show_return_stmt(stmt);
590 case STMT_COMPOUND: {
591 struct statement *s;
592 int last = 0;
594 if (stmt->inline_fn) {
595 show_statement(stmt->args);
596 printf("\tbegin_inline \t%s\n", show_ident(stmt->inline_fn->ident));
598 FOR_EACH_PTR(stmt->stmts, s) {
599 last = show_statement(s);
600 } END_FOR_EACH_PTR(s);
601 if (stmt->ret) {
602 int addr, bits;
603 printf(".L%p:\n", stmt->ret);
604 addr = show_symbol_expr(stmt->ret);
605 bits = stmt->ret->bit_size;
606 last = new_pseudo();
607 printf("\tld.%d\t\tv%d,[v%d]\n", bits, last, addr);
609 if (stmt->inline_fn)
610 printf("\tend_inlined\t%s\n", show_ident(stmt->inline_fn->ident));
611 return last;
614 case STMT_EXPRESSION:
615 return show_expression(stmt->expression);
616 case STMT_IF: {
617 int val, target;
618 struct expression *cond = stmt->if_conditional;
620 /* This is only valid if nobody can jump into the "dead" statement */
621 #if 0
622 if (cond->type == EXPR_VALUE) {
623 struct statement *s = stmt->if_true;
624 if (!cond->value)
625 s = stmt->if_false;
626 show_statement(s);
627 break;
629 #endif
630 val = show_expression(cond);
631 target = new_label();
632 printf("\tje\t\tv%d,.L%d\n", val, target);
633 show_statement(stmt->if_true);
634 if (stmt->if_false) {
635 int last = new_label();
636 printf("\tjmp\t\t.L%d\n", last);
637 printf(".L%d:\n", target);
638 target = last;
639 show_statement(stmt->if_false);
641 printf(".L%d:\n", target);
642 break;
644 case STMT_SWITCH:
645 show_switch_statement(stmt);
646 break;
648 case STMT_CASE:
649 printf(".L%p:\n", stmt->case_label);
650 show_statement(stmt->case_statement);
651 break;
653 case STMT_ITERATOR: {
654 struct statement *pre_statement = stmt->iterator_pre_statement;
655 struct expression *pre_condition = stmt->iterator_pre_condition;
656 struct statement *statement = stmt->iterator_statement;
657 struct statement *post_statement = stmt->iterator_post_statement;
658 struct expression *post_condition = stmt->iterator_post_condition;
659 int val, loop_top = 0, loop_bottom = 0;
661 show_symbol_decl(stmt->iterator_syms);
662 show_statement(pre_statement);
663 if (pre_condition) {
664 if (pre_condition->type == EXPR_VALUE) {
665 if (!pre_condition->value) {
666 loop_bottom = new_label();
667 printf("\tjmp\t\t.L%d\n", loop_bottom);
669 } else {
670 loop_bottom = new_label();
671 val = show_expression(pre_condition);
672 printf("\tje\t\tv%d, .L%d\n", val, loop_bottom);
675 if (!post_condition || post_condition->type != EXPR_VALUE || post_condition->value) {
676 loop_top = new_label();
677 printf(".L%d:\n", loop_top);
679 show_statement(statement);
680 if (stmt->iterator_continue->used)
681 printf(".L%p:\n", stmt->iterator_continue);
682 show_statement(post_statement);
683 if (!post_condition) {
684 printf("\tjmp\t\t.L%d\n", loop_top);
685 } else if (post_condition->type == EXPR_VALUE) {
686 if (post_condition->value)
687 printf("\tjmp\t\t.L%d\n", loop_top);
688 } else {
689 val = show_expression(post_condition);
690 printf("\tjne\t\tv%d, .L%d\n", val, loop_top);
692 if (stmt->iterator_break->used)
693 printf(".L%p:\n", stmt->iterator_break);
694 if (loop_bottom)
695 printf(".L%d:\n", loop_bottom);
696 break;
698 case STMT_NONE:
699 break;
701 case STMT_LABEL:
702 printf(".L%p:\n", stmt->label_identifier);
703 show_statement(stmt->label_statement);
704 break;
706 case STMT_GOTO:
707 if (stmt->goto_expression) {
708 int val = show_expression(stmt->goto_expression);
709 printf("\tgoto\t\t*v%d\n", val);
710 } else {
711 printf("\tgoto\t\t.L%p\n", stmt->goto_label);
713 break;
714 case STMT_ASM:
715 printf("\tasm( .... )\n");
716 break;
717 case STMT_CONTEXT: {
718 int val = show_expression(stmt->expression);
719 printf("\tcontext( %d )\n", val);
720 break;
722 case STMT_RANGE: {
723 int val = show_expression(stmt->range_expression);
724 int low = show_expression(stmt->range_low);
725 int high = show_expression(stmt->range_high);
726 printf("\trange( %d %d-%d)\n", val, low, high);
727 break;
730 return 0;
733 static int show_call_expression(struct expression *expr)
735 struct symbol *direct;
736 struct expression *arg, *fn;
737 int fncall, retval;
738 int framesize;
740 if (!expr->ctype) {
741 warning(expr->pos, "\tcall with no type!");
742 return 0;
745 framesize = 0;
746 FOR_EACH_PTR_REVERSE(expr->args, arg) {
747 int new = show_expression(arg);
748 int size = arg->ctype->bit_size;
749 printf("\tpush.%d\t\tv%d\n", size, new);
750 framesize += bits_to_bytes(size);
751 } END_FOR_EACH_PTR_REVERSE(arg);
753 fn = expr->fn;
755 /* Remove dereference, if any */
756 direct = NULL;
757 if (fn->type == EXPR_PREOP) {
758 if (fn->unop->type == EXPR_SYMBOL) {
759 struct symbol *sym = fn->unop->symbol;
760 if (sym->ctype.base_type->type == SYM_FN)
761 direct = sym;
764 if (direct) {
765 printf("\tcall\t\t%s\n", show_ident(direct->ident));
766 } else {
767 fncall = show_expression(fn);
768 printf("\tcall\t\t*v%d\n", fncall);
770 if (framesize)
771 printf("\tadd.%d\t\tvSP,vSP,$%d\n", bits_in_pointer, framesize);
773 retval = new_pseudo();
774 printf("\tmov.%d\t\tv%d,retval\n", expr->ctype->bit_size, retval);
775 return retval;
778 static int show_comma(struct expression *expr)
780 show_expression(expr->left);
781 return show_expression(expr->right);
784 static int show_binop(struct expression *expr)
786 int left = show_expression(expr->left);
787 int right = show_expression(expr->right);
788 int new = new_pseudo();
789 const char *opname;
790 static const char *name[] = {
791 ['+'] = "add", ['-'] = "sub",
792 ['*'] = "mul", ['/'] = "div",
793 ['%'] = "mod", ['&'] = "and",
794 ['|'] = "lor", ['^'] = "xor"
796 unsigned int op = expr->op;
798 opname = show_special(op);
799 if (op < ARRAY_SIZE(name))
800 opname = name[op];
801 printf("\t%s.%d\t\tv%d,v%d,v%d\n", opname,
802 expr->ctype->bit_size,
803 new, left, right);
804 return new;
807 static int show_slice(struct expression *expr)
809 int target = show_expression(expr->base);
810 int new = new_pseudo();
811 printf("\tslice.%d\t\tv%d,v%d,%d\n", expr->r_nrbits, target, new, expr->r_bitpos);
812 return new;
815 static int show_regular_preop(struct expression *expr)
817 int target = show_expression(expr->unop);
818 int new = new_pseudo();
819 static const char *name[] = {
820 ['!'] = "nonzero", ['-'] = "neg",
821 ['~'] = "not",
823 unsigned int op = expr->op;
824 const char *opname;
826 opname = show_special(op);
827 if (op < ARRAY_SIZE(name))
828 opname = name[op];
829 printf("\t%s.%d\t\tv%d,v%d\n", opname, expr->ctype->bit_size, new, target);
830 return new;
834 * FIXME! Not all accesses are memory loads. We should
835 * check what kind of symbol is behind the dereference.
837 static int show_address_gen(struct expression *expr)
839 return show_expression(expr->unop);
842 static int show_load_gen(int bits, struct expression *expr, int addr)
844 int new = new_pseudo();
846 printf("\tld.%d\t\tv%d,[v%d]\n", bits, new, addr);
847 return new;
850 static void show_store_gen(int bits, int value, struct expression *expr, int addr)
852 /* FIXME!!! Bitfield store! */
853 printf("\tst.%d\t\tv%d,[v%d]\n", bits, value, addr);
856 static int show_assignment(struct expression *expr)
858 struct expression *target = expr->left;
859 int val, addr, bits;
861 if (!expr->ctype)
862 return 0;
864 bits = expr->ctype->bit_size;
865 val = show_expression(expr->right);
866 addr = show_address_gen(target);
867 show_store_gen(bits, val, target, addr);
868 return val;
871 static int show_return_stmt(struct statement *stmt)
873 struct expression *expr = stmt->ret_value;
874 struct symbol *target = stmt->ret_target;
876 if (expr && expr->ctype) {
877 int val = show_expression(expr);
878 int bits = expr->ctype->bit_size;
879 int addr = show_symbol_expr(target);
880 show_store_gen(bits, val, NULL, addr);
882 printf("\tret\t\t(%p)\n", target);
883 return 0;
886 static int show_initialization(struct symbol *sym, struct expression *expr)
888 int val, addr, bits;
890 if (!expr->ctype)
891 return 0;
893 bits = expr->ctype->bit_size;
894 val = show_expression(expr);
895 addr = show_symbol_expr(sym);
896 // FIXME! The "target" expression is for bitfield store information.
897 // Leave it NULL, which works fine.
898 show_store_gen(bits, val, NULL, addr);
899 return 0;
902 static int show_access(struct expression *expr)
904 int addr = show_address_gen(expr);
905 return show_load_gen(expr->ctype->bit_size, expr, addr);
908 static int show_inc_dec(struct expression *expr, int postop)
910 int addr = show_address_gen(expr->unop);
911 int retval, new;
912 const char *opname = expr->op == SPECIAL_INCREMENT ? "add" : "sub";
913 int bits = expr->ctype->bit_size;
915 retval = show_load_gen(bits, expr->unop, addr);
916 new = retval;
917 if (postop)
918 new = new_pseudo();
919 printf("\t%s.%d\t\tv%d,v%d,$1\n", opname, bits, new, retval);
920 show_store_gen(bits, new, expr->unop, addr);
921 return retval;
924 static int show_preop(struct expression *expr)
927 * '*' is an lvalue access, and is fundamentally different
928 * from an arithmetic operation. Maybe it should have an
929 * expression type of its own..
931 if (expr->op == '*')
932 return show_access(expr);
933 if (expr->op == SPECIAL_INCREMENT || expr->op == SPECIAL_DECREMENT)
934 return show_inc_dec(expr, 0);
935 return show_regular_preop(expr);
938 static int show_postop(struct expression *expr)
940 return show_inc_dec(expr, 1);
943 static int show_symbol_expr(struct symbol *sym)
945 int new = new_pseudo();
947 if (sym->initializer && sym->initializer->type == EXPR_STRING)
948 return show_string_expr(sym->initializer);
950 if (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_EXTERN | MOD_STATIC)) {
951 printf("\tmovi.%d\t\tv%d,$%s\n", bits_in_pointer, new, show_ident(sym->ident));
952 return new;
954 if (sym->ctype.modifiers & MOD_ADDRESSABLE) {
955 printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer, new, 0LL);
956 return new;
958 printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer, new, show_ident(sym->ident), sym);
959 return new;
962 static int show_symbol_init(struct symbol *sym)
964 struct expression *expr = sym->initializer;
966 if (expr) {
967 int val, addr, bits;
969 bits = expr->ctype->bit_size;
970 val = show_expression(expr);
971 addr = show_symbol_expr(sym);
972 show_store_gen(bits, val, NULL, addr);
974 return 0;
977 static int show_cast_expr(struct expression *expr)
979 struct symbol *old_type, *new_type;
980 int op = show_expression(expr->cast_expression);
981 int oldbits, newbits;
982 int new, is_signed;
984 old_type = expr->cast_expression->ctype;
985 new_type = expr->cast_type;
987 oldbits = old_type->bit_size;
988 newbits = new_type->bit_size;
989 if (oldbits >= newbits)
990 return op;
991 new = new_pseudo();
992 is_signed = is_signed_type(old_type);
993 if (is_signed) {
994 printf("\tsext%d.%d\tv%d,v%d\n", oldbits, newbits, new, op);
995 } else {
996 printf("\tandl.%d\t\tv%d,v%d,$%lu\n", newbits, new, op, (1UL << oldbits)-1);
998 return new;
1001 static int show_value(struct expression *expr)
1003 int new = new_pseudo();
1004 unsigned long long value = expr->value;
1006 printf("\tmovi.%d\t\tv%d,$%llu\n", expr->ctype->bit_size, new, value);
1007 return new;
1010 static int show_fvalue(struct expression *expr)
1012 int new = new_pseudo();
1013 long double value = expr->fvalue;
1015 printf("\tmovf.%d\t\tv%d,$%Le\n", expr->ctype->bit_size, new, value);
1016 return new;
1019 static int show_string_expr(struct expression *expr)
1021 int new = new_pseudo();
1023 printf("\tmovi.%d\t\tv%d,&%s\n", bits_in_pointer, new, show_string(expr->string));
1024 return new;
1027 static int show_label_expr(struct expression *expr)
1029 int new = new_pseudo();
1030 printf("\tmovi.%d\t\tv%d,.L%p\n",bits_in_pointer, new, expr->label_symbol);
1031 return new;
1034 static int show_conditional_expr(struct expression *expr)
1036 int cond = show_expression(expr->conditional);
1037 int valt = show_expression(expr->cond_true);
1038 int valf = show_expression(expr->cond_false);
1039 int new = new_pseudo();
1041 printf("[v%d]\tcmov.%d\t\tv%d,v%d,v%d\n", cond, expr->ctype->bit_size, new, valt, valf);
1042 return new;
1045 static int show_statement_expr(struct expression *expr)
1047 return show_statement(expr->statement);
1050 static int show_position_expr(struct expression *expr, struct symbol *base)
1052 int new = show_expression(expr->init_expr);
1053 struct symbol *ctype = expr->init_expr->ctype;
1054 int bit_offset;
1056 bit_offset = ctype ? ctype->bit_offset : -1;
1058 printf("\tinsert v%d at [%d:%d] of %s\n", new,
1059 expr->init_offset, bit_offset,
1060 show_ident(base->ident));
1061 return 0;
1064 static int show_initializer_expr(struct expression *expr, struct symbol *ctype)
1066 struct expression *entry;
1068 FOR_EACH_PTR(expr->expr_list, entry) {
1070 again:
1071 // Nested initializers have their positions already
1072 // recursively calculated - just output them too
1073 if (entry->type == EXPR_INITIALIZER) {
1074 show_initializer_expr(entry, ctype);
1075 continue;
1078 // Initializer indexes and identifiers should
1079 // have been evaluated to EXPR_POS
1080 if (entry->type == EXPR_IDENTIFIER) {
1081 printf(" AT '%s':\n", show_ident(entry->expr_ident));
1082 entry = entry->ident_expression;
1083 goto again;
1086 if (entry->type == EXPR_INDEX) {
1087 printf(" AT '%d..%d:\n", entry->idx_from, entry->idx_to);
1088 entry = entry->idx_expression;
1089 goto again;
1091 if (entry->type == EXPR_POS) {
1092 show_position_expr(entry, ctype);
1093 continue;
1095 show_initialization(ctype, entry);
1096 } END_FOR_EACH_PTR(entry);
1097 return 0;
1100 int show_symbol_expr_init(struct symbol *sym)
1102 struct expression *expr = sym->initializer;
1104 if (expr)
1105 show_expression(expr);
1106 return show_symbol_expr(sym);
1110 * Print out an expression. Return the pseudo that contains the
1111 * variable.
1113 int show_expression(struct expression *expr)
1115 if (!expr)
1116 return 0;
1118 if (!expr->ctype) {
1119 struct position *pos = &expr->pos;
1120 printf("\tno type at %s:%d:%d\n",
1121 stream_name(pos->stream),
1122 pos->line, pos->pos);
1123 return 0;
1126 switch (expr->type) {
1127 case EXPR_CALL:
1128 return show_call_expression(expr);
1130 case EXPR_ASSIGNMENT:
1131 return show_assignment(expr);
1133 case EXPR_COMMA:
1134 return show_comma(expr);
1135 case EXPR_BINOP:
1136 case EXPR_COMPARE:
1137 case EXPR_LOGICAL:
1138 return show_binop(expr);
1139 case EXPR_PREOP:
1140 return show_preop(expr);
1141 case EXPR_POSTOP:
1142 return show_postop(expr);
1143 case EXPR_SYMBOL:
1144 return show_symbol_expr(expr->symbol);
1145 case EXPR_DEREF:
1146 case EXPR_SIZEOF:
1147 case EXPR_PTRSIZEOF:
1148 case EXPR_ALIGNOF:
1149 case EXPR_OFFSETOF:
1150 warning(expr->pos, "invalid expression after evaluation");
1151 return 0;
1152 case EXPR_CAST:
1153 case EXPR_FORCE_CAST:
1154 case EXPR_IMPLIED_CAST:
1155 return show_cast_expr(expr);
1156 case EXPR_VALUE:
1157 return show_value(expr);
1158 case EXPR_FVALUE:
1159 return show_fvalue(expr);
1160 case EXPR_STRING:
1161 return show_string_expr(expr);
1162 case EXPR_INITIALIZER:
1163 return show_initializer_expr(expr, expr->ctype);
1164 case EXPR_SELECT:
1165 case EXPR_CONDITIONAL:
1166 return show_conditional_expr(expr);
1167 case EXPR_STATEMENT:
1168 return show_statement_expr(expr);
1169 case EXPR_LABEL:
1170 return show_label_expr(expr);
1171 case EXPR_SLICE:
1172 return show_slice(expr);
1174 // None of these should exist as direct expressions: they are only
1175 // valid as sub-expressions of initializers.
1176 case EXPR_POS:
1177 warning(expr->pos, "unable to show plain initializer position expression");
1178 return 0;
1179 case EXPR_IDENTIFIER:
1180 warning(expr->pos, "unable to show identifier expression");
1181 return 0;
1182 case EXPR_INDEX:
1183 warning(expr->pos, "unable to show index expression");
1184 return 0;
1185 case EXPR_TYPE:
1186 warning(expr->pos, "unable to show type expression");
1187 return 0;
1188 case EXPR_ASM_OPERAND:
1189 warning(expr->pos, "unable to show asm operand expression");
1190 return 0;
1192 return 0;