xref: /illumos-gate/usr/src/tools/smatch/src/show-parse.c (revision 1f5207b7604fb44407eb4342aff613f7c4508508)
1 /*
2  * sparse/show-parse.c
3  *
4  * Copyright (C) 2003 Transmeta Corp.
5  *               2003-2004 Linus Torvalds
6  *
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:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
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.
24  *
25  * Print out results of parsing for debugging and testing.
26  */
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>
34 
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"
43 
44 static int show_symbol_expr(struct symbol *sym);
45 static int show_string_expr(struct expression *expr);
46 
47 static void do_debug_symbol(struct symbol *sym, int indent)
48 {
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.",
69 	};
70 	struct context *context;
71 	int i;
72 
73 	if (!sym)
74 		return;
75 	fprintf(stderr, "%.*s%s%3d:%lu %s %s (as: %d) %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), 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);
98 	}
99 	do_debug_symbol(sym->ctype.base_type, indent+2);
100 }
101 
102 void debug_symbol(struct symbol *sym)
103 {
104 	do_debug_symbol(sym, 0);
105 }
106 
107 /*
108  * Symbol type printout. The type system is by far the most
109  * complicated part of C - everything else is trivial.
110  */
111 const char *modifier_string(unsigned long mod)
112 {
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;
120 
121 	static struct mod_name mod_names[] = {
122 		{MOD_AUTO,		"auto"},
123 		{MOD_REGISTER,		"register"},
124 		{MOD_STATIC,		"static"},
125 		{MOD_EXTERN,		"extern"},
126 		{MOD_CONST,		"const"},
127 		{MOD_VOLATILE,		"volatile"},
128 		{MOD_SIGNED,		"[signed]"},
129 		{MOD_UNSIGNED,		"[unsigned]"},
130 		{MOD_CHAR,		"[char]"},
131 		{MOD_SHORT,		"[short]"},
132 		{MOD_LONG,		"[long]"},
133 		{MOD_LONGLONG,		"[long long]"},
134 		{MOD_LONGLONGLONG,	"[long long long]"},
135 		{MOD_TYPEDEF,		"[typedef]"},
136 		{MOD_TLS,		"[tls]"},
137 		{MOD_INLINE,		"inline"},
138 		{MOD_ADDRESSABLE,	"[addressable]"},
139 		{MOD_NOCAST,		"[nocast]"},
140 		{MOD_NODEREF,		"[noderef]"},
141 		{MOD_ACCESSED,		"[accessed]"},
142 		{MOD_TOPLEVEL,		"[toplevel]"},
143 		{MOD_ASSIGNED,		"[assigned]"},
144 		{MOD_TYPE,		"[type]"},
145 		{MOD_SAFE,		"[safe]"},
146 		{MOD_USERTYPE,		"[usertype]"},
147 		{MOD_NORETURN,		"[noreturn]"},
148 		{MOD_EXPLICITLY_SIGNED,	"[explicitly-signed]"},
149 		{MOD_BITWISE,		"[bitwise]"},
150 		{MOD_PURE,		"[pure]"},
151 	};
152 
153 	for (i = 0; i < ARRAY_SIZE(mod_names); i++) {
154 		m = mod_names + i;
155 		if (mod & m->mod) {
156 			char c;
157 			const char *name = m->name;
158 			while ((c = *name++) != '\0' && len + 2 < sizeof buffer)
159 				buffer[len++] = c;
160 			buffer[len++] = ' ';
161 		}
162 	}
163 	buffer[len] = 0;
164 	return buffer;
165 }
166 
167 static void show_struct_member(struct symbol *sym)
168 {
169 	printf("\t%s:%d:%ld at offset %ld.%d", show_ident(sym->ident), sym->bit_size, sym->ctype.alignment, sym->offset, sym->bit_offset);
170 	printf("\n");
171 }
172 
173 void show_symbol_list(struct symbol_list *list, const char *sep)
174 {
175 	struct symbol *sym;
176 	const char *prepend = "";
177 
178 	FOR_EACH_PTR(list, sym) {
179 		puts(prepend);
180 		prepend = ", ";
181 		show_symbol(sym);
182 	} END_FOR_EACH_PTR(sym);
183 }
184 
185 struct type_name {
186 	char *start;
187 	char *end;
188 };
189 
190 static void FORMAT_ATTR(2) prepend(struct type_name *name, const char *fmt, ...)
191 {
192 	static char buffer[512];
193 	int n;
194 
195 	va_list args;
196 	va_start(args, fmt);
197 	n = vsprintf(buffer, fmt, args);
198 	va_end(args);
199 
200 	name->start -= n;
201 	memcpy(name->start, buffer, n);
202 }
203 
204 static void FORMAT_ATTR(2) append(struct type_name *name, const char *fmt, ...)
205 {
206 	static char buffer[512];
207 	int n;
208 
209 	va_list args;
210 	va_start(args, fmt);
211 	n = vsprintf(buffer, fmt, args);
212 	va_end(args);
213 
214 	memcpy(name->end, buffer, n);
215 	name->end += n;
216 }
217 
218 static struct ctype_name {
219 	struct symbol *sym;
220 	const char *name;
221 } typenames[] = {
222 	{ & char_ctype,  "char" },
223 	{ &schar_ctype,  "signed char" },
224 	{ &uchar_ctype,  "unsigned char" },
225 	{ & short_ctype, "short" },
226 	{ &sshort_ctype, "signed short" },
227 	{ &ushort_ctype, "unsigned short" },
228 	{ & int_ctype,   "int" },
229 	{ &sint_ctype,   "signed int" },
230 	{ &uint_ctype,   "unsigned int" },
231 	{ &slong_ctype,  "signed long" },
232 	{ & long_ctype,  "long" },
233 	{ &ulong_ctype,  "unsigned long" },
234 	{ & llong_ctype, "long long" },
235 	{ &sllong_ctype, "signed long long" },
236 	{ &ullong_ctype, "unsigned long long" },
237 	{ & lllong_ctype, "long long long" },
238 	{ &slllong_ctype, "signed long long long" },
239 	{ &ulllong_ctype, "unsigned long long long" },
240 
241 	{ &void_ctype,   "void" },
242 	{ &bool_ctype,   "bool" },
243 	{ &string_ctype, "string" },
244 
245 	{ &float_ctype,  "float" },
246 	{ &double_ctype, "double" },
247 	{ &ldouble_ctype,"long double" },
248 	{ &incomplete_ctype, "incomplete type" },
249 	{ &int_type, "abstract int" },
250 	{ &fp_type, "abstract fp" },
251 	{ &label_ctype, "label type" },
252 	{ &bad_ctype, "bad type" },
253 };
254 
255 const char *builtin_typename(struct symbol *sym)
256 {
257 	int i;
258 
259 	for (i = 0; i < ARRAY_SIZE(typenames); i++)
260 		if (typenames[i].sym == sym)
261 			return typenames[i].name;
262 	return NULL;
263 }
264 
265 const char *builtin_ctypename(struct ctype *ctype)
266 {
267 	int i;
268 
269 	for (i = 0; i < ARRAY_SIZE(typenames); i++)
270 		if (&typenames[i].sym->ctype == ctype)
271 			return typenames[i].name;
272 	return NULL;
273 }
274 
275 static void do_show_type(struct symbol *sym, struct type_name *name)
276 {
277 	const char *typename;
278 	unsigned long mod = 0;
279 	int as = 0;
280 	int was_ptr = 0;
281 	int restr = 0;
282 	int fouled = 0;
283 
284 deeper:
285 	if (!sym || (sym->type != SYM_NODE && sym->type != SYM_ARRAY &&
286 		     sym->type != SYM_BITFIELD)) {
287 		const char *s;
288 		size_t len;
289 
290 		if (as)
291 			prepend(name, "<asn:%d>", as);
292 
293 		s = modifier_string(mod);
294 		len = strlen(s);
295 		name->start -= len;
296 		memcpy(name->start, s, len);
297 		mod = 0;
298 		as = 0;
299 	}
300 
301 	if (!sym)
302 		goto out;
303 
304 	if ((typename = builtin_typename(sym))) {
305 		int len = strlen(typename);
306 		if (name->start != name->end)
307 			*--name->start = ' ';
308 		name->start -= len;
309 		memcpy(name->start, typename, len);
310 		goto out;
311 	}
312 
313 	/* Prepend */
314 	switch (sym->type) {
315 	case SYM_PTR:
316 		prepend(name, "*");
317 		mod = sym->ctype.modifiers;
318 		as = sym->ctype.as;
319 		was_ptr = 1;
320 		break;
321 
322 	case SYM_FN:
323 		if (was_ptr) {
324 			prepend(name, "( ");
325 			append(name, " )");
326 			was_ptr = 0;
327 		}
328 		append(name, "( ... )");
329 		break;
330 
331 	case SYM_STRUCT:
332 		if (name->start != name->end)
333 			*--name->start = ' ';
334 		prepend(name, "struct %s", show_ident(sym->ident));
335 		goto out;
336 
337 	case SYM_UNION:
338 		if (name->start != name->end)
339 			*--name->start = ' ';
340 		prepend(name, "union %s", show_ident(sym->ident));
341 		goto out;
342 
343 	case SYM_ENUM:
344 		prepend(name, "enum %s ", show_ident(sym->ident));
345 		break;
346 
347 	case SYM_NODE:
348 		append(name, "%s", show_ident(sym->ident));
349 		mod |= sym->ctype.modifiers;
350 		as |= sym->ctype.as;
351 		break;
352 
353 	case SYM_BITFIELD:
354 		mod |= sym->ctype.modifiers;
355 		as |= sym->ctype.as;
356 		append(name, ":%d", sym->bit_size);
357 		break;
358 
359 	case SYM_LABEL:
360 		append(name, "label(%s:%p)", show_ident(sym->ident), sym);
361 		return;
362 
363 	case SYM_ARRAY:
364 		mod |= sym->ctype.modifiers;
365 		as |= sym->ctype.as;
366 		if (was_ptr) {
367 			prepend(name, "( ");
368 			append(name, " )");
369 			was_ptr = 0;
370 		}
371 		append(name, "[%lld]", get_expression_value(sym->array_size));
372 		break;
373 
374 	case SYM_RESTRICT:
375 		if (!sym->ident) {
376 			restr = 1;
377 			break;
378 		}
379 		if (name->start != name->end)
380 			*--name->start = ' ';
381 		prepend(name, "restricted %s", show_ident(sym->ident));
382 		goto out;
383 
384 	case SYM_FOULED:
385 		fouled = 1;
386 		break;
387 
388 	default:
389 		if (name->start != name->end)
390 			*--name->start = ' ';
391 		prepend(name, "unknown type %d", sym->type);
392 		goto out;
393 	}
394 
395 	sym = sym->ctype.base_type;
396 	goto deeper;
397 
398 out:
399 	if (restr)
400 		prepend(name, "restricted ");
401 	if (fouled)
402 		prepend(name, "fouled ");
403 }
404 
405 void show_type(struct symbol *sym)
406 {
407 	char array[200];
408 	struct type_name name;
409 
410 	name.start = name.end = array+100;
411 	do_show_type(sym, &name);
412 	*name.end = 0;
413 	printf("%s", name.start);
414 }
415 
416 const char *show_typename(struct symbol *sym)
417 {
418 	static char array[200];
419 	struct type_name name;
420 
421 	name.start = name.end = array+100;
422 	do_show_type(sym, &name);
423 	*name.end = 0;
424 	return name.start;
425 }
426 
427 void show_symbol(struct symbol *sym)
428 {
429 	struct symbol *type;
430 
431 	if (!sym)
432 		return;
433 
434 	if (sym->ctype.alignment)
435 		printf(".align %ld\n", sym->ctype.alignment);
436 
437 	show_type(sym);
438 	type = sym->ctype.base_type;
439 	if (!type) {
440 		printf("\n");
441 		return;
442 	}
443 
444 	/*
445 	 * Show actual implementation information
446 	 */
447 	switch (type->type) {
448 		struct symbol *member;
449 
450 	case SYM_STRUCT:
451 	case SYM_UNION:
452 		printf(" {\n");
453 		FOR_EACH_PTR(type->symbol_list, member) {
454 			show_struct_member(member);
455 		} END_FOR_EACH_PTR(member);
456 		printf("}\n");
457 		break;
458 
459 	case SYM_FN: {
460 		struct statement *stmt = type->stmt;
461 		printf("\n");
462 		if (stmt) {
463 			int val;
464 			val = show_statement(stmt);
465 			if (val)
466 				printf("\tmov.%d\t\tretval,%d\n", stmt->ret->bit_size, val);
467 			printf("\tret\n");
468 		}
469 		break;
470 	}
471 
472 	default:
473 		printf("\n");
474 		break;
475 	}
476 
477 	if (sym->initializer) {
478 		printf(" = \n");
479 		show_expression(sym->initializer);
480 	}
481 }
482 
483 static int show_symbol_init(struct symbol *sym);
484 
485 static int new_pseudo(void)
486 {
487 	static int nr = 0;
488 	return ++nr;
489 }
490 
491 static int new_label(void)
492 {
493 	static int label = 0;
494 	return ++label;
495 }
496 
497 static void show_switch_statement(struct statement *stmt)
498 {
499 	int val = show_expression(stmt->switch_expression);
500 	struct symbol *sym;
501 	printf("\tswitch v%d\n", val);
502 
503 	/*
504 	 * Debugging only: Check that the case list is correct
505 	 * by printing it out.
506 	 *
507 	 * This is where a _real_ back-end would go through the
508 	 * cases to decide whether to use a lookup table or a
509 	 * series of comparisons etc
510 	 */
511 	printf("# case table:\n");
512 	FOR_EACH_PTR(stmt->switch_case->symbol_list, sym) {
513 		struct statement *case_stmt = sym->stmt;
514 		struct expression *expr = case_stmt->case_expression;
515 		struct expression *to = case_stmt->case_to;
516 
517 		if (!expr) {
518 			printf("    default");
519 		} else {
520 			if (expr->type == EXPR_VALUE) {
521 				printf("    case %lld", expr->value);
522 				if (to) {
523 					if (to->type == EXPR_VALUE) {
524 						printf(" .. %lld", to->value);
525 					} else {
526 						printf(" .. what?");
527 					}
528 				}
529 			} else
530 				printf("    what?");
531 		}
532 		printf(": .L%p\n", sym);
533 	} END_FOR_EACH_PTR(sym);
534 	printf("# end case table\n");
535 
536 	show_statement(stmt->switch_statement);
537 
538 	if (stmt->switch_break->used)
539 		printf(".L%p:\n", stmt->switch_break);
540 }
541 
542 static void show_symbol_decl(struct symbol_list *syms)
543 {
544 	struct symbol *sym;
545 	FOR_EACH_PTR(syms, sym) {
546 		show_symbol_init(sym);
547 	} END_FOR_EACH_PTR(sym);
548 }
549 
550 static int show_return_stmt(struct statement *stmt);
551 
552 /*
553  * Print out a statement
554  */
555 int show_statement(struct statement *stmt)
556 {
557 	if (!stmt)
558 		return 0;
559 	switch (stmt->type) {
560 	case STMT_DECLARATION:
561 		show_symbol_decl(stmt->declaration);
562 		return 0;
563 	case STMT_RETURN:
564 		return show_return_stmt(stmt);
565 	case STMT_COMPOUND: {
566 		struct statement *s;
567 		int last = 0;
568 
569 		if (stmt->inline_fn) {
570 			show_statement(stmt->args);
571 			printf("\tbegin_inline \t%s\n", show_ident(stmt->inline_fn->ident));
572 		}
573 		FOR_EACH_PTR(stmt->stmts, s) {
574 			last = show_statement(s);
575 		} END_FOR_EACH_PTR(s);
576 		if (stmt->ret) {
577 			int addr, bits;
578 			printf(".L%p:\n", stmt->ret);
579 			addr = show_symbol_expr(stmt->ret);
580 			bits = stmt->ret->bit_size;
581 			last = new_pseudo();
582 			printf("\tld.%d\t\tv%d,[v%d]\n", bits, last, addr);
583 		}
584 		if (stmt->inline_fn)
585 			printf("\tend_inlined\t%s\n", show_ident(stmt->inline_fn->ident));
586 		return last;
587 	}
588 
589 	case STMT_EXPRESSION:
590 		return show_expression(stmt->expression);
591 	case STMT_IF: {
592 		int val, target;
593 		struct expression *cond = stmt->if_conditional;
594 
595 /* This is only valid if nobody can jump into the "dead" statement */
596 #if 0
597 		if (cond->type == EXPR_VALUE) {
598 			struct statement *s = stmt->if_true;
599 			if (!cond->value)
600 				s = stmt->if_false;
601 			show_statement(s);
602 			break;
603 		}
604 #endif
605 		val = show_expression(cond);
606 		target = new_label();
607 		printf("\tje\t\tv%d,.L%d\n", val, target);
608 		show_statement(stmt->if_true);
609 		if (stmt->if_false) {
610 			int last = new_label();
611 			printf("\tjmp\t\t.L%d\n", last);
612 			printf(".L%d:\n", target);
613 			target = last;
614 			show_statement(stmt->if_false);
615 		}
616 		printf(".L%d:\n", target);
617 		break;
618 	}
619 	case STMT_SWITCH:
620 		show_switch_statement(stmt);
621 		break;
622 
623 	case STMT_CASE:
624 		printf(".L%p:\n", stmt->case_label);
625 		show_statement(stmt->case_statement);
626 		break;
627 
628 	case STMT_ITERATOR: {
629 		struct statement  *pre_statement = stmt->iterator_pre_statement;
630 		struct expression *pre_condition = stmt->iterator_pre_condition;
631 		struct statement  *statement = stmt->iterator_statement;
632 		struct statement  *post_statement = stmt->iterator_post_statement;
633 		struct expression *post_condition = stmt->iterator_post_condition;
634 		int val, loop_top = 0, loop_bottom = 0;
635 
636 		show_symbol_decl(stmt->iterator_syms);
637 		show_statement(pre_statement);
638 		if (pre_condition) {
639 			if (pre_condition->type == EXPR_VALUE) {
640 				if (!pre_condition->value) {
641 					loop_bottom = new_label();
642 					printf("\tjmp\t\t.L%d\n", loop_bottom);
643 				}
644 			} else {
645 				loop_bottom = new_label();
646 				val = show_expression(pre_condition);
647 				printf("\tje\t\tv%d, .L%d\n", val, loop_bottom);
648 			}
649 		}
650 		if (!post_condition || post_condition->type != EXPR_VALUE || post_condition->value) {
651 			loop_top = new_label();
652 			printf(".L%d:\n", loop_top);
653 		}
654 		show_statement(statement);
655 		if (stmt->iterator_continue->used)
656 			printf(".L%p:\n", stmt->iterator_continue);
657 		show_statement(post_statement);
658 		if (!post_condition) {
659 			printf("\tjmp\t\t.L%d\n", loop_top);
660 		} else if (post_condition->type == EXPR_VALUE) {
661 			if (post_condition->value)
662 				printf("\tjmp\t\t.L%d\n", loop_top);
663 		} else {
664 			val = show_expression(post_condition);
665 			printf("\tjne\t\tv%d, .L%d\n", val, loop_top);
666 		}
667 		if (stmt->iterator_break->used)
668 			printf(".L%p:\n", stmt->iterator_break);
669 		if (loop_bottom)
670 			printf(".L%d:\n", loop_bottom);
671 		break;
672 	}
673 	case STMT_NONE:
674 		break;
675 
676 	case STMT_LABEL:
677 		printf(".L%p:\n", stmt->label_identifier);
678 		show_statement(stmt->label_statement);
679 		break;
680 
681 	case STMT_GOTO:
682 		if (stmt->goto_expression) {
683 			int val = show_expression(stmt->goto_expression);
684 			printf("\tgoto\t\t*v%d\n", val);
685 		} else {
686 			printf("\tgoto\t\t.L%p\n", stmt->goto_label);
687 		}
688 		break;
689 	case STMT_ASM:
690 		printf("\tasm( .... )\n");
691 		break;
692 	case STMT_CONTEXT: {
693 		int val = show_expression(stmt->expression);
694 		printf("\tcontext( %d )\n", val);
695 		break;
696 	}
697 	case STMT_RANGE: {
698 		int val = show_expression(stmt->range_expression);
699 		int low = show_expression(stmt->range_low);
700 		int high = show_expression(stmt->range_high);
701 		printf("\trange( %d %d-%d)\n", val, low, high);
702 		break;
703 	}
704 	}
705 	return 0;
706 }
707 
708 static int show_call_expression(struct expression *expr)
709 {
710 	struct symbol *direct;
711 	struct expression *arg, *fn;
712 	int fncall, retval;
713 	int framesize;
714 
715 	if (!expr->ctype) {
716 		warning(expr->pos, "\tcall with no type!");
717 		return 0;
718 	}
719 
720 	framesize = 0;
721 	FOR_EACH_PTR_REVERSE(expr->args, arg) {
722 		int new = show_expression(arg);
723 		int size = arg->ctype->bit_size;
724 		printf("\tpush.%d\t\tv%d\n", size, new);
725 		framesize += bits_to_bytes(size);
726 	} END_FOR_EACH_PTR_REVERSE(arg);
727 
728 	fn = expr->fn;
729 
730 	/* Remove dereference, if any */
731 	direct = NULL;
732 	if (fn->type == EXPR_PREOP) {
733 		if (fn->unop->type == EXPR_SYMBOL) {
734 			struct symbol *sym = fn->unop->symbol;
735 			if (sym->ctype.base_type->type == SYM_FN)
736 				direct = sym;
737 		}
738 	}
739 	if (direct) {
740 		printf("\tcall\t\t%s\n", show_ident(direct->ident));
741 	} else {
742 		fncall = show_expression(fn);
743 		printf("\tcall\t\t*v%d\n", fncall);
744 	}
745 	if (framesize)
746 		printf("\tadd.%d\t\tvSP,vSP,$%d\n", bits_in_pointer, framesize);
747 
748 	retval = new_pseudo();
749 	printf("\tmov.%d\t\tv%d,retval\n", expr->ctype->bit_size, retval);
750 	return retval;
751 }
752 
753 static int show_comma(struct expression *expr)
754 {
755 	show_expression(expr->left);
756 	return show_expression(expr->right);
757 }
758 
759 static int show_binop(struct expression *expr)
760 {
761 	int left = show_expression(expr->left);
762 	int right = show_expression(expr->right);
763 	int new = new_pseudo();
764 	const char *opname;
765 	static const char *name[] = {
766 		['+'] = "add", ['-'] = "sub",
767 		['*'] = "mul", ['/'] = "div",
768 		['%'] = "mod", ['&'] = "and",
769 		['|'] = "lor", ['^'] = "xor"
770 	};
771 	unsigned int op = expr->op;
772 
773 	opname = show_special(op);
774 	if (op < ARRAY_SIZE(name))
775 		opname = name[op];
776 	printf("\t%s.%d\t\tv%d,v%d,v%d\n", opname,
777 		expr->ctype->bit_size,
778 		new, left, right);
779 	return new;
780 }
781 
782 static int show_slice(struct expression *expr)
783 {
784 	int target = show_expression(expr->base);
785 	int new = new_pseudo();
786 	printf("\tslice.%d\t\tv%d,v%d,%d\n", expr->r_nrbits, target, new, expr->r_bitpos);
787 	return new;
788 }
789 
790 static int show_regular_preop(struct expression *expr)
791 {
792 	int target = show_expression(expr->unop);
793 	int new = new_pseudo();
794 	static const char *name[] = {
795 		['!'] = "nonzero", ['-'] = "neg",
796 		['~'] = "not",
797 	};
798 	unsigned int op = expr->op;
799 	const char *opname;
800 
801 	opname = show_special(op);
802 	if (op < ARRAY_SIZE(name))
803 		opname = name[op];
804 	printf("\t%s.%d\t\tv%d,v%d\n", opname, expr->ctype->bit_size, new, target);
805 	return new;
806 }
807 
808 /*
809  * FIXME! Not all accesses are memory loads. We should
810  * check what kind of symbol is behind the dereference.
811  */
812 static int show_address_gen(struct expression *expr)
813 {
814 	return show_expression(expr->unop);
815 }
816 
817 static int show_load_gen(int bits, struct expression *expr, int addr)
818 {
819 	int new = new_pseudo();
820 
821 	printf("\tld.%d\t\tv%d,[v%d]\n", bits, new, addr);
822 	return new;
823 }
824 
825 static void show_store_gen(int bits, int value, struct expression *expr, int addr)
826 {
827 	/* FIXME!!! Bitfield store! */
828 	printf("\tst.%d\t\tv%d,[v%d]\n", bits, value, addr);
829 }
830 
831 static int show_assignment(struct expression *expr)
832 {
833 	struct expression *target = expr->left;
834 	int val, addr, bits;
835 
836 	if (!expr->ctype)
837 		return 0;
838 
839 	bits = expr->ctype->bit_size;
840 	val = show_expression(expr->right);
841 	addr = show_address_gen(target);
842 	show_store_gen(bits, val, target, addr);
843 	return val;
844 }
845 
846 static int show_return_stmt(struct statement *stmt)
847 {
848 	struct expression *expr = stmt->ret_value;
849 	struct symbol *target = stmt->ret_target;
850 
851 	if (expr && expr->ctype) {
852 		int val = show_expression(expr);
853 		int bits = expr->ctype->bit_size;
854 		int addr = show_symbol_expr(target);
855 		show_store_gen(bits, val, NULL, addr);
856 	}
857 	printf("\tret\t\t(%p)\n", target);
858 	return 0;
859 }
860 
861 static int show_initialization(struct symbol *sym, struct expression *expr)
862 {
863 	int val, addr, bits;
864 
865 	if (!expr->ctype)
866 		return 0;
867 
868 	bits = expr->ctype->bit_size;
869 	val = show_expression(expr);
870 	addr = show_symbol_expr(sym);
871 	// FIXME! The "target" expression is for bitfield store information.
872 	// Leave it NULL, which works fine.
873 	show_store_gen(bits, val, NULL, addr);
874 	return 0;
875 }
876 
877 static int show_access(struct expression *expr)
878 {
879 	int addr = show_address_gen(expr);
880 	return show_load_gen(expr->ctype->bit_size, expr, addr);
881 }
882 
883 static int show_inc_dec(struct expression *expr, int postop)
884 {
885 	int addr = show_address_gen(expr->unop);
886 	int retval, new;
887 	const char *opname = expr->op == SPECIAL_INCREMENT ? "add" : "sub";
888 	int bits = expr->ctype->bit_size;
889 
890 	retval = show_load_gen(bits, expr->unop, addr);
891 	new = retval;
892 	if (postop)
893 		new = new_pseudo();
894 	printf("\t%s.%d\t\tv%d,v%d,$1\n", opname, bits, new, retval);
895 	show_store_gen(bits, new, expr->unop, addr);
896 	return retval;
897 }
898 
899 static int show_preop(struct expression *expr)
900 {
901 	/*
902 	 * '*' is an lvalue access, and is fundamentally different
903 	 * from an arithmetic operation. Maybe it should have an
904 	 * expression type of its own..
905 	 */
906 	if (expr->op == '*')
907 		return show_access(expr);
908 	if (expr->op == SPECIAL_INCREMENT || expr->op == SPECIAL_DECREMENT)
909 		return show_inc_dec(expr, 0);
910 	return show_regular_preop(expr);
911 }
912 
913 static int show_postop(struct expression *expr)
914 {
915 	return show_inc_dec(expr, 1);
916 }
917 
918 static int show_symbol_expr(struct symbol *sym)
919 {
920 	int new = new_pseudo();
921 
922 	if (sym->initializer && sym->initializer->type == EXPR_STRING)
923 		return show_string_expr(sym->initializer);
924 
925 	if (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_EXTERN | MOD_STATIC)) {
926 		printf("\tmovi.%d\t\tv%d,$%s\n", bits_in_pointer, new, show_ident(sym->ident));
927 		return new;
928 	}
929 	if (sym->ctype.modifiers & MOD_ADDRESSABLE) {
930 		printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer, new, sym->value);
931 		return new;
932 	}
933 	printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer, new, show_ident(sym->ident), sym);
934 	return new;
935 }
936 
937 static int show_symbol_init(struct symbol *sym)
938 {
939 	struct expression *expr = sym->initializer;
940 
941 	if (expr) {
942 		int val, addr, bits;
943 
944 		bits = expr->ctype->bit_size;
945 		val = show_expression(expr);
946 		addr = show_symbol_expr(sym);
947 		show_store_gen(bits, val, NULL, addr);
948 	}
949 	return 0;
950 }
951 
952 static int type_is_signed(struct symbol *sym)
953 {
954 	if (sym->type == SYM_NODE)
955 		sym = sym->ctype.base_type;
956 	if (sym->type == SYM_PTR)
957 		return 0;
958 	return !(sym->ctype.modifiers & MOD_UNSIGNED);
959 }
960 
961 static int show_cast_expr(struct expression *expr)
962 {
963 	struct symbol *old_type, *new_type;
964 	int op = show_expression(expr->cast_expression);
965 	int oldbits, newbits;
966 	int new, is_signed;
967 
968 	old_type = expr->cast_expression->ctype;
969 	new_type = expr->cast_type;
970 
971 	oldbits = old_type->bit_size;
972 	newbits = new_type->bit_size;
973 	if (oldbits >= newbits)
974 		return op;
975 	new = new_pseudo();
976 	is_signed = type_is_signed(old_type);
977 	if (is_signed) {
978 		printf("\tsext%d.%d\tv%d,v%d\n", oldbits, newbits, new, op);
979 	} else {
980 		printf("\tandl.%d\t\tv%d,v%d,$%lu\n", newbits, new, op, (1UL << oldbits)-1);
981 	}
982 	return new;
983 }
984 
985 static int show_value(struct expression *expr)
986 {
987 	int new = new_pseudo();
988 	unsigned long long value = expr->value;
989 
990 	printf("\tmovi.%d\t\tv%d,$%llu\n", expr->ctype->bit_size, new, value);
991 	return new;
992 }
993 
994 static int show_fvalue(struct expression *expr)
995 {
996 	int new = new_pseudo();
997 	long double value = expr->fvalue;
998 
999 	printf("\tmovf.%d\t\tv%d,$%Lf\n", expr->ctype->bit_size, new, value);
1000 	return new;
1001 }
1002 
1003 static int show_string_expr(struct expression *expr)
1004 {
1005 	int new = new_pseudo();
1006 
1007 	printf("\tmovi.%d\t\tv%d,&%s\n", bits_in_pointer, new, show_string(expr->string));
1008 	return new;
1009 }
1010 
1011 static int show_label_expr(struct expression *expr)
1012 {
1013 	int new = new_pseudo();
1014 	printf("\tmovi.%d\t\tv%d,.L%p\n",bits_in_pointer, new, expr->label_symbol);
1015 	return new;
1016 }
1017 
1018 static int show_conditional_expr(struct expression *expr)
1019 {
1020 	int cond = show_expression(expr->conditional);
1021 	int true = show_expression(expr->cond_true);
1022 	int false = show_expression(expr->cond_false);
1023 	int new = new_pseudo();
1024 
1025 	printf("[v%d]\tcmov.%d\t\tv%d,v%d,v%d\n", cond, expr->ctype->bit_size, new, true, false);
1026 	return new;
1027 }
1028 
1029 static int show_statement_expr(struct expression *expr)
1030 {
1031 	return show_statement(expr->statement);
1032 }
1033 
1034 static int show_position_expr(struct expression *expr, struct symbol *base)
1035 {
1036 	int new = show_expression(expr->init_expr);
1037 	struct symbol *ctype = expr->init_expr->ctype;
1038 	int bit_offset;
1039 
1040 	bit_offset = ctype ? ctype->bit_offset : -1;
1041 
1042 	printf("\tinsert v%d at [%d:%d] of %s\n", new,
1043 		expr->init_offset, bit_offset,
1044 		show_ident(base->ident));
1045 	return 0;
1046 }
1047 
1048 static int show_initializer_expr(struct expression *expr, struct symbol *ctype)
1049 {
1050 	struct expression *entry;
1051 
1052 	FOR_EACH_PTR(expr->expr_list, entry) {
1053 
1054 again:
1055 		// Nested initializers have their positions already
1056 		// recursively calculated - just output them too
1057 		if (entry->type == EXPR_INITIALIZER) {
1058 			show_initializer_expr(entry, ctype);
1059 			continue;
1060 		}
1061 
1062 		// Initializer indexes and identifiers should
1063 		// have been evaluated to EXPR_POS
1064 		if (entry->type == EXPR_IDENTIFIER) {
1065 			printf(" AT '%s':\n", show_ident(entry->expr_ident));
1066 			entry = entry->ident_expression;
1067 			goto again;
1068 		}
1069 
1070 		if (entry->type == EXPR_INDEX) {
1071 			printf(" AT '%d..%d:\n", entry->idx_from, entry->idx_to);
1072 			entry = entry->idx_expression;
1073 			goto again;
1074 		}
1075 		if (entry->type == EXPR_POS) {
1076 			show_position_expr(entry, ctype);
1077 			continue;
1078 		}
1079 		show_initialization(ctype, entry);
1080 	} END_FOR_EACH_PTR(entry);
1081 	return 0;
1082 }
1083 
1084 int show_symbol_expr_init(struct symbol *sym)
1085 {
1086 	struct expression *expr = sym->initializer;
1087 
1088 	if (expr)
1089 		show_expression(expr);
1090 	return show_symbol_expr(sym);
1091 }
1092 
1093 /*
1094  * Print out an expression. Return the pseudo that contains the
1095  * variable.
1096  */
1097 int show_expression(struct expression *expr)
1098 {
1099 	if (!expr)
1100 		return 0;
1101 
1102 	if (!expr->ctype) {
1103 		struct position *pos = &expr->pos;
1104 		printf("\tno type at %s:%d:%d\n",
1105 			stream_name(pos->stream),
1106 			pos->line, pos->pos);
1107 		return 0;
1108 	}
1109 
1110 	switch (expr->type) {
1111 	case EXPR_CALL:
1112 		return show_call_expression(expr);
1113 
1114 	case EXPR_ASSIGNMENT:
1115 		return show_assignment(expr);
1116 
1117 	case EXPR_COMMA:
1118 		return show_comma(expr);
1119 	case EXPR_BINOP:
1120 	case EXPR_COMPARE:
1121 	case EXPR_LOGICAL:
1122 		return show_binop(expr);
1123 	case EXPR_PREOP:
1124 		return show_preop(expr);
1125 	case EXPR_POSTOP:
1126 		return show_postop(expr);
1127 	case EXPR_SYMBOL:
1128 		return show_symbol_expr(expr->symbol);
1129 	case EXPR_DEREF:
1130 	case EXPR_SIZEOF:
1131 	case EXPR_PTRSIZEOF:
1132 	case EXPR_ALIGNOF:
1133 	case EXPR_OFFSETOF:
1134 		warning(expr->pos, "invalid expression after evaluation");
1135 		return 0;
1136 	case EXPR_CAST:
1137 	case EXPR_FORCE_CAST:
1138 	case EXPR_IMPLIED_CAST:
1139 		return show_cast_expr(expr);
1140 	case EXPR_VALUE:
1141 		return show_value(expr);
1142 	case EXPR_FVALUE:
1143 		return show_fvalue(expr);
1144 	case EXPR_STRING:
1145 		return show_string_expr(expr);
1146 	case EXPR_INITIALIZER:
1147 		return show_initializer_expr(expr, expr->ctype);
1148 	case EXPR_SELECT:
1149 	case EXPR_CONDITIONAL:
1150 		return show_conditional_expr(expr);
1151 	case EXPR_STATEMENT:
1152 		return show_statement_expr(expr);
1153 	case EXPR_LABEL:
1154 		return show_label_expr(expr);
1155 	case EXPR_SLICE:
1156 		return show_slice(expr);
1157 
1158 	// None of these should exist as direct expressions: they are only
1159 	// valid as sub-expressions of initializers.
1160 	case EXPR_POS:
1161 		warning(expr->pos, "unable to show plain initializer position expression");
1162 		return 0;
1163 	case EXPR_IDENTIFIER:
1164 		warning(expr->pos, "unable to show identifier expression");
1165 		return 0;
1166 	case EXPR_INDEX:
1167 		warning(expr->pos, "unable to show index expression");
1168 		return 0;
1169 	case EXPR_TYPE:
1170 		warning(expr->pos, "unable to show type expression");
1171 		return 0;
1172 	}
1173 	return 0;
1174 }
1175