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