shithub: scc

Download patch

ref: f83b3b72e8baead496893abecf170e118603689b
parent: a32d55dfcfb2b73c6643013962c8ca850984eaec
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Jun 17 09:28:26 EDT 2016

[cc2-qbe] Move preambule to code instructions

Until this moment the preambule was writing directly using
printfs calls, but it created some problems related to the
restrictions impossed by qbe about basic blocks. It was
really hard to detect the cases where we were forced
to emit labels to define the begin of a basic block.
With this new approach the preamble is a set of instructions
and we can define where we need labels using the function
introduced a few commits ago.

--- a/cc2/arch/qbe/arch.h
+++ b/cc2/arch/qbe/arch.h
@@ -141,4 +141,6 @@
 	ASCALL,
 	ASPAR,
 	ASPARE,
+	ASALLOC,
+	ASFORM,
 };
--- a/cc2/arch/qbe/cgen.c
+++ b/cc2/arch/qbe/cgen.c
@@ -351,6 +351,30 @@
 	return np;
 }
 
+static Node *
+function(void)
+{
+	Symbol *p;
+
+	/* allocate stack space for parameters */
+	for (p = locals; p && (p->type.flags & PARF) != 0; p = p->next)
+		code(ASALLOC, label2node(p), NULL, NULL);
+
+	/* allocate stack space for local variables) */
+	for ( ; p && p->id != TMPSYM; p = p->next) {
+		if (p->kind != SAUTO)
+			continue;
+		code(ASALLOC, label2node(p), NULL, NULL);
+	}
+	/* store formal parameters in parameters */
+	for (p = locals; p; p = p->next) {
+		if ((p->type.flags & PARF) == 0)
+			break;
+		code(ASFORM, label2node(p), NULL, NULL);
+	}
+	return NULL;
+}
+
 /* TODO: Fix "memory leaks" */
 Node *
 cgen(Node *np)
@@ -374,6 +398,10 @@
 	switch (np->op) {
 	case OSTRING:
 		abort();
+	case OBFUN:
+		return function();
+	case OEFUN:
+		return NULL;
 	case OCONST:
 	case OLABEL:
 		np->flags |= ISCONS;
--- a/cc2/arch/qbe/code.c
+++ b/cc2/arch/qbe/code.c
@@ -10,7 +10,8 @@
 #define ADDR_LEN (INTIDENTSIZ+64)
 
 static void binary(void), unary(void), store(void), jmp(void), ret(void),
-            branch(void), call(void), ecall(void), param(void);
+            branch(void), call(void), ecall(void), param(void),
+            alloc(void), form2local(void);
 
 static struct opdata {
 	void (*fun)(void);
@@ -135,6 +136,8 @@
 	[ASCALL] = {.fun = ecall},
 	[ASPAR] = {.fun = param, .txt = "%s %s, "},
 	[ASPARE] = {.fun = param, .txt = "%s %s"},
+	[ASALLOC] = {.fun = alloc},
+	[ASFORM] = {.fun = form2local},
 };
 
 static char buff[ADDR_LEN];
@@ -295,16 +298,6 @@
 	putchar('\n');
 }
 
-static void
-alloc(Symbol *sym)
-{
-	Type *tp = &sym->type;
-	extern Type ptrtype;
-
-	printf("\t%s =%s\talloc%lu\t%lu\n",
-	       symname(sym), size2asm(&ptrtype), tp->align+3 & ~3, tp->size );
-}
-
 void
 writeout(void)
 {
@@ -324,24 +317,6 @@
 	}
 	puts(")\n{\n@.start");
 
-	/* allocate stack space for parameters */
-	for (p = locals; p && (p->type.flags & PARF) != 0; p = p->next)
-		alloc(p);
-
-	/* allocate stack space for local variables) */
-	for ( ; p && p->id != TMPSYM; p = p->next) {
-		if (p->kind == SAUTO)
-			alloc(p);
-	}
-	/* store formal parameters in parameters */
-	for (p = locals; p; p = p->next) {
-		tp = &p->type;
-		if ((tp->flags & PARF) == 0)
-			break;
-		name = symname(p);
-		printf("\t\tstore%s\t%s.val,%s\n", size2asm(tp), name, name);
-	}
-
 	/* emit assembler instructions */
 	for (pc = prog; pc; pc = pc->next) {
 		if (pc->label)
@@ -349,8 +324,6 @@
 		if (pc->op)
 			(*optbl[pc->op].fun)();
 	}
-	if (!prog)
-		puts("\t\tret");
 
 	puts("}");
 }
@@ -459,6 +432,27 @@
 	strcpy(from1, addr2txt(&pc->from1));
 	strcpy(from2, addr2txt(&pc->from2));
 	printf("\t\tjnz\t%s,%s,%s\n", to, from1, from2);
+}
+
+static void
+alloc(void)
+{
+	Symbol *sym = pc->to.u.sym;
+	Type *tp = &sym->type;
+	extern Type ptrtype;
+
+	printf("\t%s =%s\talloc%lu\t%lu\n",
+	       symname(sym), size2asm(&ptrtype), tp->align+3 & ~3, tp->size);
+}
+
+static void
+form2local(void)
+{
+	Symbol *sym = pc->to.u.sym;
+	Type *tp = &sym->type;
+	char *name = symname(sym);
+
+	printf("\t\tstore%s\t%s.val,%s\n", size2asm(tp), name, name);
 }
 
 void
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
@@ -106,6 +106,8 @@
 	ODEFAULT = 'f',
 	OBSWITCH = 's',
 	OESWITCH = 't',
+	OBFUN    = 'x',
+	OEFUN    = 'k',
 };
 
 enum nerrors {
--- a/cc2/parser.c
+++ b/cc2/parser.c
@@ -630,6 +630,7 @@
 {
 	inpars = 1;
 	pushctx();
+	addstmt(newnode(OBFUN), SETCUR);
 }
 
 static void
@@ -636,6 +637,7 @@
 endfun(void)
 {
 	endf = 1;
+	addstmt(newnode(OEFUN), SETCUR);
 }
 
 void