ref: 9d132dc59173787dd773ce0e82b55bc4e1c1dffc
parent: 2f6992e581ba599c2bcd14a04013b335269a542a
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Mon Mar 16 05:25:04 EDT 2015
Rewrite add code generation We begin to be near of something functional
--- 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 @@
bool extrn : 1;
char type;
unsigned short id;
+ uint8_t reg;
union {
struct {
Type type;
--- a/cc2/cgen.c
+++ b/cc2/cgen.c
@@ -117,15 +117,13 @@
}
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,12 +142,53 @@
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
conmute(Node *np)
{
Node *p, *q;
@@ -161,38 +200,71 @@
}
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 @@
}
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 @@
}
-static void (*opnodes[])(Node *, Node *, Node *) = {
+static void (*opnodes[])(Node *) = {
[OADD] = add,
[OASSIG] = assign
};
@@ -229,20 +303,15 @@
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(q, np);
}
- (*opnodes[np->op])(np, lp, rp);
+ (*opnodes[np->op])(np);
}
static Node *
--- a/cc2/code.c
+++ b/cc2/code.c
@@ -100,6 +100,8 @@
case MEM:
addr->u.sym = np->u.sym;
break;
+ case INDEX:
+ break;
default:
abort();
}