[hackers] [scc] [cc2-qbe] Move preambule to code instructions || Roberto E. Vargas Caballero
commit 5ef65b780276437e03c0028b418a6be0ef23eba6
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Fri Jun 17 13:28:26 2016 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Fri Jun 17 13:34:58 2016 +0200
[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.
diff --git a/cc2/arch/qbe/arch.h b/cc2/arch/qbe/arch.h
index e6af112..512511e 100644
--- a/cc2/arch/qbe/arch.h
+++ b/cc2/arch/qbe/arch.h
_AT_@ -141,4 +141,6 @@ enum asmop {
ASCALL,
ASPAR,
ASPARE,
+ ASALLOC,
+ ASFORM,
};
diff --git a/cc2/arch/qbe/cgen.c b/cc2/arch/qbe/cgen.c
index 8253d2b..101a393 100644
--- a/cc2/arch/qbe/cgen.c
+++ b/cc2/arch/qbe/cgen.c
_AT_@ -351,6 +351,30 @@ ternary(Node *np)
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)
_AT_@ -374,6 +398,10 @@ cgen(Node *np)
switch (np->op) {
case OSTRING:
abort();
+ case OBFUN:
+ return function();
+ case OEFUN:
+ return NULL;
case OCONST:
case OLABEL:
np->flags |= ISCONS;
diff --git a/cc2/arch/qbe/code.c b/cc2/arch/qbe/code.c
index 805ff0b..a856a35 100644
--- a/cc2/arch/qbe/code.c
+++ b/cc2/arch/qbe/code.c
_AT_@ -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);
_AT_@ -135,6 +136,8 @@ static struct opdata {
[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];
_AT_@ -295,16 +298,6 @@ data(Node *np)
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)
{
_AT_@ -324,24 +317,6 @@ writeout(void)
}
puts(")\n{\n_AT_.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)
_AT_@ -349,8 +324,6 @@ writeout(void)
if (pc->op)
(*optbl[pc->op].fun)();
}
- if (!prog)
- puts("\t\tret");
puts("}");
}
_AT_@ -461,6 +434,27 @@ branch(void)
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
endinit(void)
{
diff --git a/cc2/cc2.h b/cc2/cc2.h
index 13a7b8d..1883d04 100644
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
_AT_@ -106,6 +106,8 @@ enum op {
ODEFAULT = 'f',
OBSWITCH = 's',
OESWITCH = 't',
+ OBFUN = 'x',
+ OEFUN = 'k',
};
enum nerrors {
diff --git a/cc2/parser.c b/cc2/parser.c
index ab54632..fa1eae0 100644
--- a/cc2/parser.c
+++ b/cc2/parser.c
_AT_@ -630,12 +630,14 @@ beginfun(void)
{
inpars = 1;
pushctx();
+ addstmt(newnode(OBFUN), SETCUR);
}
static void
endfun(void)
{
endf = 1;
+ addstmt(newnode(OEFUN), SETCUR);
}
void
Received on Fri Jun 17 2016 - 14:02:46 CEST
This archive was generated by hypermail 2.3.0
: Fri Jun 17 2016 - 14:12:23 CEST