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