commit b8ea542ae6db4934ceb3d3a69a7884830604df31
parent af5912cb496c86beb67fdd17ef7038ffde27a04e
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Sat, 23 Jan 2016 21:28:09 +0100
[cc2] Emit initializers as soon as posible
Initializers are not important for the code generation,
so we don't waste our time with them and emit them as
soon as possible.
Diffstat:
11 files changed, 162 insertions(+), 31 deletions(-)
diff --git a/cc1/arch/i386/arch.h b/cc1/arch/i386-sysv/arch.h
diff --git a/cc2/Makefile b/cc2/Makefile
@@ -2,8 +2,8 @@
include ../config.mk
-OBJS = main.o parser.o code.o optm.o peep.o cgen.o \
- symbol.o node.o arch/$(ARCH)/types.o
+OBJS = main.o parser.o optm.o peep.o symbol.o node.o \
+ arch/$(ARCH)/code.o arch/$(ARCH)/cgen.o arch/$(ARCH)/types.o
all: cc2
diff --git a/cc2/arch/i386-sysv/code.c b/cc2/arch/i386-sysv/code.c
@@ -0,0 +1,13 @@
+
+#include "arch.h"
+#include "../../cc2.h"
+
+void
+emit(Node *np)
+{
+}
+
+void
+writeout(void)
+{
+}
diff --git a/cc2/arch/z80/cgen.c b/cc2/arch/z80/cgen.c
@@ -0,0 +1,13 @@
+
+#include "arch.h"
+#include "../../cc2.h"
+
+void
+generate(void)
+{
+}
+
+void
+addable(void)
+{
+}
diff --git a/cc2/arch/z80/code.c b/cc2/arch/z80/code.c
@@ -0,0 +1,106 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "arch.h"
+#include "../../cc2.h"
+
+enum segment {
+ CODESEG,
+ DATASEG,
+ BSSSEG,
+ NOSEG
+};
+
+static int curseg = NOSEG;
+
+static void
+segment(int seg)
+{
+ static char *txt[] = {
+ [CODESEG] = "\tCSEG\n",
+ [DATASEG] = "\tDSEG\n",
+ [BSSSEG] = "\tXSEG\n",
+ };
+
+ if (seg == curseg)
+ return;
+ fputs(txt[seg], stdout);
+ curseg = seg;
+}
+
+void
+code(int op, Node *to, Node *from)
+{
+}
+
+static void
+emitsym(Symbol *sym)
+{
+ /*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();
+ }
+ }
+}
+
+static void
+emittree(Node *np)
+{
+ if (!np)
+ return;
+ if (np->op == OSYM) {
+ emitsym(np->sym);
+ } else {
+ emit(np->left);
+ printf(" %c ", np->op);
+ emit(np->right);
+ }
+}
+
+void
+emit(Node *np)
+{
+ char *s;
+
+ /*
+ * In z80 we can ignore the alignment
+ */
+ segment(DATASEG);
+ switch (np->type.size) {
+ case 1:
+ s = "\tDB\t";
+ break;
+ case 2:
+ s = "\tDW\t";
+ break;
+ case 4:
+ s = "\tDD\t";
+ break;
+ default:
+ s = "\tDS\t";
+ break;
+ }
+ fputs(s, stdout);
+ emittree(np);
+}
+
+void
+writeout(void)
+{
+}
diff --git a/cc2/cc2.h b/cc2/cc2.h
@@ -1,12 +1,13 @@
enum tflags {
- SIGNF = 1,
- INTF = 2,
- DEFTYP = 4,
- STRUCTF = 8,
- UNIONF = 16,
- FUNCF = 32,
- ARYF = 64
+ SIGNF = 1,
+ INTF = 2,
+ DEFTYP = 4,
+ STRUCTF = 8,
+ UNIONF = 16,
+ FUNCF = 32,
+ ARYF = 64,
+ STRF = 128
};
enum op {
@@ -150,11 +151,13 @@ extern void generate(void);
extern void peephole(void);
/* code.c */
+extern void emit(Node *np);
extern void writeout(void);
/* node.c */
extern void cleannodes(void);
extern void delnode(Node *np);
+extern void deltree(Node *np);
extern Node *newnode(void);
/* symbol.c */
diff --git a/cc2/cgen.c b/cc2/cgen.c
@@ -1,13 +0,0 @@
-
-#include "arch.h"
-#include "cc2.h"
-
-void
-generate(void)
-{
-}
-
-void
-addable(void)
-{
-}
diff --git a/cc2/code.c b/cc2/code.c
@@ -1,8 +0,0 @@
-
-#include "arch.h"
-#include "cc2.h"
-
-void
-writeout(void)
-{
-}
diff --git a/cc2/main.c b/cc2/main.c
@@ -35,6 +35,7 @@ repeat:
int
main(void)
{
+
while (moreinput()) {
parse();
optimize();
diff --git a/cc2/node.c b/cc2/node.c
@@ -52,6 +52,16 @@ delnode(Node *np)
}
void
+deltree(Node *np)
+{
+ if (!np)
+ return;
+ deltree(np->left);
+ deltree(np->right);
+ delnode(np);
+}
+
+void
cleannodes(void)
{
struct arena *ap, *next;
diff --git a/cc2/parser.c b/cc2/parser.c
@@ -212,8 +212,8 @@ constant(char *token, union tokenop u)
++token;
if (*token == OSTRING) {
np->op = OSYM;
- np->type = ptrtype;
sym->id = newid();
+ sym->type.flags = STRF;
sym->u.s = xstrdup(++token);
} else {
np->op = OCONST;
@@ -224,6 +224,7 @@ constant(char *token, union tokenop u)
}
sym->u.i = v;
}
+ push(np);
}
static void
@@ -363,6 +364,11 @@ stmt(void)
static Node *lastp;
Node *np = pop();
+ if (ininit) {
+ emit(np);
+ deltree(np);
+ return;
+ }
if (!stmtp)
stmtp = np;
else