commit d7cd0ce876107c05e34c7c00cef311e2023a9352
parent 0771ecab43a53d473d65baf0d08b6177077e11b4
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Sun, 24 Jan 2016 18:45:18 +0100
[cc2] Generate code for initializers
The only architecture that generates actual code is z80,
in the other cases they are only stubs.
Diffstat:
7 files changed, 134 insertions(+), 68 deletions(-)
diff --git a/cc2/arch/amd64-sysv/code.c b/cc2/arch/amd64-sysv/code.c
@@ -3,7 +3,12 @@
#include "../../cc2.h"
void
-emit(Node *np)
+data(Node *np)
+{
+}
+
+void
+label(Symbol *sym)
{
}
diff --git a/cc2/arch/i386-sysv/code.c b/cc2/arch/i386-sysv/code.c
@@ -3,7 +3,12 @@
#include "../../cc2.h"
void
-emit(Node *np)
+data(Node *np)
+{
+}
+
+void
+label(Symbol *sym)
{
}
diff --git a/cc2/arch/z80/code.c b/cc2/arch/z80/code.c
@@ -34,28 +34,46 @@ code(int op, Node *to, Node *from)
{
}
+void
+label(Symbol *sym)
+{
+ int seg, flags = sym->type.flags;
+
+ if (flags & FUNF)
+ seg = CODESEG;
+ else if (flags & INITF)
+ seg = DATASEG;
+ else
+ seg = BSSSEG;
+ segment(seg);
+
+ printf("%s:\n", symname(sym));
+}
+
static void
-emitsym(Symbol *sym)
+emitstring(Node *np)
{
/*In z80 we can ignore the aligment */
- if (sym->type.flags & STRF) {
- fputs(sym->u.s, stdout);
- free(sym->u.s);
- sym->u.s = NULL;
- } else {
- switch (sym->type.size) {
- case 1:
- printf("%02X", (int) (sym->u.i & 0xFF));
- break;
- case 2:
- printf("%04X", (int) (sym->u.i & 0xFFFF));
- break;
- case 4:
- printf("%08X", (long) (sym->u.i & 0xFFFFFFFF));
- break;
- default:
- abort();
- }
+ printf("\"%s\"", np->u.s);
+ free(np->u.s);
+ np->u.s = NULL;
+}
+
+static void
+emitconst(Node *np)
+{
+ switch (np->type.size) {
+ case 1:
+ printf("%02X", (int) np->u.i & 0xFF);
+ break;
+ case 2:
+ printf("%04X", (int) np->u.i & 0xFFFF);
+ break;
+ case 4:
+ printf("%08X", (long) np->u.i & 0xFFFFFFFF);
+ break;
+ default:
+ abort();
}
}
@@ -64,24 +82,36 @@ emittree(Node *np)
{
if (!np)
return;
- if (np->op == OSYM) {
- emitsym(np->sym);
- } else {
- emit(np->left);
+
+ switch (np->op) {
+ case OSTRING:
+ emitstring(np);
+ break;
+ case OCONST:
+ emitconst(np);
+ break;
+ case OADDR:
+ emittree(np->left);
+ break;
+ case MEM:
+ fputs(symname(np->u.sym), stdout);
+ break;
+ default:
+ emittree(np->left);
printf(" %c ", np->op);
- emit(np->right);
+ emittree(np->right);
+ break;
}
}
void
-emit(Node *np)
+data(Node *np)
{
char *s;
/*
* In z80 we can ignore the alignment
*/
- segment(DATASEG);
switch (np->type.size) {
case 1:
s = "\tDB\t";
@@ -98,6 +128,7 @@ emit(Node *np)
}
fputs(s, stdout);
emittree(np);
+ putchar('\n');
}
void
diff --git a/cc2/cc2.h b/cc2/cc2.h
@@ -2,12 +2,11 @@
enum tflags {
SIGNF = 1,
INTF = 2,
- DEFTYP = 4,
- STRUCTF = 8,
+ STRF = 8,
UNIONF = 16,
- FUNCF = 32,
+ FUNF = 32,
ARYF = 64,
- STRF = 128
+ INITF = 128
};
enum op {
@@ -115,13 +114,10 @@ struct type {
struct symbol {
unsigned short id;
+ unsigned short numid;
char *name;
Type type;
char kind;
- union {
- TUINT i;
- char *s;
- } u;
Symbol *next;
Symbol *h_next;
};
@@ -129,7 +125,11 @@ struct symbol {
struct node {
char op;
Type type;
- Symbol *sym;
+ union {
+ TUINT i;
+ char *s;
+ Symbol *sym;
+ } u;
Node *left, *right;
Node *stmt;
};
@@ -151,7 +151,8 @@ extern void generate(void);
extern void peephole(void);
/* code.c */
-extern void emit(Node *np);
+extern void label(Symbol *sym);
+extern void data(Node *np);
extern void writeout(void);
/* node.c */
@@ -165,3 +166,4 @@ extern Symbol *getsym(int id);
extern void popctx(void);
extern void pushctx(void);
extern void freesym(Symbol *sym);
+extern char *symname(Symbol *sym);
diff --git a/cc2/node.c b/cc2/node.c
@@ -39,7 +39,6 @@ newnode(void)
np->right = NULL;
np->left = NULL;
- np->sym = NULL;
np->stmt = NULL;
return np;
}
diff --git a/cc2/parser.c b/cc2/parser.c
@@ -22,19 +22,7 @@ extern Type int8type, int16type, int32type, int64type,
elipsistype;
Type funtype = {
- .flags = DEFTYP | FUNCF
-};
-
-Type arrtype = {
- .flags = DEFTYP | ARYF
-};
-
-Type uniontype = {
- .flags = DEFTYP | UNIONF
-};
-
-Type strtype = {
- .flags = DEFTYP | STRUCTF
+ .flags = FUNF
};
union tokenop {
@@ -44,10 +32,11 @@ union tokenop {
typedef void parsefun(char *, union tokenop);
static parsefun type, symbol, getname, unary, binary, ternary, call,
- parameter, constant;
+ parameter, constant, aggregate;
typedef void evalfun(void);
-static evalfun vardecl, beginfun, endfun, endpars, stmt, begininit, endinit;
+static evalfun vardecl, beginfun, endfun, endpars, stmt, begininit,
+ endinit, array;
static struct decoc {
void (*eval)(void);
@@ -80,9 +69,9 @@ static struct decoc {
[ELLIPSIS] = {NULL, type, .u.arg = &elipsistype},
[FUNCTION] = {NULL, type, .u.arg = &funtype},
- [VECTOR] = {NULL, NULL, .u.arg = &arrtype},
- [UNION] = {NULL, NULL, .u.arg = &uniontype},
- [STRUCT] = {NULL, NULL, .u.arg = &strtype},
+ [VECTOR] = {array, aggregate},
+ [UNION] = {NULL, NULL},
+ [STRUCT] = {NULL, NULL},
[ONAME] = {NULL, getname},
['{'] = {beginfun},
@@ -161,6 +150,7 @@ newid(void)
if (++id == 0)
error(EIDOVER);
+ return id;
}
static void
@@ -170,6 +160,15 @@ type(char *token, union tokenop u)
}
static void
+aggregate(char *token, union tokenop u)
+{
+ Symbol *sym;
+
+ sym = getsym(atoi(token+1));
+ push(&sym->type);
+}
+
+static void
getname(char *t, union tokenop u)
{
push((*++t) ? xstrdup(t) : NULL);
@@ -182,7 +181,7 @@ symbol(char *token, union tokenop u)
sclass = *token++;
np = newnode();
- np->sym = getsym(atoi(token));
+ np->u.sym = getsym(atoi(token));
np->op = u.op;
push(np);
}
@@ -204,17 +203,14 @@ constant(char *token, union tokenop u)
{
static char letters[] = "0123456789ABCDEF";
Node *np = newnode();
- Symbol *sym = getsym(0);
TUINT v;
unsigned c;
- np->sym = sym;
++token;
if (*token == OSTRING) {
- np->op = OSYM;
- sym->id = newid();
- sym->type.flags = STRF;
- sym->u.s = xstrdup(++token);
+ np->op = OSTRING;
+ np->type.flags = STRF;
+ np->u.s = xstrdup(++token);
} else {
np->op = OCONST;
np->type = *gettype(token++);
@@ -222,7 +218,7 @@ constant(char *token, union tokenop u)
v <<= 4;
c = strchr(letters, c) - letters;
}
- sym->u.i = v;
+ np->u.i = v;
}
push(np);
}
@@ -295,6 +291,8 @@ static void
begininit(void)
{
ininit = 1;
+ lastsym->type.flags |= INITF;
+ label(lastsym);
}
static void
@@ -333,6 +331,17 @@ endpars(void)
}
static void
+array(void)
+{
+ Type *tp, *base;
+ Node *np;
+
+ np = pop();
+ base = pop();
+ tp = pop();
+}
+
+static void
vardecl(void)
{
Type *tp;
@@ -344,11 +353,13 @@ vardecl(void)
tp = pop();
np = pop();
- sym = np->sym;
+ sym = np->u.sym;
sym->name = name;
sym->type = *tp;
sym->kind = sclass;
lastsym = sym;
+ if (!name)
+ sym->numid = newid();
if (funpars >= 0) {
if (funpars == NR_FUNPARAM)
@@ -365,7 +376,7 @@ stmt(void)
Node *np = pop();
if (ininit) {
- emit(np);
+ data(np);
deltree(np);
return;
}
diff --git a/cc2/symbol.c b/cc2/symbol.c
@@ -1,4 +1,5 @@
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -47,7 +48,7 @@ getsym(int id)
htab = &symtab[id & NR_SYMHASH-1];
for (sym = *htab; sym; sym = sym->h_next) {
- if (sym->id > 0 && sym->id != id)
+ if (sym->id > 0 && sym->id == id)
break;
}
if (!sym) {
@@ -64,3 +65,15 @@ getsym(int id)
}
return sym;
}
+
+char *
+symname(Symbol *sym)
+{
+ static char name[20];
+
+ if (sym->name)
+ return sym->name;
+ sprintf(name, ".%d", sym->numid);
+
+ return name;
+}