commit 1cc0995ffaabe9f5abc298123ff591df5ca32ce0
parent 169482fbf00dd02608f6fa20c928bdf12a56363d
Author: Roberto E. Vargas Caballero <roberto.vargas@igrid-td.com>
Date: Thu, 7 Apr 2016 08:45:10 +0200
[cc2] Add defpar() and defvar()
Every target is going to do different things when a parameter
or a variable is declared, so the best thing we can do is to
create new functions to signal them these parsing events.
Diffstat:
8 files changed, 192 insertions(+), 46 deletions(-)
diff --git a/cc2/arch/amd64-sysv/code.c b/cc2/arch/amd64-sysv/code.c
@@ -174,16 +174,31 @@ label(Symbol *sym)
}
void
-defsym(Symbol *sym, int alloc)
+defglobal(Symbol *sym)
{
label(sym);
- if (!alloc || (sym->type.flags & INITF))
+ if (sym->kind == EXTRN || (sym->type.flags & INITF))
return;
size2asm(&sym->type);
puts("0");
}
void
+defvar(Symbol *sym)
+{
+}
+
+void
+defpar(Symbol *sym)
+{
+}
+
+void
+newfun(void)
+{
+}
+
+void
writeout(void)
{
}
diff --git a/cc2/arch/i386-sysv/code.c b/cc2/arch/i386-sysv/code.c
@@ -173,16 +173,31 @@ label(Symbol *sym)
}
void
-defsym(Symbol *sym, int alloc)
+defglobal(Symbol *sym)
{
label(sym);
- if (!alloc || (sym->type.flags & INITF))
+ if (sym->kind == EXTRN || (sym->type.flags & INITF))
return;
size2asm(&sym->type);
puts("0");
}
void
+defpar(Symbol *sym)
+{
+}
+
+void
+defvar(Symbol *sym)
+{
+}
+
+void
+newfun(void)
+{
+}
+
+void
writeout(void)
{
}
diff --git a/cc2/arch/qbe/code.c b/cc2/arch/qbe/code.c
@@ -109,9 +109,9 @@ size2asm(Type *tp)
}
void
-defsym(Symbol *sym, int alloc)
+defglobal(Symbol *sym)
{
- if (!alloc)
+ if (sym->kind == EXTRN)
return;
if (sym->kind == GLOB)
fputs("export ", stdout);
@@ -122,6 +122,16 @@ defsym(Symbol *sym, int alloc)
}
void
+defpar(Symbol *sym)
+{
+}
+
+void
+defvar(Symbol *sym)
+{
+}
+
+void
data(Node *np)
{
putchar('\t');
diff --git a/cc2/arch/z80/cgen.c b/cc2/arch/z80/cgen.c
@@ -7,7 +7,73 @@ generate(void)
{
}
+/*
+ * This is strongly influenced by
+ * http://plan9.bell-labs.com/sys/doc/compiler.ps (/sys/doc/compiler.ps)
+ * calculate addresability as follows
+ * AUTO => 11 value+fp
+ * REG => 13 reg
+ * STATIC => 12 (value)
+ * CONST => 20 $value
+ */
+static Node *
+address(Node *np)
+{
+ Node *lp, *rp;
+
+ if (!np)
+ return np;
+
+ np->complex = 0;
+ np->address = 0;
+ lp = np->left;
+ rp = np->right;
+ switch (np->op) {
+ case AUTO:
+ np->address = 11;
+ break;
+ case REG:
+ np->address = 13;
+ break;
+ case MEM:
+ np->address = 12;
+ break;
+ case CONST:
+ np->address = 20;
+ break;
+ default:
+ if (lp)
+ address(lp);
+ if (rp)
+ address(rp);
+ break;
+ }
+
+ if (np->address > 10)
+ return np;
+ if (lp)
+ np->complex = lp->complex;
+ if (rp) {
+ int d = np->complex - rp->complex;
+
+ if (d == 0)
+ ++np->complex;
+ else if (d < 0)
+ np->complex = rp->complex;
+ }
+ if (np->complex == 0)
+ ++np->complex;
+ return np;
+}
+
void
addressability(void)
{
+ Node *np;
+
+ if (!curfun)
+ return;
+
+ for (np = curfun->u.label; np; np = np->stmt)
+ address(np);
}
diff --git a/cc2/arch/z80/code.c b/cc2/arch/z80/code.c
@@ -14,6 +14,7 @@ enum segment {
};
static int curseg = NOSEG;
+static TSIZE offpar, offvar;
static void
segment(int seg)
@@ -162,10 +163,48 @@ size2asm(Type *tp)
}
void
-defsym(Symbol *sym, int alloc)
+newfun()
+{
+ offpar = offvar = 0;
+}
+
+void
+defpar(Symbol *sym)
+{
+ TSIZE align, size;
+
+ if (sym->kind != REG && sym->kind != AUTO)
+ return;
+ align = sym->type.align;
+ size = sym->type.size;
+
+ offpar -= align-1 & ~align;
+ sym->u.off = offpar;
+ offpar -= size;
+ sym->kind = AUTO;
+}
+
+void
+defvar(Symbol *sym)
+{
+ TSIZE align, size;
+
+ if (sym->kind != REG && sym->kind != AUTO)
+ return;
+ align = sym->type.align;
+ size = sym->type.size;
+
+ offvar += align-1 & ~align;
+ sym->u.off = offvar;
+ offvar += size;
+ sym->kind = AUTO;
+}
+
+void
+defglobal(Symbol *sym)
{
label(sym);
- if (!alloc || (sym->type.flags & INITF))
+ if (sym->kind == EXTRN || (sym->type.flags & INITF))
return;
size2asm(&sym->type);
puts("0");
diff --git a/cc2/cc2.h b/cc2/cc2.h
@@ -35,14 +35,22 @@ enum op {
MEM = 'M',
AUTO = 'A',
REG = 'R',
+ CONST = '#',
+ STRING = '"',
+ LABEL = 'L',
/* storage class */
GLOB = 'G',
EXTRN = 'X',
PRIVAT = 'Y',
LOCAL = 'T',
MEMBER = 'M',
- LABEL = 'L',
/* operands */
+ OMEM = 'M',
+ OAUTO = 'A',
+ OREG = 'R',
+ OCONST = '#',
+ OSTRING = '"',
+ OLABEL = 'L',
OADD = '+',
OSUB = '-',
OMUL = '*',
@@ -74,8 +82,6 @@ enum op {
OPTR = '@',
OSYM = 'i',
OCAST = 'g',
- OCONST = '#',
- OSTRING = '"',
OINC = 'i',
ODEC = 'd',
/*statements */
@@ -134,6 +140,8 @@ struct symbol {
struct node {
char op;
Type type;
+ char complex;
+ char address;
union {
TUINT i;
char *s;
@@ -163,14 +171,15 @@ extern void peephole(void);
/* code.c */
extern void data(Node *np);
-extern void defsym(Symbol *sym, int alloc);
-extern void writeout(void), endinit(void);
+extern void writeout(void), endinit(void), newfun(void);
+extern void defvar(Symbol *), defpar(Symbol *), defglobal(Symbol *);
/* node.c */
extern void cleannodes(void);
extern void delnode(Node *np);
extern void deltree(Node *np);
extern Node *newnode(void);
+extern Symbol *curfun;
/* symbol.c */
extern Symbol *getsym(int id);
diff --git a/cc2/node.c b/cc2/node.c
@@ -8,14 +8,16 @@
#define NSYMBOLS 32
-int inhome;
+Symbol *curfun;
struct arena {
Node *mem;
struct arena *next;
};
+
static struct arena *arena;
static Node *freep;
+static int inhome;
Node *
newnode(void)
diff --git a/cc2/parser.c b/cc2/parser.c
@@ -44,14 +44,14 @@ static struct decoc {
void (*parse)(char *token, union tokenop);
union tokenop u;
} optbl[] = { /* eval parse args */
- [AUTO] = { vardecl, symbol, .u.op = AUTO},
- [REG] = { vardecl, symbol, .u.op = REG},
- [GLOB] = { vardecl, symbol, .u.op = MEM},
- [EXTRN] = { vardecl, symbol, .u.op = MEM},
- [PRIVAT] = { vardecl, symbol, .u.op = MEM},
- [LOCAL] = { vardecl, symbol, .u.op = MEM},
- [MEMBER] = { flddecl, symbol, 0},
- [LABEL] = { labeldcl, symbol, 0},
+ [AUTO] = { vardecl, symbol, .u.op = OAUTO},
+ [REG] = { vardecl, symbol, .u.op = OREG},
+ [GLOB] = { vardecl, symbol, .u.op = OMEM},
+ [EXTRN] = { vardecl, symbol, .u.op = OMEM},
+ [PRIVAT] = { vardecl, symbol, .u.op = OMEM},
+ [LOCAL] = { vardecl, symbol, .u.op = OMEM},
+ [MEMBER] = { flddecl, symbol, .u.op = OMEM},
+ [LABEL] = { labeldcl, symbol, .u.op = OLABEL},
[INT8] = { NULL, type, .u.arg = &int8type},
[INT16] = { NULL, type, .u.arg = &int16type},
@@ -130,11 +130,9 @@ static struct decoc {
[OTABLE] = { NULL, casetbl, 0}
};
-static Symbol *curfun;
-static int funpars = -1, sclass, ininit, endf, lineno;
+static int sclass, inpars, ininit, endf, lineno;
static Node *stmtp;
static void *stack[STACKSIZ], **sp = stack;
-static Symbol *params[NR_FUNPARAM];
static void
push(void *elem)
@@ -447,9 +445,9 @@ einit(char *token, union tokenop u)
static void
endpars(void)
{
- if (!curfun || funpars == -1)
+ if (!curfun || !inpars)
error(ESYNTAX);
- funpars = -1;
+ inpars = 0;
}
static void
@@ -499,35 +497,28 @@ array(void)
static void
decl(Symbol *sym)
{
- int alloc;
Type *tp = &sym->type;
if (tp->flags & FUNF) {
curfun = sym;
- return;
} else {
switch (sym->kind) {
case EXTRN:
- alloc = 0;
- break;
case GLOB:
case PRIVAT:
case LOCAL:
- alloc = 1;
+ defglobal(sym);
break;
case AUTO:
case REG:
- if (funpars >= 0) {
- if (funpars == NR_FUNPARAM)
- error(EOUTPAR);
- params[funpars++] = sym;
- }
- return;
+ if (!curfun)
+ error(ESYNTAX);
+ ((inpars) ? defpar : defvar)(sym);
+ break;
default:
abort();
}
}
- defsym(sym, alloc);
}
static void
@@ -622,8 +613,7 @@ stmt(void)
static void
beginfun(void)
{
- memset(params, 0, sizeof(params));
- funpars = 0;
+ inpars = 0;
pushctx();
}
@@ -633,19 +623,19 @@ endfun(void)
Node *np;
np = newnode();
- np->op = ONOP;
- addstmt(np);
- /* TODO: process the function */
curfun = NULL;
- funpars = -1;
+ inpars = 0; /* I know, it is a bit redundant */
endf = 1;
- popctx();
}
void
parse(void)
{
+ cleannodes(); /* remove code of previous function */
+ popctx(); /* remove context of previous function */
+ curfun = NULL;
endf = 0;
+
while (!endf && nextline())
/* nothing */;
if (ferror(stdin))