check_overflow: separate the two types of states
[smatch.git] / show-parse.c
blobf249f4b5b372b50cecb08e7e064d23a23c39b8df
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.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.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 char *p = buffer;
99 const char *res,**ptr, *names[] = {
100 "auto", "register", "static", "extern",
101 "const", "volatile", "[signed]", "[unsigned]",
102 "[char]", "[short]", "[long]", "[long long]",
103 "[typdef]", "[structof]", "[unionof]", "[enum]",
104 "[typeof]", "[attribute]", "inline", "[addressable]",
105 "[nocast]", "[noderef]", "[accessed]", "[toplevel]",
106 "[label]", "[assigned]", "[type]", "[safe]",
107 "[usertype]", "[force]", "[explicitly-signed]",
108 NULL
110 ptr = names;
111 while ((res = *ptr++) != NULL) {
112 if (mod & 1) {
113 char c;
114 while ((c = *res++) != '\0')
115 *p++ = c;
116 *p++ = ' ';
118 mod >>= 1;
120 *p = 0;
121 return buffer;
124 static void show_struct_member(struct symbol *sym)
126 printf("\t%s:%d:%ld at offset %ld.%d", show_ident(sym->ident), sym->bit_size, sym->ctype.alignment, sym->offset, sym->bit_offset);
127 printf("\n");
130 void show_symbol_list(struct symbol_list *list, const char *sep)
132 struct symbol *sym;
133 const char *prepend = "";
135 FOR_EACH_PTR(list, sym) {
136 puts(prepend);
137 prepend = ", ";
138 show_symbol(sym);
139 } END_FOR_EACH_PTR(sym);
142 struct type_name {
143 char *start;
144 char *end;
147 static void FORMAT_ATTR(2) prepend(struct type_name *name, const char *fmt, ...)
149 static char buffer[512];
150 int n;
152 va_list args;
153 va_start(args, fmt);
154 n = vsprintf(buffer, fmt, args);
155 va_end(args);
157 name->start -= n;
158 memcpy(name->start, buffer, n);
161 static void FORMAT_ATTR(2) append(struct type_name *name, const char *fmt, ...)
163 static char buffer[512];
164 int n;
166 va_list args;
167 va_start(args, fmt);
168 n = vsprintf(buffer, fmt, args);
169 va_end(args);
171 memcpy(name->end, buffer, n);
172 name->end += n;
175 static struct ctype_name {
176 struct symbol *sym;
177 const char *name;
178 } typenames[] = {
179 { & char_ctype, "char" },
180 { &schar_ctype, "signed char" },
181 { &uchar_ctype, "unsigned char" },
182 { & short_ctype, "short" },
183 { &sshort_ctype, "signed short" },
184 { &ushort_ctype, "unsigned short" },
185 { & int_ctype, "int" },
186 { &sint_ctype, "signed int" },
187 { &uint_ctype, "unsigned int" },
188 { &slong_ctype, "signed long" },
189 { & long_ctype, "long" },
190 { &ulong_ctype, "unsigned long" },
191 { & llong_ctype, "long long" },
192 { &sllong_ctype, "signed long long" },
193 { &ullong_ctype, "unsigned long long" },
194 { & lllong_ctype, "long long long" },
195 { &slllong_ctype, "signed long long long" },
196 { &ulllong_ctype, "unsigned long long long" },
198 { &void_ctype, "void" },
199 { &bool_ctype, "bool" },
200 { &string_ctype, "string" },
202 { &float_ctype, "float" },
203 { &double_ctype, "double" },
204 { &ldouble_ctype,"long double" },
205 { &incomplete_ctype, "incomplete type" },
206 { &int_type, "abstract int" },
207 { &fp_type, "abstract fp" },
208 { &label_ctype, "label type" },
209 { &bad_ctype, "bad type" },
212 const char *builtin_typename(struct symbol *sym)
214 int i;
216 for (i = 0; i < sizeof(typenames)/sizeof(typenames[0]); i++)
217 if (typenames[i].sym == sym)
218 return typenames[i].name;
219 return NULL;
222 const char *builtin_ctypename(struct ctype *ctype)
224 int i;
226 for (i = 0; i < sizeof(typenames)/sizeof(typenames[0]); i++)
227 if (&typenames[i].sym->ctype == ctype)
228 return typenames[i].name;
229 return NULL;
232 static void do_show_type(struct symbol *sym, struct type_name *name)
234 const char *typename;
235 unsigned long mod = 0;
236 int as = 0;
237 int was_ptr = 0;
238 int restr = 0;
239 int fouled = 0;
241 deeper:
242 if (!sym || (sym->type != SYM_NODE && sym->type != SYM_ARRAY &&
243 sym->type != SYM_BITFIELD)) {
244 const char *s;
245 size_t len;
247 if (as)
248 prepend(name, "<asn:%d>", as);
250 s = modifier_string(mod);
251 len = strlen(s);
252 name->start -= len;
253 memcpy(name->start, s, len);
254 mod = 0;
255 as = 0;
258 if (!sym)
259 goto out;
261 if ((typename = builtin_typename(sym))) {
262 int len = strlen(typename);
263 if (name->start != name->end)
264 *--name->start = ' ';
265 name->start -= len;
266 memcpy(name->start, typename, len);
267 goto out;
270 /* Prepend */
271 switch (sym->type) {
272 case SYM_PTR:
273 prepend(name, "*");
274 mod = sym->ctype.modifiers;
275 as = sym->ctype.as;
276 was_ptr = 1;
277 break;
279 case SYM_FN:
280 if (was_ptr) {
281 prepend(name, "( ");
282 append(name, " )");
283 was_ptr = 0;
285 append(name, "( ... )");
286 break;
288 case SYM_STRUCT:
289 if (name->start != name->end)
290 *--name->start = ' ';
291 prepend(name, "struct %s", show_ident(sym->ident));
292 goto out;
294 case SYM_UNION:
295 if (name->start != name->end)
296 *--name->start = ' ';
297 prepend(name, "union %s", show_ident(sym->ident));
298 goto out;
300 case SYM_ENUM:
301 prepend(name, "enum %s ", show_ident(sym->ident));
302 break;
304 case SYM_NODE:
305 append(name, "%s", show_ident(sym->ident));
306 mod |= sym->ctype.modifiers;
307 as |= sym->ctype.as;
308 break;
310 case SYM_BITFIELD:
311 mod |= sym->ctype.modifiers;
312 as |= sym->ctype.as;
313 append(name, ":%d", sym->bit_size);
314 break;
316 case SYM_LABEL:
317 append(name, "label(%s:%p)", show_ident(sym->ident), sym);
318 return;
320 case SYM_ARRAY:
321 mod |= sym->ctype.modifiers;
322 as |= sym->ctype.as;
323 if (was_ptr) {
324 prepend(name, "( ");
325 append(name, " )");
326 was_ptr = 0;
328 append(name, "[%lld]", get_expression_value(sym->array_size));
329 break;
331 case SYM_RESTRICT:
332 if (!sym->ident) {
333 restr = 1;
334 break;
336 if (name->start != name->end)
337 *--name->start = ' ';
338 prepend(name, "restricted %s", show_ident(sym->ident));
339 goto out;
341 case SYM_FOULED:
342 fouled = 1;
343 break;
345 default:
346 if (name->start != name->end)
347 *--name->start = ' ';
348 prepend(name, "unknown type %d", sym->type);
349 goto out;
352 sym = sym->ctype.base_type;
353 goto deeper;
355 out:
356 if (restr)
357 prepend(name, "restricted ");
358 if (fouled)
359 prepend(name, "fouled ");
362 void show_type(struct symbol *sym)
364 char array[200];
365 struct type_name name;
367 name.start = name.end = array+100;
368 do_show_type(sym, &name);
369 *name.end = 0;
370 printf("%s", name.start);
373 const char *show_typename(struct symbol *sym)
375 static char array[200];
376 struct type_name name;
378 name.start = name.end = array+100;
379 do_show_type(sym, &name);
380 *name.end = 0;
381 return name.start;
384 void show_symbol(struct symbol *sym)
386 struct symbol *type;
388 if (!sym)
389 return;
391 if (sym->ctype.alignment)
392 printf(".align %ld\n", sym->ctype.alignment);
394 show_type(sym);
395 type = sym->ctype.base_type;
396 if (!type) {
397 printf("\n");
398 return;
402 * Show actual implementation information
404 switch (type->type) {
405 struct symbol *member;
407 case SYM_STRUCT:
408 case SYM_UNION:
409 printf(" {\n");
410 FOR_EACH_PTR(type->symbol_list, member) {
411 show_struct_member(member);
412 } END_FOR_EACH_PTR(member);
413 printf("}\n");
414 break;
416 case SYM_FN: {
417 struct statement *stmt = type->stmt;
418 printf("\n");
419 if (stmt) {
420 int val;
421 val = show_statement(stmt);
422 if (val)
423 printf("\tmov.%d\t\tretval,%d\n", stmt->ret->bit_size, val);
424 printf("\tret\n");
426 break;
429 default:
430 printf("\n");
431 break;
434 if (sym->initializer) {
435 printf(" = \n");
436 show_expression(sym->initializer);
440 static int show_symbol_init(struct symbol *sym);
442 static int new_pseudo(void)
444 static int nr = 0;
445 return ++nr;
448 static int new_label(void)
450 static int label = 0;
451 return ++label;
454 static void show_switch_statement(struct statement *stmt)
456 int val = show_expression(stmt->switch_expression);
457 struct symbol *sym;
458 printf("\tswitch v%d\n", val);
461 * Debugging only: Check that the case list is correct
462 * by printing it out.
464 * This is where a _real_ back-end would go through the
465 * cases to decide whether to use a lookup table or a
466 * series of comparisons etc
468 printf("# case table:\n");
469 FOR_EACH_PTR(stmt->switch_case->symbol_list, sym) {
470 struct statement *case_stmt = sym->stmt;
471 struct expression *expr = case_stmt->case_expression;
472 struct expression *to = case_stmt->case_to;
474 if (!expr) {
475 printf(" default");
476 } else {
477 if (expr->type == EXPR_VALUE) {
478 printf(" case %lld", expr->value);
479 if (to) {
480 if (to->type == EXPR_VALUE) {
481 printf(" .. %lld", to->value);
482 } else {
483 printf(" .. what?");
486 } else
487 printf(" what?");
489 printf(": .L%p\n", sym->bb_target);
490 } END_FOR_EACH_PTR(sym);
491 printf("# end case table\n");
493 show_statement(stmt->switch_statement);
495 if (stmt->switch_break->used)
496 printf(".L%p:\n", stmt->switch_break->bb_target);
499 static void show_symbol_decl(struct symbol_list *syms)
501 struct symbol *sym;
502 FOR_EACH_PTR(syms, sym) {
503 show_symbol_init(sym);
504 } END_FOR_EACH_PTR(sym);
507 static int show_return_stmt(struct statement *stmt);
510 * Print out a statement
512 int show_statement(struct statement *stmt)
514 if (!stmt)
515 return 0;
516 switch (stmt->type) {
517 case STMT_DECLARATION:
518 show_symbol_decl(stmt->declaration);
519 return 0;
520 case STMT_RETURN:
521 return show_return_stmt(stmt);
522 case STMT_COMPOUND: {
523 struct statement *s;
524 int last = 0;
526 if (stmt->inline_fn) {
527 show_statement(stmt->args);
528 printf("\tbegin_inline \t%s\n", show_ident(stmt->inline_fn->ident));
530 FOR_EACH_PTR(stmt->stmts, s) {
531 last = show_statement(s);
532 } END_FOR_EACH_PTR(s);
533 if (stmt->ret) {
534 int addr, bits;
535 printf(".L%p:\n", stmt->ret);
536 addr = show_symbol_expr(stmt->ret);
537 bits = stmt->ret->bit_size;
538 last = new_pseudo();
539 printf("\tld.%d\t\tv%d,[v%d]\n", bits, last, addr);
541 if (stmt->inline_fn)
542 printf("\tend_inlined\t%s\n", show_ident(stmt->inline_fn->ident));
543 return last;
546 case STMT_EXPRESSION:
547 return show_expression(stmt->expression);
548 case STMT_IF: {
549 int val, target;
550 struct expression *cond = stmt->if_conditional;
552 /* This is only valid if nobody can jump into the "dead" statement */
553 #if 0
554 if (cond->type == EXPR_VALUE) {
555 struct statement *s = stmt->if_true;
556 if (!cond->value)
557 s = stmt->if_false;
558 show_statement(s);
559 break;
561 #endif
562 val = show_expression(cond);
563 target = new_label();
564 printf("\tje\t\tv%d,.L%d\n", val, target);
565 show_statement(stmt->if_true);
566 if (stmt->if_false) {
567 int last = new_label();
568 printf("\tjmp\t\t.L%d\n", last);
569 printf(".L%d:\n", target);
570 target = last;
571 show_statement(stmt->if_false);
573 printf(".L%d:\n", target);
574 break;
576 case STMT_SWITCH:
577 show_switch_statement(stmt);
578 break;
580 case STMT_CASE:
581 printf(".L%p:\n", stmt->case_label);
582 show_statement(stmt->case_statement);
583 break;
585 case STMT_ITERATOR: {
586 struct statement *pre_statement = stmt->iterator_pre_statement;
587 struct expression *pre_condition = stmt->iterator_pre_condition;
588 struct statement *statement = stmt->iterator_statement;
589 struct statement *post_statement = stmt->iterator_post_statement;
590 struct expression *post_condition = stmt->iterator_post_condition;
591 int val, loop_top = 0, loop_bottom = 0;
593 show_symbol_decl(stmt->iterator_syms);
594 show_statement(pre_statement);
595 if (pre_condition) {
596 if (pre_condition->type == EXPR_VALUE) {
597 if (!pre_condition->value) {
598 loop_bottom = new_label();
599 printf("\tjmp\t\t.L%d\n", loop_bottom);
601 } else {
602 loop_bottom = new_label();
603 val = show_expression(pre_condition);
604 printf("\tje\t\tv%d, .L%d\n", val, loop_bottom);
607 if (!post_condition || post_condition->type != EXPR_VALUE || post_condition->value) {
608 loop_top = new_label();
609 printf(".L%d:\n", loop_top);
611 show_statement(statement);
612 if (stmt->iterator_continue->used)
613 printf(".L%p:\n", stmt->iterator_continue);
614 show_statement(post_statement);
615 if (!post_condition) {
616 printf("\tjmp\t\t.L%d\n", loop_top);
617 } else if (post_condition->type == EXPR_VALUE) {
618 if (post_condition->value)
619 printf("\tjmp\t\t.L%d\n", loop_top);
620 } else {
621 val = show_expression(post_condition);
622 printf("\tjne\t\tv%d, .L%d\n", val, loop_top);
624 if (stmt->iterator_break->used)
625 printf(".L%p:\n", stmt->iterator_break);
626 if (loop_bottom)
627 printf(".L%d:\n", loop_bottom);
628 break;
630 case STMT_NONE:
631 break;
633 case STMT_LABEL:
634 printf(".L%p:\n", stmt->label_identifier);
635 show_statement(stmt->label_statement);
636 break;
638 case STMT_GOTO:
639 if (stmt->goto_expression) {
640 int val = show_expression(stmt->goto_expression);
641 printf("\tgoto\t\t*v%d\n", val);
642 } else {
643 printf("\tgoto\t\t.L%p\n", stmt->goto_label->bb_target);
645 break;
646 case STMT_ASM:
647 printf("\tasm( .... )\n");
648 break;
649 case STMT_CONTEXT: {
650 int val = show_expression(stmt->expression);
651 printf("\tcontext( %d )\n", val);
652 break;
654 case STMT_RANGE: {
655 int val = show_expression(stmt->range_expression);
656 int low = show_expression(stmt->range_low);
657 int high = show_expression(stmt->range_high);
658 printf("\trange( %d %d-%d)\n", val, low, high);
659 break;
662 return 0;
665 static int show_call_expression(struct expression *expr)
667 struct symbol *direct;
668 struct expression *arg, *fn;
669 int fncall, retval;
670 int framesize;
672 if (!expr->ctype) {
673 warning(expr->pos, "\tcall with no type!");
674 return 0;
677 framesize = 0;
678 FOR_EACH_PTR_REVERSE(expr->args, arg) {
679 int new = show_expression(arg);
680 int size = arg->ctype->bit_size;
681 printf("\tpush.%d\t\tv%d\n", size, new);
682 framesize += bits_to_bytes(size);
683 } END_FOR_EACH_PTR_REVERSE(arg);
685 fn = expr->fn;
687 /* Remove dereference, if any */
688 direct = NULL;
689 if (fn->type == EXPR_PREOP) {
690 if (fn->unop->type == EXPR_SYMBOL) {
691 struct symbol *sym = fn->unop->symbol;
692 if (sym->ctype.base_type->type == SYM_FN)
693 direct = sym;
696 if (direct) {
697 printf("\tcall\t\t%s\n", show_ident(direct->ident));
698 } else {
699 fncall = show_expression(fn);
700 printf("\tcall\t\t*v%d\n", fncall);
702 if (framesize)
703 printf("\tadd.%d\t\tvSP,vSP,$%d\n", bits_in_pointer, framesize);
705 retval = new_pseudo();
706 printf("\tmov.%d\t\tv%d,retval\n", expr->ctype->bit_size, retval);
707 return retval;
710 static int show_comma(struct expression *expr)
712 show_expression(expr->left);
713 return show_expression(expr->right);
716 static int show_binop(struct expression *expr)
718 int left = show_expression(expr->left);
719 int right = show_expression(expr->right);
720 int new = new_pseudo();
721 const char *opname;
722 static const char *name[] = {
723 ['+'] = "add", ['-'] = "sub",
724 ['*'] = "mul", ['/'] = "div",
725 ['%'] = "mod", ['&'] = "and",
726 ['|'] = "lor", ['^'] = "xor"
728 unsigned int op = expr->op;
730 opname = show_special(op);
731 if (op < sizeof(name)/sizeof(*name))
732 opname = name[op];
733 printf("\t%s.%d\t\tv%d,v%d,v%d\n", opname,
734 expr->ctype->bit_size,
735 new, left, right);
736 return new;
739 static int show_slice(struct expression *expr)
741 int target = show_expression(expr->base);
742 int new = new_pseudo();
743 printf("\tslice.%d\t\tv%d,v%d,%d\n", expr->r_nrbits, target, new, expr->r_bitpos);
744 return new;
747 static int show_regular_preop(struct expression *expr)
749 int target = show_expression(expr->unop);
750 int new = new_pseudo();
751 static const char *name[] = {
752 ['!'] = "nonzero", ['-'] = "neg",
753 ['~'] = "not",
755 unsigned int op = expr->op;
756 const char *opname;
758 opname = show_special(op);
759 if (op < sizeof(name)/sizeof(*name))
760 opname = name[op];
761 printf("\t%s.%d\t\tv%d,v%d\n", opname, expr->ctype->bit_size, new, target);
762 return new;
766 * FIXME! Not all accesses are memory loads. We should
767 * check what kind of symbol is behind the dereference.
769 static int show_address_gen(struct expression *expr)
771 return show_expression(expr->unop);
774 static int show_load_gen(int bits, struct expression *expr, int addr)
776 int new = new_pseudo();
778 printf("\tld.%d\t\tv%d,[v%d]\n", bits, new, addr);
779 return new;
782 static void show_store_gen(int bits, int value, struct expression *expr, int addr)
784 /* FIXME!!! Bitfield store! */
785 printf("\tst.%d\t\tv%d,[v%d]\n", bits, value, addr);
788 static int show_assignment(struct expression *expr)
790 struct expression *target = expr->left;
791 int val, addr, bits;
793 if (!expr->ctype)
794 return 0;
796 bits = expr->ctype->bit_size;
797 val = show_expression(expr->right);
798 addr = show_address_gen(target);
799 show_store_gen(bits, val, target, addr);
800 return val;
803 static int show_return_stmt(struct statement *stmt)
805 struct expression *expr = stmt->ret_value;
806 struct symbol *target = stmt->ret_target;
808 if (expr && expr->ctype) {
809 int val = show_expression(expr);
810 int bits = expr->ctype->bit_size;
811 int addr = show_symbol_expr(target);
812 show_store_gen(bits, val, NULL, addr);
814 printf("\tret\t\t(%p)\n", target);
815 return 0;
818 static int show_initialization(struct symbol *sym, struct expression *expr)
820 int val, addr, bits;
822 if (!expr->ctype)
823 return 0;
825 bits = expr->ctype->bit_size;
826 val = show_expression(expr);
827 addr = show_symbol_expr(sym);
828 // FIXME! The "target" expression is for bitfield store information.
829 // Leave it NULL, which works fine.
830 show_store_gen(bits, val, NULL, addr);
831 return 0;
834 static int show_access(struct expression *expr)
836 int addr = show_address_gen(expr);
837 return show_load_gen(expr->ctype->bit_size, expr, addr);
840 static int show_inc_dec(struct expression *expr, int postop)
842 int addr = show_address_gen(expr->unop);
843 int retval, new;
844 const char *opname = expr->op == SPECIAL_INCREMENT ? "add" : "sub";
845 int bits = expr->ctype->bit_size;
847 retval = show_load_gen(bits, expr->unop, addr);
848 new = retval;
849 if (postop)
850 new = new_pseudo();
851 printf("\t%s.%d\t\tv%d,v%d,$1\n", opname, bits, new, retval);
852 show_store_gen(bits, new, expr->unop, addr);
853 return retval;
856 static int show_preop(struct expression *expr)
859 * '*' is an lvalue access, and is fundamentally different
860 * from an arithmetic operation. Maybe it should have an
861 * expression type of its own..
863 if (expr->op == '*')
864 return show_access(expr);
865 if (expr->op == SPECIAL_INCREMENT || expr->op == SPECIAL_DECREMENT)
866 return show_inc_dec(expr, 0);
867 return show_regular_preop(expr);
870 static int show_postop(struct expression *expr)
872 return show_inc_dec(expr, 1);
875 static int show_symbol_expr(struct symbol *sym)
877 int new = new_pseudo();
879 if (sym->initializer && sym->initializer->type == EXPR_STRING)
880 return show_string_expr(sym->initializer);
882 if (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_EXTERN | MOD_STATIC)) {
883 printf("\tmovi.%d\t\tv%d,$%s\n", bits_in_pointer, new, show_ident(sym->ident));
884 return new;
886 if (sym->ctype.modifiers & MOD_ADDRESSABLE) {
887 printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer, new, sym->value);
888 return new;
890 printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer, new, show_ident(sym->ident), sym);
891 return new;
894 static int show_symbol_init(struct symbol *sym)
896 struct expression *expr = sym->initializer;
898 if (expr) {
899 int val, addr, bits;
901 bits = expr->ctype->bit_size;
902 val = show_expression(expr);
903 addr = show_symbol_expr(sym);
904 show_store_gen(bits, val, NULL, addr);
906 return 0;
909 static int type_is_signed(struct symbol *sym)
911 if (sym->type == SYM_NODE)
912 sym = sym->ctype.base_type;
913 if (sym->type == SYM_PTR)
914 return 0;
915 return !(sym->ctype.modifiers & MOD_UNSIGNED);
918 static int show_cast_expr(struct expression *expr)
920 struct symbol *old_type, *new_type;
921 int op = show_expression(expr->cast_expression);
922 int oldbits, newbits;
923 int new, is_signed;
925 old_type = expr->cast_expression->ctype;
926 new_type = expr->cast_type;
928 oldbits = old_type->bit_size;
929 newbits = new_type->bit_size;
930 if (oldbits >= newbits)
931 return op;
932 new = new_pseudo();
933 is_signed = type_is_signed(old_type);
934 if (is_signed) {
935 printf("\tsext%d.%d\tv%d,v%d\n", oldbits, newbits, new, op);
936 } else {
937 printf("\tandl.%d\t\tv%d,v%d,$%lu\n", newbits, new, op, (1UL << oldbits)-1);
939 return new;
942 static int show_value(struct expression *expr)
944 int new = new_pseudo();
945 unsigned long long value = expr->value;
947 printf("\tmovi.%d\t\tv%d,$%llu\n", expr->ctype->bit_size, new, value);
948 return new;
951 static int show_fvalue(struct expression *expr)
953 int new = new_pseudo();
954 long double value = expr->fvalue;
956 printf("\tmovf.%d\t\tv%d,$%Lf\n", expr->ctype->bit_size, new, value);
957 return new;
960 static int show_string_expr(struct expression *expr)
962 int new = new_pseudo();
964 printf("\tmovi.%d\t\tv%d,&%s\n", bits_in_pointer, new, show_string(expr->string));
965 return new;
968 static int show_label_expr(struct expression *expr)
970 int new = new_pseudo();
971 printf("\tmovi.%d\t\tv%d,.L%p\n",bits_in_pointer, new, expr->label_symbol);
972 return new;
975 static int show_conditional_expr(struct expression *expr)
977 int cond = show_expression(expr->conditional);
978 int true = show_expression(expr->cond_true);
979 int false = show_expression(expr->cond_false);
980 int new = new_pseudo();
982 printf("[v%d]\tcmov.%d\t\tv%d,v%d,v%d\n", cond, expr->ctype->bit_size, new, true, false);
983 return new;
986 static int show_statement_expr(struct expression *expr)
988 return show_statement(expr->statement);
991 static int show_position_expr(struct expression *expr, struct symbol *base)
993 int new = show_expression(expr->init_expr);
994 struct symbol *ctype = expr->init_expr->ctype;
995 int bit_offset;
997 bit_offset = ctype ? ctype->bit_offset : -1;
999 printf("\tinsert v%d at [%d:%d] of %s\n", new,
1000 expr->init_offset, bit_offset,
1001 show_ident(base->ident));
1002 return 0;
1005 static int show_initializer_expr(struct expression *expr, struct symbol *ctype)
1007 struct expression *entry;
1009 FOR_EACH_PTR(expr->expr_list, entry) {
1011 again:
1012 // Nested initializers have their positions already
1013 // recursively calculated - just output them too
1014 if (entry->type == EXPR_INITIALIZER) {
1015 show_initializer_expr(entry, ctype);
1016 continue;
1019 // Initializer indexes and identifiers should
1020 // have been evaluated to EXPR_POS
1021 if (entry->type == EXPR_IDENTIFIER) {
1022 printf(" AT '%s':\n", show_ident(entry->expr_ident));
1023 entry = entry->ident_expression;
1024 goto again;
1027 if (entry->type == EXPR_INDEX) {
1028 printf(" AT '%d..%d:\n", entry->idx_from, entry->idx_to);
1029 entry = entry->idx_expression;
1030 goto again;
1032 if (entry->type == EXPR_POS) {
1033 show_position_expr(entry, ctype);
1034 continue;
1036 show_initialization(ctype, entry);
1037 } END_FOR_EACH_PTR(entry);
1038 return 0;
1041 int show_symbol_expr_init(struct symbol *sym)
1043 struct expression *expr = sym->initializer;
1045 if (expr)
1046 show_expression(expr);
1047 return show_symbol_expr(sym);
1051 * Print out an expression. Return the pseudo that contains the
1052 * variable.
1054 int show_expression(struct expression *expr)
1056 if (!expr)
1057 return 0;
1059 if (!expr->ctype) {
1060 struct position *pos = &expr->pos;
1061 printf("\tno type at %s:%d:%d\n",
1062 stream_name(pos->stream),
1063 pos->line, pos->pos);
1064 return 0;
1067 switch (expr->type) {
1068 case EXPR_CALL:
1069 return show_call_expression(expr);
1071 case EXPR_ASSIGNMENT:
1072 return show_assignment(expr);
1074 case EXPR_COMMA:
1075 return show_comma(expr);
1076 case EXPR_BINOP:
1077 case EXPR_COMPARE:
1078 case EXPR_LOGICAL:
1079 return show_binop(expr);
1080 case EXPR_PREOP:
1081 return show_preop(expr);
1082 case EXPR_POSTOP:
1083 return show_postop(expr);
1084 case EXPR_SYMBOL:
1085 return show_symbol_expr(expr->symbol);
1086 case EXPR_DEREF:
1087 case EXPR_SIZEOF:
1088 case EXPR_PTRSIZEOF:
1089 case EXPR_ALIGNOF:
1090 case EXPR_OFFSETOF:
1091 warning(expr->pos, "invalid expression after evaluation");
1092 return 0;
1093 case EXPR_CAST:
1094 case EXPR_FORCE_CAST:
1095 case EXPR_IMPLIED_CAST:
1096 return show_cast_expr(expr);
1097 case EXPR_VALUE:
1098 return show_value(expr);
1099 case EXPR_FVALUE:
1100 return show_fvalue(expr);
1101 case EXPR_STRING:
1102 return show_string_expr(expr);
1103 case EXPR_INITIALIZER:
1104 return show_initializer_expr(expr, expr->ctype);
1105 case EXPR_SELECT:
1106 case EXPR_CONDITIONAL:
1107 return show_conditional_expr(expr);
1108 case EXPR_STATEMENT:
1109 return show_statement_expr(expr);
1110 case EXPR_LABEL:
1111 return show_label_expr(expr);
1112 case EXPR_SLICE:
1113 return show_slice(expr);
1115 // None of these should exist as direct expressions: they are only
1116 // valid as sub-expressions of initializers.
1117 case EXPR_POS:
1118 warning(expr->pos, "unable to show plain initializer position expression");
1119 return 0;
1120 case EXPR_IDENTIFIER:
1121 warning(expr->pos, "unable to show identifier expression");
1122 return 0;
1123 case EXPR_INDEX:
1124 warning(expr->pos, "unable to show index expression");
1125 return 0;
1126 case EXPR_TYPE:
1127 warning(expr->pos, "unable to show type expression");
1128 return 0;
1130 return 0;