ref: b419af2e240fc9da3ea5fa5b4ecad1c9fc71cbb1
parent: 83925bdbebb1658ac7e26c3dc5181b3ae595d864
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Thu Apr 7 04:45:10 EDT 2016
[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.
--- a/cc2/arch/amd64-sysv/code.c
+++ b/cc2/arch/amd64-sysv/code.c
@@ -174,13 +174,28 @@
}
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
--- a/cc2/arch/i386-sysv/code.c
+++ b/cc2/arch/i386-sysv/code.c
@@ -173,13 +173,28 @@
}
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
--- a/cc2/arch/qbe/code.c
+++ b/cc2/arch/qbe/code.c
@@ -109,9 +109,9 @@
}
void
-defsym(Symbol *sym, int alloc)
+defglobal(Symbol *sym)
{
- if (!alloc)
+ if (sym->kind == EXTRN)
return;
if (sym->kind == GLOB)
fputs("export ", stdout);
@@ -119,6 +119,16 @@
if (sym->type.flags & INITF)
return;
printf("\tz\t%llu\n}\n", (unsigned long long) sym->type.size);
+}
+
+void
+defpar(Symbol *sym)
+{
+}
+
+void
+defvar(Symbol *sym)
+{
}
void
--- a/cc2/arch/z80/cgen.c
+++ b/cc2/arch/z80/cgen.c
@@ -7,7 +7,73 @@
{
}
+/*
+ * 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);
}
--- a/cc2/arch/z80/code.c
+++ b/cc2/arch/z80/code.c
@@ -14,6 +14,7 @@
};
static int curseg = NOSEG;
+static TSIZE offpar, offvar;
static void
segment(int seg)
@@ -162,10 +163,48 @@
}
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");
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
@@ -35,6 +35,9 @@
MEM = 'M',
AUTO = 'A',
REG = 'R',
+ CONST = '#',
+ STRING = '"',
+ LABEL = 'L',
/* storage class */
GLOB = 'G',
EXTRN = 'X',
@@ -41,8 +44,13 @@
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 @@
OPTR = '@',
OSYM = 'i',
OCAST = 'g',
- OCONST = '#',
- OSTRING = '"',
OINC = 'i',
ODEC = 'd',
/*statements */
@@ -134,6 +140,8 @@
struct node {
char op;
Type type;
+ char complex;
+ char address;
union {
TUINT i;
char *s;
@@ -163,8 +171,8 @@
/* 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);
@@ -171,6 +179,7 @@
extern void delnode(Node *np);
extern void deltree(Node *np);
extern Node *newnode(void);
+extern Symbol *curfun;
/* symbol.c */
extern Symbol *getsym(int id);
--- 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)
--- a/cc2/parser.c
+++ b/cc2/parser.c
@@ -44,14 +44,14 @@
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 @@
[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 @@
static void
endpars(void)
{
- if (!curfun || funpars == -1)
+ if (!curfun || !inpars)
error(ESYNTAX);
- funpars = -1;
+ inpars = 0;
}
static void
@@ -499,35 +497,28 @@
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 @@
static void
beginfun(void)
{
- memset(params, 0, sizeof(params));
- funpars = 0;
+ inpars = 0;
pushctx();
}
@@ -633,19 +623,19 @@
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))