shithub: scc

Download patch

ref: 4f26471416516e201f2d0efdfb87f601a5682134
parent: a0758440d875f800b9cd5e9d726cc568a8633a43
author: Roberto E. Vargas Caballero <[email protected]>
date: Tue Sep 16 14:57:40 EDT 2014

Add generation of additions

This is a first attemp to generate additions, that generate
code only for very simple cases, and even destroy the stack,
but it is usable to can check another parts, as for example
the offset of local variables in the stack.

--- a/cc2/cc2.h
+++ b/cc2/cc2.h
@@ -36,6 +36,7 @@
 	union {
 		Symbol *sym;
 		TINT imm;
+		char reg;
 	} u;
 	struct node *left, *right;
 } Node;
--- a/cc2/cgen.c
+++ b/cc2/cgen.c
@@ -9,7 +9,7 @@
 
 #include <stdio.h>
 
-
+/* TODO: Change emit to code */
 enum {
 	PUSH, POP, LD, ADD, RET, ADDI, LDI, ADDR, ADDX, ADCX, LDX,
 	LDFX
@@ -157,15 +157,16 @@
 	Symbol *sym;
 	char reg;
 
+	reg = allocreg(np);
+
 	switch (np->op) {
 	case AUTO:
 		sym = np->u.sym;
 		switch (tp->size) {
 		case 1:
-			emit(LDFX, allocreg(np), sym->u.v.off);
+			emit(LDFX, reg, sym->u.v.off);
 			break;
 		case 2:
-			reg = allocreg(np);
 			emit(LDFX, lower(reg), IX, sym->u.v.off);
 			emit(LDFX, upper(reg), IX, sym->u.v.off+1);
 			break;
@@ -178,9 +179,23 @@
 	default:
 		abort();
 	}
+	/* TODO: Update symbol  if necessary */
+	np->op = REG;
+	np->u.reg = reg;
 }
 
 static void
+conmute(Node *np)
+{
+	Node *p, *q;
+
+	p = np->left;
+	q = np->right;
+	np->left = q;
+	np->right = p;
+}
+
+static void
 cgen(Node *np)
 {
 	Node *lp, *rp;
@@ -210,7 +225,40 @@
 		cgen(q);
 	}
 
+	assert(lp && lp->op == REG || rp && rp->op == REG);
 	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 */
+				emit(PUSH, AF);
+				emit(LD, A, lp->u.reg);
+			}
+			emit(ADD, A, rp->u.reg);
+			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 */
+				emit(PUSH, HL);
+				emit(LD, H, upper(lp->u.reg));
+				emit(LD, L, lower(lp->u.reg));
+			}
+			emit(ADD, HL, rp->u.reg);
+			break;
+		case 4:
+		case 8:
+			abort();
+		}
+		break;
 	default:
 		abort();
 	}