shithub: scc

Download patch

ref: a0758440d875f800b9cd5e9d726cc568a8633a43
parent: a7dba1661a8d960eac3e8f7f315a50b23673cc39
author: Roberto E. Vargas Caballero <[email protected]>
date: Tue Sep 16 13:56:21 EDT 2014

Move addresable nodes to register

This is a first attemp of generating some code. It only allocate
register for a value, but it doesn't save to stack or anything similar.
This code is only a stub.

--- a/cc2/cc2.h
+++ b/cc2/cc2.h
@@ -90,6 +90,8 @@
 #define OCPL      '~'
 #define OCOMMA    ','
 
+#define ADDABLE 10
+
 extern void error(unsigned nerror, ...);
 extern void genaddable(Node *list[]);
 extern void generate(Symbol *sym, Node *list[]);
--- a/cc2/cgen.c
+++ b/cc2/cgen.c
@@ -11,17 +11,18 @@
 
 
 enum {
-	PUSH, POP, LD, ADD, RET, ADDI, LDI, ADDR, ADDX, ADCX, LDX
+	PUSH, POP, LD, ADD, RET, ADDI, LDI, ADDR, ADDX, ADCX, LDX,
+	LDFX
 };
 
 enum {
-	AF, HL, DE, BC, IX, IY, SP, A, F, B, C, D, E, H, L, IXL, IXH, IYL, IYH
+	A, B, C, D, E, H, L, IYL, IYH, NREGS, IXL, IXH, F, I, SP, AF, HL, DE, BC, IX, IY
 };
 
 char *opnames[] = {
 	[PUSH] = "PUSH", [POP] = "POP", [LD]  = "LD", [ADD] = "ADD",
 	[RET]  = "RET" , [ADDI]= "ADD", [LDI] = "LD", [ADDX] = "ADD",
-	[ADCX] = "ADC" , [LDX] = "LD"
+	[ADCX] = "ADC" , [LDX] = "LD" , [LDFX] = "LD"
 };
 
 char *regnames[] = {
@@ -28,7 +29,7 @@
 	[AF] = "AF", [HL] = "HL", [DE] = "DE", [BC] = "BC", [IX] = "IX",
 	[IY] = "IY", [SP] = "SP", [A]  = "A",  [F]  = "F",  [B]  = "B",
 	[C]  = "C",  [D]  = "D",  [E]  = "E",  [H]  = "H",  [L]  = "L",
-	[IXL]= "IXL",[IXH]= "IXH",[IYL]= "IYL",[IYH]= "IYH"
+	[IXL]= "IXL",[IXH]= "IXH",[IYL]= "IYL",[IYH]= "IYH", [I] = "I"
 };
 
 void
@@ -60,6 +61,13 @@
 		imm = va_arg(va, int);
 		printf("\t%s\t%s,%d\n", opnames[op], regnames[reg1], imm);
 		break;
+	case LDFX:
+		reg1 = va_arg(va, int);
+		reg2 = va_arg(va, int);
+		off = va_arg(va, int);
+		printf("\t%s\t%s,(%s%+d)\n",
+		       opnames[op], regnames[reg1], regnames[reg2], off);
+		break;
 	case LDX:
 		reg1 = va_arg(va, int);
 		off = va_arg(va, int);
@@ -83,16 +91,111 @@
 	va_end(va);
 }
 
-void
+static char
+upper(char pair)
+{
+	switch (pair) {
+	case HL: return H;
+	case BC: return B;
+	case DE: return D;
+	case IY: return IYH;
+	}
+}
+
+static char
+lower(char pair)
+{
+	switch (pair) {
+	case HL: return L;
+	case DE: return E;
+	case BC: return B;
+	case IY: return IYL;
+	}
+}
+
+static char
+allocreg(Node *np)
+{
+	static bool regs[NREGS], *bp;
+
+	switch (np->type->size) {
+	case 1:
+		for (bp = regs; bp < &regs[NREGS]; ++bp) {
+			if (*bp)
+				continue;
+			*bp = 1;
+			return bp - regs;
+		}
+		/* TODO: Move variable to stack using PUSH/POP */
+		break;
+	case 2:
+		if (!regs[H] && !regs[L]) {
+			regs[H] = regs [L] = 1;
+			return HL;
+		}
+		if (!regs[D] && !regs[E]) {
+			regs[D] = regs [E] = 1;
+			return DE;
+		}
+		if (!regs[C] && !regs[B]) {
+			regs[B] = regs [C] = 1;
+			return BC;
+		}
+		if (!regs[IYL] && !regs[IYH]) {
+			regs[IYL] = regs [IYH] = 1;
+			return IY;
+		}
+		/* TODO: Move variable to stack using PUSH/POP */
+	}
+	abort();
+}
+
+static void
+move(Node *np)
+{
+	Type *tp = np->type;
+	Symbol *sym;
+	char reg;
+
+	switch (np->op) {
+	case AUTO:
+		sym = np->u.sym;
+		switch (tp->size) {
+		case 1:
+			emit(LDFX, allocreg(np), 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;
+		case 4:
+		case 8:
+		default:
+			abort();
+		}
+		break;
+	default:
+		abort();
+	}
+}
+
+static void
 cgen(Node *np)
 {
 	Node *lp, *rp;
 	TINT imm;
 
-	if (!np || np->complex == 0)
+	if (!np)
 		return;
+
 	lp = np->left;
 	rp = np->right;
+	if (np->addable >= ADDABLE) {
+		move(np);
+		return;
+	}
+
 	if (!lp) {
 		cgen(rp);
 	} else if (!rp) {