shithub: scc

Download patch

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(&reg_HL);
+		moveto(np, HL);
+		break;
+	case 4:
+	case 8:
+		abort();
+	}
+}
+
+static void
+index(Node *np)
+{
+	if (reguse[H] || reguse[L])
+		push(&reg_HL);
+	code(MOV, &reg_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();
 	}