shithub: scc

Download patch

ref: 09fa67e950f46b3c661d5d1e34623b2c7177f6d1
parent: 971c825d05531e609d340225327527040a658f0f
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sat Aug 9 11:35:08 EDT 2014

Second iteration of emit()

This version only emits one instruction by every call. This aproach
is better than the previous because it will allow a good trasaction
when we moved to emit into memory.

--- a/cc2/cgen.c
+++ b/cc2/cgen.c
@@ -1,4 +1,5 @@
 
+#include <stdarg.h>
 #include <stdint.h>
 #include <stdlib.h>
 
@@ -18,37 +19,75 @@
 	fun->u.f.stack = siz;
 }
 
-static void
-emit(char what, void *data)
+enum {
+	PUSH, POP, LD, ADD, RET, ADDI, LDI, ADDR
+};
+
+enum {
+	AF, HL, DE, BC, IX, IY, SP, A, F, B, C, D, E, H, L, IXL, IXH, IYL, IYH
+};
+
+char *opnames[] = {
+	[PUSH] = "PUSH", [POP] = "POP", [LD]  = "LD", [ADD] = "ADD",
+	[RET]  = "RET" , [ADDI]= "ADD", [LDI] = "LD"
+};
+
+char *regnames[] = {
+	[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"
+};
+
+void
+emit(char op, ...)
 {
-	Symbol *sym, *p;
+	va_list va;
+	uint8_t reg1, reg2;
+	short imm;
+	char *label;
 
-	switch (what) {
-	case FUN:
-		sym = data;
-		printf("%s:\n"
-		       "\tPUSH\tIX\n"
-		       "\tLD\tIX,SP\n"
-		       "\tLD\tHL,%d\n"
-		       "\tADD\tHL,SP\n"
-		       "\tLD\tSP,HL\n", sym->u.f.name, -sym->u.f.stack);
-		return;
-	case EFUN:
-		puts("\tLD\tSP,IX\n"
-		     "\tPOP\tIX\n"
-		     "\tRET");
-		return;
-	default:
-		fputs("internal error: incorrect emit\n", stderr);
-		abort();
+	va_start(va, op);
+	switch (op) {
+	case RET:
+		printf("\t%s\n", opnames[op]);
+		break;
+	case PUSH: case POP:
+		reg1 = va_arg(va, int);
+		printf("\t%s\t%s\n", opnames[op], regnames[reg1]);
+		break;
+	case ADD: case LD:
+		reg1 = va_arg(va, int);
+		reg2 = va_arg(va, int);
+		printf("\t%s\t%s,%s\n",
+		       opnames[op], regnames[reg1], regnames[reg2]);
+		break;
+	case ADDI: case LDI:
+		reg1 = va_arg(va, int);
+		imm = va_arg(va, int);
+		printf("\t%s\t%s,%hX\n", opnames[op], regnames[reg1], imm);
+		break;
+	case ADDR:
+		label = va_arg(va, char *);
+		printf("%s:\n", label);
+		break;
 	}
+
+	va_end(va);
 }
 
 void
 cgen(Symbol *sym, Node *list[])
 {
-	emit(FUN, sym);
-	emit(EFUN, NULL);
+	emit(ADDR, sym->u.f.name);
+	emit(PUSH, IX);
+	emit(LD, IX, SP);
+	emit(LDI, HL, -sym->u.f.stack);
+	emit(ADD, HL, SP);
+	emit(LD, SP, HL);
+	emit(LD, SP, IX);
+	emit(POP, IX);
+	emit(RET);
 }
 
 /*
--