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