[hackers] [scc] [cc2] Add defpar() and defvar() || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Thu, 7 Apr 2016 16:22:13 +0200 (CEST)

commit 1cc0995ffaabe9f5abc298123ff591df5ca32ce0
Author: Roberto E. Vargas Caballero <roberto.vargas_AT_igrid-td.com>
AuthorDate: Thu Apr 7 08:45:10 2016 +0200
Commit: Roberto E. Vargas Caballero <roberto.vargas_AT_igrid-td.com>
CommitDate: Thu Apr 7 08:45:10 2016 +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.

diff --git a/cc2/arch/amd64-sysv/code.c b/cc2/arch/amd64-sysv/code.c
index e58b937..7076542 100644
--- a/cc2/arch/amd64-sysv/code.c
+++ b/cc2/arch/amd64-sysv/code.c
_AT_@ -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
index fddb672..b012cf4 100644
--- a/cc2/arch/i386-sysv/code.c
+++ b/cc2/arch/i386-sysv/code.c
_AT_@ -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
index 003163b..b55a8bd 100644
--- a/cc2/arch/qbe/code.c
+++ b/cc2/arch/qbe/code.c
_AT_@ -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);
_AT_@ -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
index 1101f84..1a70d6a 100644
--- a/cc2/arch/z80/cgen.c
+++ b/cc2/arch/z80/cgen.c
_AT_@ -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
index 49a4737..2954ecf 100644
--- a/cc2/arch/z80/code.c
+++ b/cc2/arch/z80/code.c
_AT_@ -14,6 +14,7 @@ enum segment {
 };
 
 static int curseg = NOSEG;
+static TSIZE offpar, offvar;
 
 static void
 segment(int seg)
_AT_@ -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
index 4a91575..442d7ce 100644
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
_AT_@ -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 = '*',
_AT_@ -74,8 +82,6 @@ enum op {
         OPTR = '_AT_',
         OSYM = 'i',
         OCAST = 'g',
- OCONST = '#',
- OSTRING = '"',
         OINC = 'i',
         ODEC = 'd',
         /*statements */
_AT_@ -134,6 +140,8 @@ struct symbol {
 struct node {
         char op;
         Type type;
+ char complex;
+ char address;
         union {
                 TUINT i;
                 char *s;
_AT_@ -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
index 7433e1e..4bfc353 100644
--- a/cc2/node.c
+++ b/cc2/node.c
_AT_@ -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
index 0657dc6..a02de01 100644
--- a/cc2/parser.c
+++ b/cc2/parser.c
_AT_@ -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},
_AT_@ -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)
_AT_@ -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
_AT_@ -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
_AT_@ -622,8 +613,7 @@ stmt(void)
 static void
 beginfun(void)
 {
- memset(params, 0, sizeof(params));
- funpars = 0;
+ inpars = 0;
         pushctx();
 }
 
_AT_@ -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))
Received on Thu Apr 07 2016 - 16:22:13 CEST

This archive was generated by hypermail 2.3.0 : Thu Apr 07 2016 - 16:24:18 CEST