shithub: scc

Download patch

ref: 6902f4ced599888da040b7abe331a07ddf88c46b
parent: e5e0b99538110a36bdc8f15176cf8849e9764b86
author: Roberto E. Vargas Caballero <[email protected]>
date: Fri Mar 13 21:18:44 EDT 2015

Split cgen()

This function will be too big, so it is better to split it in several
functions and to use a jump table. Yes, yes, I know is more efficient
the big case, but I cannot manage it.

--- a/cc2/cgen.c
+++ b/cc2/cgen.c
@@ -162,6 +162,71 @@
 }
 
 static void
+add(Node *np, Node *lp, Node *rp)
+{
+	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);
+		}
+		code(ADD, regs[A], 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();
+	}
+}
+
+static void
+assign(Node *np, Node *lp, Node *rp)
+{
+	switch (np->type.size) {
+	case 1:
+		switch (lp->op) {
+		case AUTO:
+			code(LDL, rp, lp);
+			break;
+		case REG:
+		case MEM:
+		default:
+			abort();
+		}
+		break;
+	default:
+		abort();
+	}
+}
+
+
+static void (*opnodes[])(Node *, Node *, Node *) = {
+	[OADD] = add,
+	[OASSIG] = assign
+};
+
+static void
 cgen(Node *np, Node *parent)
 {
 	Node *lp, *rp;
@@ -193,63 +258,7 @@
 		cgen(q, np);
 	}
 
-	switch (np->op) {
-	case OADD:
-		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);
-			}
-			code(ADD, regs[A], 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();
-		}
-		break;
-	case OASSIG:
-		switch (np->type.size) {
-		case 1:
-			switch (lp->op) {
-			case AUTO:
-				code(LDL, rp, lp);
-				break;
-			case REG:
-			case MEM:
-			default:
-				abort();
-			}
-			break;
-		default:
-			abort();
-		}
-		break;
-	default:
-		abort();
-	}
+	(*opnodes[np->op])(np, lp, rp);
 }
 
 static Node *