struct_assignment: add a comment explaining what the file does
[smatch.git] / show-parse.c
blob47e490b0d4109f0a798a1f5aecbfc9ca411c2809
1 /*
2 * sparse/show-parse.c
4 * Copyright (C) 2003 Transmeta Corp.
5 * 2003-2004 Linus Torvalds
7 * Licensed under the Open Software License version 1.1
9 * Print out results of parsing for debugging and testing.
11 #include <stdarg.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <ctype.h>
16 #include <unistd.h>
17 #include <fcntl.h>
19 #include "lib.h"
20 #include "allocate.h"
21 #include "token.h"
22 #include "parse.h"
23 #include "symbol.h"
24 #include "scope.h"
25 #include "expression.h"
26 #include "target.h"
28 static int show_symbol_expr(struct symbol *sym);
29 static int show_string_expr(struct expression *expr);
31 static void do_debug_symbol(struct symbol *sym, int indent)
33 static const char indent_string[] = " ";
34 static const char *typestr[] = {
35 [SYM_UNINITIALIZED] = "none",
36 [SYM_PREPROCESSOR] = "cpp.",
37 [SYM_BASETYPE] = "base",
38 [SYM_NODE] = "node",
39 [SYM_PTR] = "ptr.",
40 [SYM_FN] = "fn..",
41 [SYM_ARRAY] = "arry",
42 [SYM_STRUCT] = "strt",
43 [SYM_UNION] = "unin",
44 [SYM_ENUM] = "enum",
45 [SYM_TYPEDEF] = "tdef",
46 [SYM_TYPEOF] = "tpof",
47 [SYM_MEMBER] = "memb",
48 [SYM_BITFIELD] = "bitf",
49 [SYM_LABEL] = "labl",
50 [SYM_RESTRICT] = "rstr",
51 [SYM_FOULED] = "foul",
52 [SYM_BAD] = "bad.",
54 struct context *context;
55 int i;
57 if (!sym)
58 return;
59 fprintf(stderr, "%.*s%s%3d:%lu %s %s (as: %d) %p (%s:%d:%d) %s\n",
60 indent, indent_string, typestr[sym->type],
61 sym->bit_size, sym->ctype.alignment,
62 modifier_string(sym->ctype.modifiers), show_ident(sym->ident), sym->ctype.attribute->as,
63 sym, stream_name(sym->pos.stream), sym->pos.line, sym->pos.pos,
64 builtin_typename(sym) ?: "");
65 i = 0;
66 FOR_EACH_PTR(sym->ctype.attribute->contexts, context) {
67 /* FIXME: should print context expression */
68 fprintf(stderr, "< context%d: in=%d, out=%d\n",
69 i, context->in, context->out);
70 fprintf(stderr, " end context%d >\n", i);
71 i++;
72 } END_FOR_EACH_PTR(context);
73 if (sym->type == SYM_FN) {
74 struct symbol *arg;
75 i = 0;
76 FOR_EACH_PTR(sym->arguments, arg) {
77 fprintf(stderr, "< arg%d:\n", i);
78 do_debug_symbol(arg, 0);
79 fprintf(stderr, " end arg%d >\n", i);
80 i++;
81 } END_FOR_EACH_PTR(arg);
83 do_debug_symbol(sym->ctype.base_type, indent+2);
86 void debug_symbol(struct symbol *sym)
88 do_debug_symbol(sym, 0);
92 * Symbol type printout. The type system is by far the most
93 * complicated part of C - everything else is trivial.
95 const char *modifier_string(unsigned long mod)
97 static char buffer[100];
98 int len = 0;
99 int i;
100 struct mod_name {
101 unsigned long mod;
102 const char *name;
103 } *m;
105 static struct mod_name mod_names[] = {
106 {MOD_AUTO, "auto"},
107 {MOD_REGISTER, "register"},
108 {MOD_STATIC, "static"},
109 {MOD_EXTERN, "extern"},
110 {MOD_CONST, "const"},
111 {MOD_VOLATILE, "volatile"},
112 {MOD_SIGNED, "[signed]"},
113 {MOD_UNSIGNED, "[unsigned]"},
114 {MOD_CHAR, "[char]"},
115 {MOD_SHORT, "[short]"},
116 {MOD_LONG, "[long]"},
117 {MOD_LONGLONG, "[long long]"},
118 {MOD_LONGLONGLONG, "[long long long]"},
119 {MOD_TYPEDEF, "[typedef]"},
120 {MOD_TLS, "[tls]"},
121 {MOD_INLINE, "inline"},
122 {MOD_ADDRESSABLE, "[addressable]"},
123 {MOD_NOCAST, "[nocast]"},
124 {MOD_NODEREF, "[noderef]"},
125 {MOD_ACCESSED, "[accessed]"},
126 {MOD_TOPLEVEL, "[toplevel]"},
127 {MOD_ASSIGNED, "[assigned]"},
128 {MOD_TYPE, "[type]"},
129 {MOD_SAFE, "[safe]"},
130 {MOD_USERTYPE, "[usertype]"},
131 {MOD_NORETURN, "[noreturn]"},
132 {MOD_EXPLICITLY_SIGNED, "[explicitly-signed]"},
133 {MOD_BITWISE, "[bitwise]"},
134 {MOD_PURE, "[pure]"},
137 for (i = 0; i < ARRAY_SIZE(mod_names); i++) {
138 m = mod_names + i;
139 if (mod & m->mod) {
140 char c;
141 const char *name = m->name;
142 while ((c = *name++) != '\0' && len + 2 < sizeof buffer)
143 buffer[len++] = c;
144 buffer[len++] = ' ';
147 buffer[len] = 0;
148 return buffer;
151 static void show_struct_member(struct symbol *sym)
153 printf("\t%s:%d:%ld at offset %ld.%d", show_ident(sym->ident), sym->bit_size, sym->ctype.alignment, sym->offset, sym->bit_offset);
154 printf("\n");
157 void show_symbol_list(struct symbol_list *list, const char *sep)
159 struct symbol *sym;
160 const char *prepend = "";
162 FOR_EACH_PTR(list, sym) {
163 puts(prepend);
164 prepend = ", ";
165 show_symbol(sym);
166 } END_FOR_EACH_PTR(sym);
169 struct type_name {
170 char *start;
171 char *end;
174 static void FORMAT_ATTR(2) prepend(struct type_name *name, const char *fmt, ...)
176 static char buffer[512];
177 int n;
179 va_list args;
180 va_start(args, fmt);
181 n = vsprintf(buffer, fmt, args);
182 va_end(args);
184 name->start -= n;
185 memcpy(name->start, buffer, n);
188 static void FORMAT_ATTR(2) append(struct type_name *name, const char *fmt, ...)
190 static char buffer[512];
191 int n;
193 va_list args;
194 va_start(args, fmt);
195 n = vsprintf(buffer, fmt, args);
196 va_end(args);
198 memcpy(name->end, buffer, n);
199 name->end += n;
202 static struct ctype_name {
203 struct symbol *sym;
204 const char *name;
205 } typenames[] = {
206 { & char_ctype, "char" },
207 { &schar_ctype, "signed char" },
208 { &uchar_ctype, "unsigned char" },
209 { & short_ctype, "short" },
210 { &sshort_ctype, "signed short" },
211 { &ushort_ctype, "unsigned short" },
212 { & int_ctype, "int" },
213 { &sint_ctype, "signed int" },
214 { &uint_ctype, "unsigned int" },
215 { &slong_ctype, "signed long" },
216 { & long_ctype, "long" },
217 { &ulong_ctype, "unsigned long" },
218 { & llong_ctype, "long long" },
219 { &sllong_ctype, "signed long long" },
220 { &ullong_ctype, "unsigned long long" },
221 { & lllong_ctype, "long long long" },
222 { &slllong_ctype, "signed long long long" },
223 { &ulllong_ctype, "unsigned long long long" },
225 { &void_ctype, "void" },
226 { &bool_ctype, "bool" },
227 { &string_ctype, "string" },
229 { &float_ctype, "float" },
230 { &double_ctype, "double" },
231 { &ldouble_ctype,"long double" },
232 { &incomplete_ctype, "incomplete type" },
233 { &int_type, "abstract int" },
234 { &fp_type, "abstract fp" },
235 { &label_ctype, "label type" },
236 { &bad_ctype, "bad type" },
239 const char *builtin_typename(struct symbol *sym)
241 int i;
243 for (i = 0; i < ARRAY_SIZE(typenames); i++)
244 if (typenames[i].sym == sym)
245 return typenames[i].name;
246 return NULL;
249 const char *builtin_ctypename(struct ctype *ctype)
251 int i;
253 for (i = 0; i < ARRAY_SIZE(typenames); i++)
254 if (&typenames[i].sym->ctype == ctype)
255 return typenames[i].name;
256 return NULL;
259 static void do_show_type(struct symbol *sym, struct type_name *name)
261 const char *typename;
262 unsigned long mod = 0;
263 int as = 0;
264 int was_ptr = 0;
265 int restr = 0;
266 int fouled = 0;
268 deeper:
269 if (!sym || (sym->type != SYM_NODE && sym->type != SYM_ARRAY &&
270 sym->type != SYM_BITFIELD)) {
271 const char *s;
272 size_t len;
274 if (as)
275 prepend(name, "<asn:%d>", as);
277 s = modifier_string(mod);
278 len = strlen(s);
279 name->start -= len;
280 memcpy(name->start, s, len);
281 mod = 0;
282 as = 0;
285 if (!sym)
286 goto out;
288 if ((typename = builtin_typename(sym))) {
289 int len = strlen(typename);
290 if (name->start != name->end)
291 *--name->start = ' ';
292 name->start -= len;
293 memcpy(name->start, typename, len);
294 goto out;
297 /* Prepend */
298 switch (sym->type) {
299 case SYM_PTR:
300 prepend(name, "*");
301 mod = sym->ctype.modifiers;
302 as = sym->ctype.attribute->as;
303 was_ptr = 1;
304 break;
306 case SYM_FN:
307 if (was_ptr) {
308 prepend(name, "( ");
309 append(name, " )");
310 was_ptr = 0;
312 append(name, "( ... )");
313 break;
315 case SYM_STRUCT:
316 if (name->start != name->end)
317 *--name->start = ' ';
318 prepend(name, "struct %s", show_ident(sym->ident));
319 goto out;
321 case SYM_UNION:
322 if (name->start != name->end)
323 *--name->start = ' ';
324 prepend(name, "union %s", show_ident(sym->ident));
325 goto out;
327 case SYM_ENUM:
328 prepend(name, "enum %s ", show_ident(sym->ident));
329 break;
331 case SYM_NODE:
332 append(name, "%s", show_ident(sym->ident));
333 mod |= sym->ctype.modifiers;
334 as |= sym->ctype.attribute->as;
335 break;
337 case SYM_BITFIELD:
338 mod |= sym->ctype.modifiers;
339 as |= sym->ctype.attribute->as;
340 append(name, ":%d", sym->bit_size);
341 break;
343 case SYM_LABEL:
344 append(name, "label(%s:%p)", show_ident(sym->ident), sym);
345 return;
347 case SYM_ARRAY:
348 mod |= sym->ctype.modifiers;
349 as |= sym->ctype.attribute->as;
350 if (was_ptr) {
351 prepend(name, "( ");
352 append(name, " )");
353 was_ptr = 0;
355 append(name, "[%lld]", get_expression_value(sym->array_size));
356 break;
358 case SYM_RESTRICT:
359 if (!sym->ident) {
360 restr = 1;
361 break;
363 if (name->start != name->end)
364 *--name->start = ' ';
365 prepend(name, "restricted %s", show_ident(sym->ident));
366 goto out;
368 case SYM_FOULED:
369 fouled = 1;
370 break;
372 default:
373 if (name->start != name->end)
374 *--name->start = ' ';
375 prepend(name, "unknown type %d", sym->type);
376 goto out;
379 sym = sym->ctype.base_type;
380 goto deeper;
382 out:
383 if (restr)
384 prepend(name, "restricted ");
385 if (fouled)
386 prepend(name, "fouled ");
389 void show_type(struct symbol *sym)
391 char array[200];
392 struct type_name name;
394 name.start = name.end = array+100;
395 do_show_type(sym, &name);
396 *name.end = 0;
397 printf("%s", name.start);
400 const char *show_typename(struct symbol *sym)
402 static char array[200];
403 struct type_name name;
405 name.start = name.end = array+100;
406 do_show_type(sym, &name);
407 *name.end = 0;
408 return name.start;
411 void show_symbol(struct symbol *sym)
413 struct symbol *type;
415 if (!sym)
416 return;
418 if (sym->ctype.alignment)
419 printf(".align %ld\n", sym->ctype.alignment);
421 show_type(sym);
422 type = sym->ctype.base_type;
423 if (!type) {
424 printf("\n");
425 return;
429 * Show actual implementation information
431 switch (type->type) {
432 struct symbol *member;
434 case SYM_STRUCT:
435 case SYM_UNION:
436 printf(" {\n");
437 FOR_EACH_PTR(type->symbol_list, member) {
438 show_struct_member(member);
439 } END_FOR_EACH_PTR(member);
440 printf("}\n");
441 break;
443 case SYM_FN: {
444 struct statement *stmt = type->stmt;
445 printf("\n");
446 if (stmt) {
447 int val;
448 val = show_statement(stmt);
449 if (val)
450 printf("\tmov.%d\t\tretval,%d\n", stmt->ret->bit_size, val);
451 printf("\tret\n");
453 break;
456 default:
457 printf("\n");
458 break;
461 if (sym->initializer) {
462 printf(" = \n");
463 show_expression(sym->initializer);
467 static int show_symbol_init(struct symbol *sym);
469 static int new_pseudo(void)
471 static int nr = 0;
472 return ++nr;
475 static int new_label(void)
477 static int label = 0;
478 return ++label;
481 static void show_switch_statement(struct statement *stmt)
483 int val = show_expression(stmt->switch_expression);
484 struct symbol *sym;
485 printf("\tswitch v%d\n", val);
488 * Debugging only: Check that the case list is correct
489 * by printing it out.
491 * This is where a _real_ back-end would go through the
492 * cases to decide whether to use a lookup table or a
493 * series of comparisons etc
495 printf("# case table:\n");
496 FOR_EACH_PTR(stmt->switch_case->symbol_list, sym) {
497 struct statement *case_stmt = sym->stmt;
498 struct expression *expr = case_stmt->case_expression;
499 struct expression *to = case_stmt->case_to;
501 if (!expr) {
502 printf(" default");
503 } else {
504 if (expr->type == EXPR_VALUE) {
505 printf(" case %lld", expr->value);
506 if (to) {
507 if (to->type == EXPR_VALUE) {
508 printf(" .. %lld", to->value);
509 } else {
510 printf(" .. what?");
513 } else
514 printf(" what?");
516 printf(": .L%p\n", sym->bb_target);
517 } END_FOR_EACH_PTR(sym);
518 printf("# end case table\n");
520 show_statement(stmt->switch_statement);
522 if (stmt->switch_break->used)
523 printf(".L%p:\n", stmt->switch_break->bb_target);
526 static void show_symbol_decl(struct symbol_list *syms)
528 struct symbol *sym;
529 FOR_EACH_PTR(syms, sym) {
530 show_symbol_init(sym);
531 } END_FOR_EACH_PTR(sym);
534 static int show_return_stmt(struct statement *stmt);
537 * Print out a statement
539 int show_statement(struct statement *stmt)
541 if (!stmt)
542 return 0;
543 switch (stmt->type) {
544 case STMT_DECLARATION:
545 show_symbol_decl(stmt->declaration);
546 return 0;
547 case STMT_RETURN:
548 return show_return_stmt(stmt);
549 case STMT_COMPOUND: {
550 struct statement *s;
551 int last = 0;
553 if (stmt->inline_fn) {
554 show_statement(stmt->args);
555 printf("\tbegin_inline \t%s\n", show_ident(stmt->inline_fn->ident));
557 FOR_EACH_PTR(stmt->stmts, s) {
558 last = show_statement(s);
559 } END_FOR_EACH_PTR(s);
560 if (stmt->ret) {
561 int addr, bits;
562 printf(".L%p:\n", stmt->ret);
563 addr = show_symbol_expr(stmt->ret);
564 bits = stmt->ret->bit_size;
565 last = new_pseudo();
566 printf("\tld.%d\t\tv%d,[v%d]\n", bits, last, addr);
568 if (stmt->inline_fn)
569 printf("\tend_inlined\t%s\n", show_ident(stmt->inline_fn->ident));
570 return last;
573 case STMT_EXPRESSION:
574 return show_expression(stmt->expression);
575 case STMT_IF: {
576 int val, target;
577 struct expression *cond = stmt->if_conditional;
579 /* This is only valid if nobody can jump into the "dead" statement */
580 #if 0
581 if (cond->type == EXPR_VALUE) {
582 struct statement *s = stmt->if_true;
583 if (!cond->value)
584 s = stmt->if_false;
585 show_statement(s);
586 break;
588 #endif
589 val = show_expression(cond);
590 target = new_label();
591 printf("\tje\t\tv%d,.L%d\n", val, target);
592 show_statement(stmt->if_true);
593 if (stmt->if_false) {
594 int last = new_label();
595 printf("\tjmp\t\t.L%d\n", last);
596 printf(".L%d:\n", target);
597 target = last;
598 show_statement(stmt->if_false);
600 printf(".L%d:\n", target);
601 break;
603 case STMT_SWITCH:
604 show_switch_statement(stmt);
605 break;
607 case STMT_CASE:
608 printf(".L%p:\n", stmt->case_label);
609 show_statement(stmt->case_statement);
610 break;
612 case STMT_ITERATOR: {
613 struct statement *pre_statement = stmt->iterator_pre_statement;
614 struct expression *pre_condition = stmt->iterator_pre_condition;
615 struct statement *statement = stmt->iterator_statement;
616 struct statement *post_statement = stmt->iterator_post_statement;
617 struct expression *post_condition = stmt->iterator_post_condition;
618 int val, loop_top = 0, loop_bottom = 0;
620 show_symbol_decl(stmt->iterator_syms);
621 show_statement(pre_statement);
622 if (pre_condition) {
623 if (pre_condition->type == EXPR_VALUE) {
624 if (!pre_condition->value) {
625 loop_bottom = new_label();
626 printf("\tjmp\t\t.L%d\n", loop_bottom);
628 } else {
629 loop_bottom = new_label();
630 val = show_expression(pre_condition);
631 printf("\tje\t\tv%d, .L%d\n", val, loop_bottom);
634 if (!post_condition || post_condition->type != EXPR_VALUE || post_condition->value) {
635 loop_top = new_label();
636 printf(".L%d:\n", loop_top);
638 show_statement(statement);
639 if (stmt->iterator_continue->used)
640 printf(".L%p:\n", stmt->iterator_continue);
641 show_statement(post_statement);
642 if (!post_condition) {
643 printf("\tjmp\t\t.L%d\n", loop_top);
644 } else if (post_condition->type == EXPR_VALUE) {
645 if (post_condition->value)
646 printf("\tjmp\t\t.L%d\n", loop_top);
647 } else {
648 val = show_expression(post_condition);
649 printf("\tjne\t\tv%d, .L%d\n", val, loop_top);
651 if (stmt->iterator_break->used)
652 printf(".L%p:\n", stmt->iterator_break);
653 if (loop_bottom)
654 printf(".L%d:\n", loop_bottom);
655 break;
657 case STMT_NONE:
658 break;
660 case STMT_LABEL:
661 printf(".L%p:\n", stmt->label_identifier);
662 show_statement(stmt->label_statement);
663 break;
665 case STMT_GOTO:
666 if (stmt->goto_expression) {
667 int val = show_expression(stmt->goto_expression);
668 printf("\tgoto\t\t*v%d\n", val);
669 } else {
670 printf("\tgoto\t\t.L%p\n", stmt->goto_label->bb_target);
672 break;
673 case STMT_ASM:
674 printf("\tasm( .... )\n");
675 break;
676 case STMT_CONTEXT: {
677 int val = show_expression(stmt->expression);
678 printf("\tcontext( %d )\n", val);
679 break;
681 case STMT_RANGE: {
682 int val = show_expression(stmt->range_expression);
683 int low = show_expression(stmt->range_low);
684 int high = show_expression(stmt->range_high);
685 printf("\trange( %d %d-%d)\n", val, low, high);
686 break;
689 return 0;
692 static int show_call_expression(struct expression *expr)
694 struct symbol *direct;
695 struct expression *arg, *fn;
696 int fncall, retval;
697 int framesize;
699 if (!expr->ctype) {
700 warning(expr->pos, "\tcall with no type!");
701 return 0;
704 framesize = 0;
705 FOR_EACH_PTR_REVERSE(expr->args, arg) {
706 int new = show_expression(arg);
707 int size = arg->ctype->bit_size;
708 printf("\tpush.%d\t\tv%d\n", size, new);
709 framesize += bits_to_bytes(size);
710 } END_FOR_EACH_PTR_REVERSE(arg);
712 fn = expr->fn;
714 /* Remove dereference, if any */
715 direct = NULL;
716 if (fn->type == EXPR_PREOP) {
717 if (fn->unop->type == EXPR_SYMBOL) {
718 struct symbol *sym = fn->unop->symbol;
719 if (sym->ctype.base_type->type == SYM_FN)
720 direct = sym;
723 if (direct) {
724 printf("\tcall\t\t%s\n", show_ident(direct->ident));
725 } else {
726 fncall = show_expression(fn);
727 printf("\tcall\t\t*v%d\n", fncall);
729 if (framesize)
730 printf("\tadd.%d\t\tvSP,vSP,$%d\n", bits_in_pointer, framesize);
732 retval = new_pseudo();
733 printf("\tmov.%d\t\tv%d,retval\n", expr->ctype->bit_size, retval);
734 return retval;
737 static int show_comma(struct expression *expr)
739 show_expression(expr->left);
740 return show_expression(expr->right);
743 static int show_binop(struct expression *expr)
745 int left = show_expression(expr->left);
746 int right = show_expression(expr->right);
747 int new = new_pseudo();
748 const char *opname;
749 static const char *name[] = {
750 ['+'] = "add", ['-'] = "sub",
751 ['*'] = "mul", ['/'] = "div",
752 ['%'] = "mod", ['&'] = "and",
753 ['|'] = "lor", ['^'] = "xor"
755 unsigned int op = expr->op;
757 opname = show_special(op);
758 if (op < ARRAY_SIZE(name))
759 opname = name[op];
760 printf("\t%s.%d\t\tv%d,v%d,v%d\n", opname,
761 expr->ctype->bit_size,
762 new, left, right);
763 return new;
766 static int show_slice(struct expression *expr)
768 int target = show_expression(expr->base);
769 int new = new_pseudo();
770 printf("\tslice.%d\t\tv%d,v%d,%d\n", expr->r_nrbits, target, new, expr->r_bitpos);
771 return new;
774 static int show_regular_preop(struct expression *expr)
776 int target = show_expression(expr->unop);
777 int new = new_pseudo();
778 static const char *name[] = {
779 ['!'] = "nonzero", ['-'] = "neg",
780 ['~'] = "not",
782 unsigned int op = expr->op;
783 const char *opname;
785 opname = show_special(op);
786 if (op < ARRAY_SIZE(name))
787 opname = name[op];
788 printf("\t%s.%d\t\tv%d,v%d\n", opname, expr->ctype->bit_size, new, target);
789 return new;
793 * FIXME! Not all accesses are memory loads. We should
794 * check what kind of symbol is behind the dereference.
796 static int show_address_gen(struct expression *expr)
798 return show_expression(expr->unop);
801 static int show_load_gen(int bits, struct expression *expr, int addr)
803 int new = new_pseudo();
805 printf("\tld.%d\t\tv%d,[v%d]\n", bits, new, addr);
806 return new;
809 static void show_store_gen(int bits, int value, struct expression *expr, int addr)
811 /* FIXME!!! Bitfield store! */
812 printf("\tst.%d\t\tv%d,[v%d]\n", bits, value, addr);
815 static int show_assignment(struct expression *expr)
817 struct expression *target = expr->left;
818 int val, addr, bits;
820 if (!expr->ctype)
821 return 0;
823 bits = expr->ctype->bit_size;
824 val = show_expression(expr->right);
825 addr = show_address_gen(target);
826 show_store_gen(bits, val, target, addr);
827 return val;
830 static int show_return_stmt(struct statement *stmt)
832 struct expression *expr = stmt->ret_value;
833 struct symbol *target = stmt->ret_target;
835 if (expr && expr->ctype) {
836 int val = show_expression(expr);
837 int bits = expr->ctype->bit_size;
838 int addr = show_symbol_expr(target);
839 show_store_gen(bits, val, NULL, addr);
841 printf("\tret\t\t(%p)\n", target);
842 return 0;
845 static int show_initialization(struct symbol *sym, struct expression *expr)
847 int val, addr, bits;
849 if (!expr->ctype)
850 return 0;
852 bits = expr->ctype->bit_size;
853 val = show_expression(expr);
854 addr = show_symbol_expr(sym);
855 // FIXME! The "target" expression is for bitfield store information.
856 // Leave it NULL, which works fine.
857 show_store_gen(bits, val, NULL, addr);
858 return 0;
861 static int show_access(struct expression *expr)
863 int addr = show_address_gen(expr);
864 return show_load_gen(expr->ctype->bit_size, expr, addr);
867 static int show_inc_dec(struct expression *expr, int postop)
869 int addr = show_address_gen(expr->unop);
870 int retval, new;
871 const char *opname = expr->op == SPECIAL_INCREMENT ? "add" : "sub";
872 int bits = expr->ctype->bit_size;
874 retval = show_load_gen(bits, expr->unop, addr);
875 new = retval;
876 if (postop)
877 new = new_pseudo();
878 printf("\t%s.%d\t\tv%d,v%d,$1\n", opname, bits, new, retval);
879 show_store_gen(bits, new, expr->unop, addr);
880 return retval;
883 static int show_preop(struct expression *expr)
886 * '*' is an lvalue access, and is fundamentally different
887 * from an arithmetic operation. Maybe it should have an
888 * expression type of its own..
890 if (expr->op == '*')
891 return show_access(expr);
892 if (expr->op == SPECIAL_INCREMENT || expr->op == SPECIAL_DECREMENT)
893 return show_inc_dec(expr, 0);
894 return show_regular_preop(expr);
897 static int show_postop(struct expression *expr)
899 return show_inc_dec(expr, 1);
902 static int show_symbol_expr(struct symbol *sym)
904 int new = new_pseudo();
906 if (sym->initializer && sym->initializer->type == EXPR_STRING)
907 return show_string_expr(sym->initializer);
909 if (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_EXTERN | MOD_STATIC)) {
910 printf("\tmovi.%d\t\tv%d,$%s\n", bits_in_pointer, new, show_ident(sym->ident));
911 return new;
913 if (sym->ctype.modifiers & MOD_ADDRESSABLE) {
914 printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer, new, sym->value);
915 return new;
917 printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer, new, show_ident(sym->ident), sym);
918 return new;
921 static int show_symbol_init(struct symbol *sym)
923 struct expression *expr = sym->initializer;
925 if (expr) {
926 int val, addr, bits;
928 bits = expr->ctype->bit_size;
929 val = show_expression(expr);
930 addr = show_symbol_expr(sym);
931 show_store_gen(bits, val, NULL, addr);
933 return 0;
936 static int type_is_signed(struct symbol *sym)
938 if (sym->type == SYM_NODE)
939 sym = sym->ctype.base_type;
940 if (sym->type == SYM_PTR)
941 return 0;
942 return !(sym->ctype.modifiers & MOD_UNSIGNED);
945 static int show_cast_expr(struct expression *expr)
947 struct symbol *old_type, *new_type;
948 int op = show_expression(expr->cast_expression);
949 int oldbits, newbits;
950 int new, is_signed;
952 old_type = expr->cast_expression->ctype;
953 new_type = expr->cast_type;
955 oldbits = old_type->bit_size;
956 newbits = new_type->bit_size;
957 if (oldbits >= newbits)
958 return op;
959 new = new_pseudo();
960 is_signed = type_is_signed(old_type);
961 if (is_signed) {
962 printf("\tsext%d.%d\tv%d,v%d\n", oldbits, newbits, new, op);
963 } else {
964 printf("\tandl.%d\t\tv%d,v%d,$%lu\n", newbits, new, op, (1UL << oldbits)-1);
966 return new;
969 static int show_value(struct expression *expr)
971 int new = new_pseudo();
972 unsigned long long value = expr->value;
974 printf("\tmovi.%d\t\tv%d,$%llu\n", expr->ctype->bit_size, new, value);
975 return new;
978 static int show_fvalue(struct expression *expr)
980 int new = new_pseudo();
981 long double value = expr->fvalue;
983 printf("\tmovf.%d\t\tv%d,$%Lf\n", expr->ctype->bit_size, new, value);
984 return new;
987 static int show_string_expr(struct expression *expr)
989 int new = new_pseudo();
991 printf("\tmovi.%d\t\tv%d,&%s\n", bits_in_pointer, new, show_string(expr->string));
992 return new;
995 static int show_label_expr(struct expression *expr)
997 int new = new_pseudo();
998 printf("\tmovi.%d\t\tv%d,.L%p\n",bits_in_pointer, new, expr->label_symbol);
999 return new;
1002 static int show_conditional_expr(struct expression *expr)
1004 int cond = show_expression(expr->conditional);
1005 int true = show_expression(expr->cond_true);
1006 int false = show_expression(expr->cond_false);
1007 int new = new_pseudo();
1009 printf("[v%d]\tcmov.%d\t\tv%d,v%d,v%d\n", cond, expr->ctype->bit_size, new, true, false);
1010 return new;
1013 static int show_statement_expr(struct expression *expr)
1015 return show_statement(expr->statement);
1018 static int show_position_expr(struct expression *expr, struct symbol *base)
1020 int new = show_expression(expr->init_expr);
1021 struct symbol *ctype = expr->init_expr->ctype;
1022 int bit_offset;
1024 bit_offset = ctype ? ctype->bit_offset : -1;
1026 printf("\tinsert v%d at [%d:%d] of %s\n", new,
1027 expr->init_offset, bit_offset,
1028 show_ident(base->ident));
1029 return 0;
1032 static int show_initializer_expr(struct expression *expr, struct symbol *ctype)
1034 struct expression *entry;
1036 FOR_EACH_PTR(expr->expr_list, entry) {
1038 again:
1039 // Nested initializers have their positions already
1040 // recursively calculated - just output them too
1041 if (entry->type == EXPR_INITIALIZER) {
1042 show_initializer_expr(entry, ctype);
1043 continue;
1046 // Initializer indexes and identifiers should
1047 // have been evaluated to EXPR_POS
1048 if (entry->type == EXPR_IDENTIFIER) {
1049 printf(" AT '%s':\n", show_ident(entry->expr_ident));
1050 entry = entry->ident_expression;
1051 goto again;
1054 if (entry->type == EXPR_INDEX) {
1055 printf(" AT '%d..%d:\n", entry->idx_from, entry->idx_to);
1056 entry = entry->idx_expression;
1057 goto again;
1059 if (entry->type == EXPR_POS) {
1060 show_position_expr(entry, ctype);
1061 continue;
1063 show_initialization(ctype, entry);
1064 } END_FOR_EACH_PTR(entry);
1065 return 0;
1068 int show_symbol_expr_init(struct symbol *sym)
1070 struct expression *expr = sym->initializer;
1072 if (expr)
1073 show_expression(expr);
1074 return show_symbol_expr(sym);
1078 * Print out an expression. Return the pseudo that contains the
1079 * variable.
1081 int show_expression(struct expression *expr)
1083 if (!expr)
1084 return 0;
1086 if (!expr->ctype) {
1087 struct position *pos = &expr->pos;
1088 printf("\tno type at %s:%d:%d\n",
1089 stream_name(pos->stream),
1090 pos->line, pos->pos);
1091 return 0;
1094 switch (expr->type) {
1095 case EXPR_CALL:
1096 return show_call_expression(expr);
1098 case EXPR_ASSIGNMENT:
1099 return show_assignment(expr);
1101 case EXPR_COMMA:
1102 return show_comma(expr);
1103 case EXPR_BINOP:
1104 case EXPR_COMPARE:
1105 case EXPR_LOGICAL:
1106 return show_binop(expr);
1107 case EXPR_PREOP:
1108 return show_preop(expr);
1109 case EXPR_POSTOP:
1110 return show_postop(expr);
1111 case EXPR_SYMBOL:
1112 return show_symbol_expr(expr->symbol);
1113 case EXPR_DEREF:
1114 case EXPR_SIZEOF:
1115 case EXPR_PTRSIZEOF:
1116 case EXPR_ALIGNOF:
1117 case EXPR_OFFSETOF:
1118 warning(expr->pos, "invalid expression after evaluation");
1119 return 0;
1120 case EXPR_CAST:
1121 case EXPR_FORCE_CAST:
1122 case EXPR_IMPLIED_CAST:
1123 return show_cast_expr(expr);
1124 case EXPR_VALUE:
1125 return show_value(expr);
1126 case EXPR_FVALUE:
1127 return show_fvalue(expr);
1128 case EXPR_STRING:
1129 return show_string_expr(expr);
1130 case EXPR_INITIALIZER:
1131 return show_initializer_expr(expr, expr->ctype);
1132 case EXPR_SELECT:
1133 case EXPR_CONDITIONAL:
1134 return show_conditional_expr(expr);
1135 case EXPR_STATEMENT:
1136 return show_statement_expr(expr);
1137 case EXPR_LABEL:
1138 return show_label_expr(expr);
1139 case EXPR_SLICE:
1140 return show_slice(expr);
1142 // None of these should exist as direct expressions: they are only
1143 // valid as sub-expressions of initializers.
1144 case EXPR_POS:
1145 warning(expr->pos, "unable to show plain initializer position expression");
1146 return 0;
1147 case EXPR_IDENTIFIER:
1148 warning(expr->pos, "unable to show identifier expression");
1149 return 0;
1150 case EXPR_INDEX:
1151 warning(expr->pos, "unable to show index expression");
1152 return 0;
1153 case EXPR_TYPE:
1154 warning(expr->pos, "unable to show type expression");
1155 return 0;
1157 return 0;