states: rename unreachable() to is_unreachable()
[smatch.git] / show-parse.c
blobceb6b3cb6f823239c7e2254a8c38d249cae9c31e
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_TYPEOF_UNQUAL] = "tpof_unqual",
63 [SYM_BITFIELD] = "bitf",
64 [SYM_LABEL] = "labl",
65 [SYM_RESTRICT] = "rstr",
66 [SYM_FOULED] = "foul",
67 [SYM_BAD] = "bad.",
69 struct context *context;
70 int i;
72 if (!sym)
73 return;
74 fprintf(stderr, "%.*s%s%3d:%lu %s%s (as: %s) %p (%s:%d:%d) %s\n",
75 indent, indent_string, typestr[sym->type],
76 sym->bit_size, sym->ctype.alignment,
77 modifier_string(sym->ctype.modifiers), show_ident(sym->ident),
78 show_as(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);
99 do_debug_symbol(sym->ctype.base_type, indent+2);
102 void debug_symbol(struct symbol *sym)
104 do_debug_symbol(sym, 0);
108 * Symbol type printout. The type system is by far the most
109 * complicated part of C - everything else is trivial.
111 static const char *show_modifiers(unsigned long mod, int term)
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;
121 static struct mod_name mod_names[] = {
122 {MOD_AUTO, "auto"},
123 {MOD_EXTERN, "extern"},
124 {MOD_REGISTER, "register"},
125 {MOD_STATIC, "static"},
126 {MOD_INLINE, "inline"},
127 {MOD_CONST, "const"},
128 {MOD_RESTRICT, "restrict"},
129 {MOD_VOLATILE, "volatile"},
130 {MOD_ADDRESSABLE, "[addressable]"},
131 {MOD_ASSIGNED, "[assigned]"},
132 {MOD_ATOMIC, "[atomic]"},
133 {MOD_BITWISE, "[bitwise]"},
134 {MOD_EXPLICITLY_SIGNED, "[explicitly-signed]"},
135 {MOD_GNU_INLINE, "[gnu_inline]"},
136 {MOD_NOCAST, "[nocast]"},
137 {MOD_NODEREF, "[noderef]"},
138 {MOD_NORETURN, "[noreturn]"},
139 {MOD_PURE, "[pure]"},
140 {MOD_SAFE, "[safe]"},
141 {MOD_SIGNED, "[signed]"},
142 {MOD_TLS, "[tls]"},
143 {MOD_TOPLEVEL, "[toplevel]"},
144 {MOD_UNSIGNED, "[unsigned]"},
145 {MOD_UNUSED, "[unused]"},
146 {MOD_USERTYPE, "[usertype]"},
149 for (i = 0; i < ARRAY_SIZE(mod_names); i++) {
150 m = mod_names + i;
151 if (mod & m->mod) {
152 char c;
153 const char *name = m->name;
154 while ((c = *name++) != '\0' && len + 2 < sizeof buffer)
155 buffer[len++] = c;
156 buffer[len++] = ' ';
159 if (len && !term) // strip the trailing space
160 --len;
161 buffer[len] = 0;
162 return buffer;
166 // show the modifiers, terminated by a space if not empty
167 const char *modifier_string(unsigned long mod)
169 return show_modifiers(mod, 1);
173 // show the modifiers, without an ending space
174 const char *modifier_name(unsigned long mod)
176 return show_modifiers(mod, 0);
179 static void show_struct_member(struct symbol *sym)
181 printf("\t%s:%d:%ld at offset %ld.%d", show_ident(sym->ident), sym->bit_size, sym->ctype.alignment, sym->offset, sym->bit_offset);
182 printf("\n");
185 void show_symbol_list(struct symbol_list *list)
187 struct symbol *sym;
188 const char *prepend = "";
190 FOR_EACH_PTR(list, sym) {
191 puts(prepend);
192 prepend = ", ";
193 show_symbol(sym);
194 } END_FOR_EACH_PTR(sym);
197 const char *show_as(struct ident *as)
199 if (!as)
200 return "";
201 return show_ident(as);
204 struct type_name {
205 char *start;
206 char *end;
209 static void FORMAT_ATTR(2) prepend(struct type_name *name, const char *fmt, ...)
211 static char buffer[512];
212 int n;
214 va_list args;
215 va_start(args, fmt);
216 n = vsprintf(buffer, fmt, args);
217 va_end(args);
219 name->start -= n;
220 memcpy(name->start, buffer, n);
223 static void FORMAT_ATTR(2) append(struct type_name *name, const char *fmt, ...)
225 static char buffer[512];
226 int n;
228 va_list args;
229 va_start(args, fmt);
230 n = vsprintf(buffer, fmt, args);
231 va_end(args);
233 memcpy(name->end, buffer, n);
234 name->end += n;
237 static struct ctype_name {
238 struct symbol *sym;
239 const char *name;
240 const char *suffix;
241 } typenames[] = {
242 { & char_ctype, "char", "" },
243 { &schar_ctype, "signed char", "" },
244 { &uchar_ctype, "unsigned char", "" },
245 { & short_ctype, "short", "" },
246 { &sshort_ctype, "signed short", "" },
247 { &ushort_ctype, "unsigned short", "" },
248 { & int_ctype, "int", "" },
249 { &sint_ctype, "signed int", "" },
250 { &uint_ctype, "unsigned int", "U" },
251 { & long_ctype, "long", "L" },
252 { &slong_ctype, "signed long", "L" },
253 { &ulong_ctype, "unsigned long", "UL" },
254 { & llong_ctype, "long long", "LL" },
255 { &sllong_ctype, "signed long long", "LL" },
256 { &ullong_ctype, "unsigned long long", "ULL" },
257 { & int128_ctype, "__int128", "" },
258 { &sint128_ctype, "signed __int128", "" },
259 { &uint128_ctype, "unsigned __int128", "" },
261 { &void_ctype, "void", "" },
262 { &bool_ctype, "bool", "" },
264 { &float_ctype, "float", "F" },
265 { &double_ctype, "double", "" },
266 { &ldouble_ctype,"long double", "L" },
267 { &incomplete_ctype, "incomplete type", "" },
268 { &int_type, "abstract int", "" },
269 { &fp_type, "abstract fp", "" },
270 { &label_ctype, "label type", "" },
271 { &bad_ctype, "bad type", "" },
274 const char *builtin_typename(struct symbol *sym)
276 int i;
278 for (i = 0; i < ARRAY_SIZE(typenames); i++)
279 if (typenames[i].sym == sym)
280 return typenames[i].name;
281 return NULL;
284 const char *builtin_type_suffix(struct symbol *sym)
286 int i;
288 for (i = 0; i < ARRAY_SIZE(typenames); i++)
289 if (typenames[i].sym == sym)
290 return typenames[i].suffix;
291 return NULL;
294 const char *builtin_ctypename(struct ctype *ctype)
296 int i;
298 for (i = 0; i < ARRAY_SIZE(typenames); i++)
299 if (&typenames[i].sym->ctype == ctype)
300 return typenames[i].name;
301 return NULL;
304 static void do_show_type(struct symbol *sym, struct type_name *name)
306 const char *typename;
307 unsigned long mod = 0;
308 struct ident *as = NULL;
309 int was_ptr = 0;
310 int restr = 0;
311 int fouled = 0;
313 deeper:
314 if (sym && (sym->type != SYM_NODE && sym->type != SYM_ARRAY &&
315 sym->type != SYM_BITFIELD)) {
316 const char *s;
317 size_t len;
319 if (as)
320 prepend(name, "%s ", show_as(as));
322 if (sym && (sym->type == SYM_BASETYPE || sym->type == SYM_ENUM))
323 mod &= ~MOD_SPECIFIER;
324 s = modifier_string(mod);
325 len = strlen(s);
326 name->start -= len;
327 memcpy(name->start, s, len);
328 mod = 0;
329 as = NULL;
332 if (!sym)
333 goto out;
335 if ((typename = builtin_typename(sym))) {
336 int len = strlen(typename);
337 if (name->start != name->end)
338 *--name->start = ' ';
339 name->start -= len;
340 memcpy(name->start, typename, len);
341 goto out;
344 /* Prepend */
345 switch (sym->type) {
346 case SYM_PTR:
347 prepend(name, "*");
348 mod = sym->ctype.modifiers;
349 as = sym->ctype.as;
350 was_ptr = 1;
351 examine_pointer_target(sym);
352 break;
354 case SYM_FN:
355 if (was_ptr) {
356 prepend(name, "( ");
357 append(name, " )");
358 was_ptr = 0;
360 append(name, "( ... )");
361 break;
363 case SYM_STRUCT:
364 if (name->start != name->end)
365 *--name->start = ' ';
366 prepend(name, "struct %s", show_ident(sym->ident));
367 goto out;
369 case SYM_UNION:
370 if (name->start != name->end)
371 *--name->start = ' ';
372 prepend(name, "union %s", show_ident(sym->ident));
373 goto out;
375 case SYM_ENUM:
376 prepend(name, "enum %s ", show_ident(sym->ident));
377 break;
379 case SYM_NODE:
380 if (sym->ident)
381 append(name, "%s", show_ident(sym->ident));
382 mod |= sym->ctype.modifiers;
383 combine_address_space(sym->pos, &as, sym->ctype.as);
384 break;
386 case SYM_BITFIELD:
387 mod |= sym->ctype.modifiers;
388 combine_address_space(sym->pos, &as, sym->ctype.as);
389 append(name, ":%d", sym->bit_size);
390 break;
392 case SYM_LABEL:
393 append(name, "label(%s:%p)", show_ident(sym->ident), sym);
394 return;
396 case SYM_ARRAY:
397 mod |= sym->ctype.modifiers;
398 combine_address_space(sym->pos, &as, sym->ctype.as);
399 if (was_ptr) {
400 prepend(name, "( ");
401 append(name, " )");
402 was_ptr = 0;
404 append(name, "[%lld]", get_expression_value(sym->array_size));
405 break;
407 case SYM_RESTRICT:
408 if (!sym->ident) {
409 restr = 1;
410 break;
412 if (name->start != name->end)
413 *--name->start = ' ';
414 prepend(name, "restricted %s", show_ident(sym->ident));
415 goto out;
417 case SYM_FOULED:
418 fouled = 1;
419 break;
421 default:
422 if (name->start != name->end)
423 *--name->start = ' ';
424 prepend(name, "unknown type %d", sym->type);
425 goto out;
428 sym = sym->ctype.base_type;
429 goto deeper;
431 out:
432 if (restr)
433 prepend(name, "restricted ");
434 if (fouled)
435 prepend(name, "fouled ");
437 // strip trailing space
438 if (name->end > name->start && name->end[-1] == ' ')
439 name->end--;
442 void show_type(struct symbol *sym)
444 char array[200];
445 struct type_name name;
447 name.start = name.end = array+100;
448 do_show_type(sym, &name);
449 *name.end = 0;
450 printf("%s", name.start);
453 const char *show_typename(struct symbol *sym)
455 static char array[200];
456 struct type_name name;
458 name.start = name.end = array+100;
459 do_show_type(sym, &name);
460 *name.end = 0;
461 return name.start;
464 void show_symbol(struct symbol *sym)
466 struct symbol *type;
468 if (!sym)
469 return;
471 if (sym->ctype.alignment)
472 printf(".align %ld\n", sym->ctype.alignment);
474 show_type(sym);
475 type = sym->ctype.base_type;
476 if (!type) {
477 printf("\n");
478 return;
482 * Show actual implementation information
484 switch (type->type) {
485 struct symbol *member;
487 case SYM_STRUCT:
488 case SYM_UNION:
489 printf(" {\n");
490 FOR_EACH_PTR(type->symbol_list, member) {
491 show_struct_member(member);
492 } END_FOR_EACH_PTR(member);
493 printf("}\n");
494 break;
496 case SYM_FN: {
497 struct statement *stmt = type->stmt;
498 printf("\n");
499 if (stmt) {
500 int val;
501 val = show_statement(stmt);
502 if (val)
503 printf("\tmov.%d\t\tretval,%d\n", stmt->ret->bit_size, val);
504 printf("\tret\n");
506 break;
509 default:
510 printf("\n");
511 break;
514 if (sym->initializer) {
515 printf(" = \n");
516 show_expression(sym->initializer);
520 static int show_symbol_init(struct symbol *sym);
522 static int new_pseudo(void)
524 static int nr = 0;
525 return ++nr;
528 static int new_label(void)
530 static int label = 0;
531 return ++label;
534 static void show_switch_statement(struct statement *stmt)
536 int val = show_expression(stmt->switch_expression);
537 struct symbol *sym;
538 printf("\tswitch v%d\n", val);
541 * Debugging only: Check that the case list is correct
542 * by printing it out.
544 * This is where a _real_ back-end would go through the
545 * cases to decide whether to use a lookup table or a
546 * series of comparisons etc
548 printf("# case table:\n");
549 FOR_EACH_PTR(stmt->switch_case->symbol_list, sym) {
550 struct statement *case_stmt = sym->stmt;
551 struct expression *expr = case_stmt->case_expression;
552 struct expression *to = case_stmt->case_to;
554 if (!expr) {
555 printf(" default");
556 } else {
557 if (expr->type == EXPR_VALUE) {
558 printf(" case %lld", expr->value);
559 if (to) {
560 if (to->type == EXPR_VALUE) {
561 printf(" .. %lld", to->value);
562 } else {
563 printf(" .. what?");
566 } else
567 printf(" what?");
569 printf(": .L%p\n", sym);
570 } END_FOR_EACH_PTR(sym);
571 printf("# end case table\n");
573 show_statement(stmt->switch_statement);
575 if (stmt->switch_break->used)
576 printf(".L%p:\n", stmt->switch_break);
579 static void show_symbol_decl(struct symbol_list *syms)
581 struct symbol *sym;
582 FOR_EACH_PTR(syms, sym) {
583 show_symbol_init(sym);
584 } END_FOR_EACH_PTR(sym);
587 static int show_return_stmt(struct statement *stmt);
590 * Print out a statement
592 int show_statement(struct statement *stmt)
594 if (!stmt)
595 return 0;
596 switch (stmt->type) {
597 case STMT_DECLARATION:
598 show_symbol_decl(stmt->declaration);
599 return 0;
600 case STMT_RETURN:
601 return show_return_stmt(stmt);
602 case STMT_COMPOUND: {
603 struct statement *s;
604 int last = 0;
606 if (stmt->inline_fn) {
607 show_statement(stmt->args);
608 printf("\tbegin_inline \t%s\n", show_ident(stmt->inline_fn->ident));
610 FOR_EACH_PTR(stmt->stmts, s) {
611 last = show_statement(s);
612 } END_FOR_EACH_PTR(s);
613 if (stmt->ret) {
614 int addr, bits;
615 printf(".L%p:\n", stmt->ret);
616 addr = show_symbol_expr(stmt->ret);
617 bits = stmt->ret->bit_size;
618 last = new_pseudo();
619 printf("\tld.%d\t\tv%d,[v%d]\n", bits, last, addr);
621 if (stmt->inline_fn)
622 printf("\tend_inlined\t%s\n", show_ident(stmt->inline_fn->ident));
623 return last;
626 case STMT_EXPRESSION:
627 return show_expression(stmt->expression);
628 case STMT_IF: {
629 int val, target;
630 struct expression *cond = stmt->if_conditional;
632 /* This is only valid if nobody can jump into the "dead" statement */
633 #if 0
634 if (cond->type == EXPR_VALUE) {
635 struct statement *s = stmt->if_true;
636 if (!cond->value)
637 s = stmt->if_false;
638 show_statement(s);
639 break;
641 #endif
642 val = show_expression(cond);
643 target = new_label();
644 printf("\tje\t\tv%d,.L%d\n", val, target);
645 show_statement(stmt->if_true);
646 if (stmt->if_false) {
647 int last = new_label();
648 printf("\tjmp\t\t.L%d\n", last);
649 printf(".L%d:\n", target);
650 target = last;
651 show_statement(stmt->if_false);
653 printf(".L%d:\n", target);
654 break;
656 case STMT_SWITCH:
657 show_switch_statement(stmt);
658 break;
660 case STMT_CASE:
661 printf(".L%p:\n", stmt->case_label);
662 show_statement(stmt->case_statement);
663 break;
665 case STMT_ITERATOR: {
666 struct statement *pre_statement = stmt->iterator_pre_statement;
667 struct expression *pre_condition = stmt->iterator_pre_condition;
668 struct statement *statement = stmt->iterator_statement;
669 struct statement *post_statement = stmt->iterator_post_statement;
670 struct expression *post_condition = stmt->iterator_post_condition;
671 int val, loop_top = 0, loop_bottom = 0;
673 show_symbol_decl(stmt->iterator_syms);
674 show_statement(pre_statement);
675 if (pre_condition) {
676 if (pre_condition->type == EXPR_VALUE) {
677 if (!pre_condition->value) {
678 loop_bottom = new_label();
679 printf("\tjmp\t\t.L%d\n", loop_bottom);
681 } else {
682 loop_bottom = new_label();
683 val = show_expression(pre_condition);
684 printf("\tje\t\tv%d, .L%d\n", val, loop_bottom);
687 if (!post_condition || post_condition->type != EXPR_VALUE || post_condition->value) {
688 loop_top = new_label();
689 printf(".L%d:\n", loop_top);
691 show_statement(statement);
692 if (stmt->iterator_continue->used)
693 printf(".L%p:\n", stmt->iterator_continue);
694 show_statement(post_statement);
695 if (!post_condition) {
696 printf("\tjmp\t\t.L%d\n", loop_top);
697 } else if (post_condition->type == EXPR_VALUE) {
698 if (post_condition->value)
699 printf("\tjmp\t\t.L%d\n", loop_top);
700 } else {
701 val = show_expression(post_condition);
702 printf("\tjne\t\tv%d, .L%d\n", val, loop_top);
704 if (stmt->iterator_break->used)
705 printf(".L%p:\n", stmt->iterator_break);
706 if (loop_bottom)
707 printf(".L%d:\n", loop_bottom);
708 break;
710 case STMT_NONE:
711 break;
713 case STMT_LABEL:
714 printf(".L%p:\n", stmt->label_identifier);
715 show_statement(stmt->label_statement);
716 break;
718 case STMT_GOTO:
719 if (stmt->goto_expression) {
720 int val = show_expression(stmt->goto_expression);
721 printf("\tgoto\t\t*v%d\n", val);
722 } else {
723 printf("\tgoto\t\t.L%p\n", stmt->goto_label);
725 break;
726 case STMT_ASM:
727 printf("\tasm( .... )\n");
728 break;
729 case STMT_CONTEXT: {
730 int val = show_expression(stmt->expression);
731 printf("\tcontext( %d )\n", val);
732 break;
734 case STMT_RANGE: {
735 int val = show_expression(stmt->range_expression);
736 int low = show_expression(stmt->range_low);
737 int high = show_expression(stmt->range_high);
738 printf("\trange( %d %d-%d)\n", val, low, high);
739 break;
742 return 0;
745 static int show_call_expression(struct expression *expr)
747 struct symbol *direct;
748 struct expression *arg, *fn;
749 int fncall, retval;
750 int framesize;
752 if (!expr->ctype) {
753 warning(expr->pos, "\tcall with no type!");
754 return 0;
757 framesize = 0;
758 FOR_EACH_PTR_REVERSE(expr->args, arg) {
759 int new = show_expression(arg);
760 int size = arg->ctype->bit_size;
761 printf("\tpush.%d\t\tv%d\n", size, new);
762 framesize += bits_to_bytes(size);
763 } END_FOR_EACH_PTR_REVERSE(arg);
765 fn = expr->fn;
767 /* Remove dereference, if any */
768 direct = NULL;
769 if (fn->type == EXPR_PREOP) {
770 if (fn->unop->type == EXPR_SYMBOL) {
771 struct symbol *sym = fn->unop->symbol;
772 if (sym->ctype.base_type->type == SYM_FN)
773 direct = sym;
776 if (direct) {
777 printf("\tcall\t\t%s\n", show_ident(direct->ident));
778 } else {
779 fncall = show_expression(fn);
780 printf("\tcall\t\t*v%d\n", fncall);
782 if (framesize)
783 printf("\tadd.%d\t\tvSP,vSP,$%d\n", bits_in_pointer, framesize);
785 retval = new_pseudo();
786 printf("\tmov.%d\t\tv%d,retval\n", expr->ctype->bit_size, retval);
787 return retval;
790 static int show_comma(struct expression *expr)
792 show_expression(expr->left);
793 return show_expression(expr->right);
796 static int show_binop(struct expression *expr)
798 int left = show_expression(expr->left);
799 int right = show_expression(expr->right);
800 int new = new_pseudo();
801 const char *opname;
802 static const char *name[] = {
803 ['+'] = "add", ['-'] = "sub",
804 ['*'] = "mul", ['/'] = "div",
805 ['%'] = "mod", ['&'] = "and",
806 ['|'] = "lor", ['^'] = "xor"
808 unsigned int op = expr->op;
810 opname = show_special(op);
811 if (op < ARRAY_SIZE(name))
812 opname = name[op];
813 printf("\t%s.%d\t\tv%d,v%d,v%d\n", opname,
814 expr->ctype->bit_size,
815 new, left, right);
816 return new;
819 static int show_slice(struct expression *expr)
821 int target = show_expression(expr->base);
822 int new = new_pseudo();
823 printf("\tslice.%d\t\tv%d,v%d,%d\n", expr->ctype->bit_size, target, new, expr->r_bitpos);
824 return new;
827 static int show_regular_preop(struct expression *expr)
829 int target = show_expression(expr->unop);
830 int new = new_pseudo();
831 static const char *name[] = {
832 ['!'] = "nonzero", ['-'] = "neg",
833 ['~'] = "not",
835 unsigned int op = expr->op;
836 const char *opname;
838 opname = show_special(op);
839 if (op < ARRAY_SIZE(name))
840 opname = name[op];
841 printf("\t%s.%d\t\tv%d,v%d\n", opname, expr->ctype->bit_size, new, target);
842 return new;
846 * FIXME! Not all accesses are memory loads. We should
847 * check what kind of symbol is behind the dereference.
849 static int show_address_gen(struct expression *expr)
851 return show_expression(expr->unop);
854 static int show_load_gen(int bits, struct expression *expr, int addr)
856 int new = new_pseudo();
858 printf("\tld.%d\t\tv%d,[v%d]\n", bits, new, addr);
859 return new;
862 static void show_store_gen(int bits, int value, struct expression *expr, int addr)
864 /* FIXME!!! Bitfield store! */
865 printf("\tst.%d\t\tv%d,[v%d]\n", bits, value, addr);
868 static int show_assignment(struct expression *expr)
870 struct expression *target = expr->left;
871 int val, addr, bits;
873 if (!expr->ctype)
874 return 0;
876 bits = expr->ctype->bit_size;
877 val = show_expression(expr->right);
878 addr = show_address_gen(target);
879 show_store_gen(bits, val, target, addr);
880 return val;
883 static int show_return_stmt(struct statement *stmt)
885 struct expression *expr = stmt->ret_value;
886 struct symbol *target = stmt->ret_target;
888 if (expr && expr->ctype) {
889 int val = show_expression(expr);
890 int bits = expr->ctype->bit_size;
891 int addr = show_symbol_expr(target);
892 show_store_gen(bits, val, NULL, addr);
894 printf("\tret\t\t(%p)\n", target);
895 return 0;
898 static int show_initialization(struct symbol *sym, struct expression *expr)
900 int val, addr, bits;
902 if (!expr->ctype)
903 return 0;
905 bits = expr->ctype->bit_size;
906 val = show_expression(expr);
907 addr = show_symbol_expr(sym);
908 // FIXME! The "target" expression is for bitfield store information.
909 // Leave it NULL, which works fine.
910 show_store_gen(bits, val, NULL, addr);
911 return 0;
914 static int show_access(struct expression *expr)
916 int addr = show_address_gen(expr);
917 return show_load_gen(expr->ctype->bit_size, expr, addr);
920 static int show_inc_dec(struct expression *expr, int postop)
922 int addr = show_address_gen(expr->unop);
923 int retval, new;
924 const char *opname = expr->op == SPECIAL_INCREMENT ? "add" : "sub";
925 int bits = expr->ctype->bit_size;
927 retval = show_load_gen(bits, expr->unop, addr);
928 new = retval;
929 if (postop)
930 new = new_pseudo();
931 printf("\t%s.%d\t\tv%d,v%d,$1\n", opname, bits, new, retval);
932 show_store_gen(bits, new, expr->unop, addr);
933 return retval;
936 static int show_preop(struct expression *expr)
939 * '*' is an lvalue access, and is fundamentally different
940 * from an arithmetic operation. Maybe it should have an
941 * expression type of its own..
943 if (expr->op == '*')
944 return show_access(expr);
945 if (expr->op == SPECIAL_INCREMENT || expr->op == SPECIAL_DECREMENT)
946 return show_inc_dec(expr, 0);
947 return show_regular_preop(expr);
950 static int show_postop(struct expression *expr)
952 return show_inc_dec(expr, 1);
955 static int show_symbol_expr(struct symbol *sym)
957 int new = new_pseudo();
959 if (sym->initializer && sym->initializer->type == EXPR_STRING)
960 return show_string_expr(sym->initializer);
962 if (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_EXTERN | MOD_STATIC)) {
963 printf("\tmovi.%d\t\tv%d,$%s\n", bits_in_pointer, new, show_ident(sym->ident));
964 return new;
966 if (sym->ctype.modifiers & MOD_ADDRESSABLE) {
967 printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer, new, 0LL);
968 return new;
970 printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer, new, show_ident(sym->ident), sym);
971 return new;
974 static int show_symbol_init(struct symbol *sym)
976 struct expression *expr = sym->initializer;
978 if (expr) {
979 int val, addr, bits;
981 bits = expr->ctype->bit_size;
982 val = show_expression(expr);
983 addr = show_symbol_expr(sym);
984 show_store_gen(bits, val, NULL, addr);
986 return 0;
989 static int show_cast_expr(struct expression *expr)
991 struct symbol *old_type, *new_type;
992 int op = show_expression(expr->cast_expression);
993 int oldbits, newbits;
994 int new, is_signed;
996 old_type = expr->cast_expression->ctype;
997 new_type = expr->cast_type;
999 oldbits = old_type->bit_size;
1000 newbits = new_type->bit_size;
1001 if (oldbits >= newbits)
1002 return op;
1003 new = new_pseudo();
1004 is_signed = is_signed_type(old_type);
1005 if (is_signed) {
1006 printf("\tsext%d.%d\tv%d,v%d\n", oldbits, newbits, new, op);
1007 } else {
1008 printf("\tandl.%d\t\tv%d,v%d,$%lu\n", newbits, new, op, (1UL << oldbits)-1);
1010 return new;
1013 static int show_value(struct expression *expr)
1015 int new = new_pseudo();
1016 unsigned long long value = expr->value;
1018 printf("\tmovi.%d\t\tv%d,$%llu\n", expr->ctype->bit_size, new, value);
1019 return new;
1022 static int show_fvalue(struct expression *expr)
1024 int new = new_pseudo();
1025 long double value = expr->fvalue;
1027 printf("\tmovf.%d\t\tv%d,$%Le\n", expr->ctype->bit_size, new, value);
1028 return new;
1031 static int show_string_expr(struct expression *expr)
1033 int new = new_pseudo();
1035 printf("\tmovi.%d\t\tv%d,&%s\n", bits_in_pointer, new, show_string(expr->string));
1036 return new;
1039 static int show_label_expr(struct expression *expr)
1041 int new = new_pseudo();
1042 printf("\tmovi.%d\t\tv%d,.L%p\n",bits_in_pointer, new, expr->label_symbol);
1043 return new;
1046 static int show_conditional_expr(struct expression *expr)
1048 int cond = show_expression(expr->conditional);
1049 int valt = show_expression(expr->cond_true);
1050 int valf = show_expression(expr->cond_false);
1051 int new = new_pseudo();
1053 printf("[v%d]\tcmov.%d\t\tv%d,v%d,v%d\n", cond, expr->ctype->bit_size, new, valt, valf);
1054 return new;
1057 static int show_statement_expr(struct expression *expr)
1059 return show_statement(expr->statement);
1062 static int show_position_expr(struct expression *expr, struct symbol *base)
1064 int new = show_expression(expr->init_expr);
1065 struct symbol *ctype = expr->init_expr->ctype;
1066 int bit_offset;
1068 bit_offset = ctype ? ctype->bit_offset : -1;
1070 printf("\tinsert v%d at [%d:%d] of %s\n", new,
1071 expr->init_offset, bit_offset,
1072 show_ident(base->ident));
1073 return 0;
1076 static int show_initializer_expr(struct expression *expr, struct symbol *ctype)
1078 struct expression *entry;
1080 FOR_EACH_PTR(expr->expr_list, entry) {
1082 again:
1083 // Nested initializers have their positions already
1084 // recursively calculated - just output them too
1085 if (entry->type == EXPR_INITIALIZER) {
1086 show_initializer_expr(entry, ctype);
1087 continue;
1090 // Initializer indexes and identifiers should
1091 // have been evaluated to EXPR_POS
1092 if (entry->type == EXPR_IDENTIFIER) {
1093 printf(" AT '%s':\n", show_ident(entry->expr_ident));
1094 entry = entry->ident_expression;
1095 goto again;
1098 if (entry->type == EXPR_INDEX) {
1099 printf(" AT '%d..%d:\n", entry->idx_from, entry->idx_to);
1100 entry = entry->idx_expression;
1101 goto again;
1103 if (entry->type == EXPR_POS) {
1104 show_position_expr(entry, ctype);
1105 continue;
1107 show_initialization(ctype, entry);
1108 } END_FOR_EACH_PTR(entry);
1109 return 0;
1112 int show_symbol_expr_init(struct symbol *sym)
1114 struct expression *expr = sym->initializer;
1116 if (expr)
1117 show_expression(expr);
1118 return show_symbol_expr(sym);
1122 * Print out an expression. Return the pseudo that contains the
1123 * variable.
1125 int show_expression(struct expression *expr)
1127 if (!expr)
1128 return 0;
1130 if (!expr->ctype) {
1131 struct position *pos = &expr->pos;
1132 printf("\tno type at %s:%d:%d\n",
1133 stream_name(pos->stream),
1134 pos->line, pos->pos);
1135 return 0;
1138 switch (expr->type) {
1139 case EXPR_CALL:
1140 return show_call_expression(expr);
1142 case EXPR_ASSIGNMENT:
1143 return show_assignment(expr);
1145 case EXPR_COMMA:
1146 return show_comma(expr);
1147 case EXPR_BINOP:
1148 case EXPR_COMPARE:
1149 case EXPR_LOGICAL:
1150 return show_binop(expr);
1151 case EXPR_PREOP:
1152 return show_preop(expr);
1153 case EXPR_POSTOP:
1154 return show_postop(expr);
1155 case EXPR_SYMBOL:
1156 return show_symbol_expr(expr->symbol);
1157 case EXPR_DEREF:
1158 case EXPR_SIZEOF:
1159 case EXPR_PTRSIZEOF:
1160 case EXPR_ALIGNOF:
1161 case EXPR_OFFSETOF:
1162 warning(expr->pos, "invalid expression after evaluation");
1163 return 0;
1164 case EXPR_CAST:
1165 case EXPR_FORCE_CAST:
1166 case EXPR_IMPLIED_CAST:
1167 return show_cast_expr(expr);
1168 case EXPR_VALUE:
1169 return show_value(expr);
1170 case EXPR_FVALUE:
1171 return show_fvalue(expr);
1172 case EXPR_STRING:
1173 return show_string_expr(expr);
1174 case EXPR_INITIALIZER:
1175 return show_initializer_expr(expr, expr->ctype);
1176 case EXPR_SELECT:
1177 case EXPR_CONDITIONAL:
1178 return show_conditional_expr(expr);
1179 case EXPR_STATEMENT:
1180 return show_statement_expr(expr);
1181 case EXPR_LABEL:
1182 return show_label_expr(expr);
1183 case EXPR_SLICE:
1184 return show_slice(expr);
1186 // None of these should exist as direct expressions: they are only
1187 // valid as sub-expressions of initializers.
1188 case EXPR_POS:
1189 warning(expr->pos, "unable to show plain initializer position expression");
1190 return 0;
1191 case EXPR_IDENTIFIER:
1192 warning(expr->pos, "unable to show identifier expression");
1193 return 0;
1194 case EXPR_INDEX:
1195 warning(expr->pos, "unable to show index expression");
1196 return 0;
1197 case EXPR_TYPE:
1198 warning(expr->pos, "unable to show type expression");
1199 return 0;
1200 case EXPR_GENERIC:
1201 warning(expr->pos, "unable to show generic expression");
1202 return 0;
1204 return 0;