commit 9d132dc59173787dd773ce0e82b55bc4e1c1dffc
parent 2f6992e581ba599c2bcd14a04013b335269a542a
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Mon, 16 Mar 2015 09:25:04 +0000
Rewrite add code generation
We begin to be near of something functional
Diffstat:
3 files changed, 115 insertions(+), 42 deletions(-)
diff --git a/cc2/cc2.h b/cc2/cc2.h
@@ -11,6 +11,7 @@
#define MEM 'T'
#define PAR 'P'
#define CONST '#'
+#define PUSHED 'S'
#define INDEX 'I'
#define LABEL 'L'
#define OADD '+'
@@ -58,6 +59,7 @@ struct symbol {
bool extrn : 1;
char type;
unsigned short id;
+ uint8_t reg;
union {
struct {
Type type;
diff --git a/cc2/cgen.c b/cc2/cgen.c
@@ -117,15 +117,13 @@ allocreg(Node *np)
}
static void
-move(Node *np)
+moveto(Node *np, uint8_t reg)
{
Symbol *sym;
- char reg;
-
- reg = allocreg(np);
switch (np->op) {
case AUTO:
+ case CONST:
sym = np->u.sym;
switch (np->type.size) {
case 1:
@@ -144,9 +142,50 @@ move(Node *np)
default:
abort();
}
- /* TODO: Update symbol if necessary */
np->op = REG;
- np->u.reg = reg;
+ sym->reg = np->u.reg = reg;
+}
+
+static void
+move(Node *np)
+{
+ moveto(np, allocreg(np));
+}
+
+static void
+push(Node *np)
+{
+ code(PUSH, NULL, np);
+ np->op = PUSHED;
+}
+
+static void
+accum(Node *np)
+{
+ switch (np->type.size) {
+ case 1:
+ if (reguse[A])
+ push(reguse[A]);
+ moveto(np, A);
+ break;
+ case 2:
+ if (reguse[H] || reguse[L])
+ push(®_HL);
+ moveto(np, HL);
+ break;
+ case 4:
+ case 8:
+ abort();
+ }
+}
+
+static void
+index(Node *np)
+{
+ if (reguse[H] || reguse[L])
+ push(®_HL);
+ code(MOV, ®_HL, np);
+ np->op = INDEX;
}
static void
@@ -161,38 +200,71 @@ conmute(Node *np)
}
static void
-add(Node *np, Node *lp, Node *rp)
+add(Node *np)
{
+ Node *lp = np->left, *rp = np->right;
+
+ if (rp->op == REG || lp->op == CONST) {
+ conmute(np);
+ lp = np->left;
+ rp = np->right;
+ }
switch (np->type.size) {
case 1:
- if (rp->u.reg == A) {
- conmute(np);
- lp = np->left;
- rp = np->right;
- } else if (lp->u.reg != A) {
- /* TODO: Move A to variable */
- code(PUSH, NULL, lp);
- code(LDL, regs[A], lp);
+ switch (lp->op) {
+ case PAR:
+ case AUTO:
+ switch (rp->op) {
+ case MEM:
+ index(rp);
+ case PAR:
+ case AUTO:
+ case CONST:
+ accum(lp);
+ break;
+ default:
+ abort();
+ }
+ break;
+ case MEM:
+ if (reguse[A]) {
+ switch (rp->op) {
+ case PAR:
+ case AUTO:
+ case CONST:
+ break;
+ case MEM:
+ index(rp);
+ goto add_A;
+ default:
+ abort();
+ }
+ }
+ accum(lp);
+ break;
+ case REG:
+ if (lp->u.reg != A)
+ moveto(lp, A);
+ switch (rp->op) {
+ case REG:
+ case AUTO:
+ case PAR:
+ case CONST:
+ case MEM:
+ break;
+ default:
+ abort();
+ }
+ break;
+ default:
+ abort();
}
- code(ADD, regs[A], rp);
+ add_A:
+ code(ADD, lp, rp);
np->op = REG;
np->u.reg = A;
break;
case 2:
- if (rp->u.reg == HL || rp->u.reg == IY) {
- conmute(np);
- lp = np->left;
- rp = np->right;
- } else if (lp->u.reg != HL && lp->u.reg != IY) {
- /* TODO: Move HL to variable */
- code(PUSH, NULL, lp);
- code(LDL, regs[L], lp);
- code(LDH, regs[H], lp);
- }
- code(ADD, lp, rp);
- np->op = REG;
- np->u.reg = lp->u.reg;
- break;
case 4:
case 8:
abort();
@@ -200,13 +272,15 @@ add(Node *np, Node *lp, Node *rp)
}
static void
-assign(Node *np, Node *lp, Node *rp)
+assign(Node *np)
{
+ Node *lp = np->left, *rp = np->right;
+
switch (np->type.size) {
case 1:
switch (lp->op) {
case AUTO:
- code(LDL, rp, lp);
+ code(LDL, lp, rp);
break;
case REG:
case MEM:
@@ -220,7 +294,7 @@ assign(Node *np, Node *lp, Node *rp)
}
-static void (*opnodes[])(Node *, Node *, Node *) = {
+static void (*opnodes[])(Node *) = {
[OADD] = add,
[OASSIG] = assign
};
@@ -229,20 +303,15 @@ static void
cgen(Node *np, Node *parent)
{
Node *lp, *rp;
- TINT imm;
if (!np)
return;
- lp = np->left;
- rp = np->right;
- if (np->addable >= ADDABLE) {
- if (parent && parent->op == OASSIG)
- return;
- move(np);
+ if (np->addable >= ADDABLE)
return;
- }
+ lp = np->left;
+ rp = np->right;
if (!lp) {
cgen(rp, np);
} else if (!rp) {
@@ -257,7 +326,7 @@ cgen(Node *np, Node *parent)
cgen(q, np);
}
- (*opnodes[np->op])(np, lp, rp);
+ (*opnodes[np->op])(np);
}
static Node *
diff --git a/cc2/code.c b/cc2/code.c
@@ -100,6 +100,8 @@ addr(char op, Node *np, Addr *addr)
case MEM:
addr->u.sym = np->u.sym;
break;
+ case INDEX:
+ break;
default:
abort();
}