shithub: scc

Download patch

ref: c8caef1d8146964be3fe2ca62b59306c393fa77e
parent: 408728300a8203681bfe8ee19ef0cf8cba8ee849
parent: a17171c31cbee75461bd04eb7b406a7a73b31e76
author: Roberto E. Vargas Caballero <[email protected]>
date: Thu Apr 21 20:03:16 EDT 2016

Merge remote-tracking branch 'origin/master'

--- a/cc2/arch/qbe/arch.h
+++ b/cc2/arch/qbe/arch.h
@@ -5,8 +5,19 @@
 #define TSIZE   unsigned long
 
 enum asmop {
-	ASLOAD,
-	ASASSIG,
+	ASSTB,
+	ASSTH,
+	ASSTW,
+	ASSTL,
+	ASSTS,
+	ASSTD,
+
+	ASLDB,
+	ASLDH,
+	ASLDW,
+	ASLDL,
+	ASLDS,
+	ASLDD,
 
 	ASADDW,
 	ASSUBW,
--- a/cc2/arch/qbe/cgen.c
+++ b/cc2/arch/qbe/cgen.c
@@ -107,12 +107,31 @@
 load(Node *np)
 {
 	Node *new;
+	int op;
+	Type *tp = &np->type;
 
 	new = tmpnode(newnode());
 	new->left = np;
-	new->type = np->type;
-	code(ASLOAD, new, np, NULL);
+	new->type = *tp;
 
+	switch (tp->size) {
+	case 1:
+		op = ASLDB;
+		break;
+	case 2:
+		op = ASLDH;
+		break;
+	case 4:
+		op = (tp->flags & INTF) ? ASLDW : ASLDS;
+		break;
+	case 8:
+		op = (tp->flags & INTF) ? ASLDL : ASLDD;
+		break;
+	default:
+		abort();
+	}
+	code(op, new, np, NULL);
+
 	return new;
 }
 
@@ -133,7 +152,6 @@
 	tp = &np->type;
 
 	switch (np->op) {
-	case OREG:
 	case OSTRING:
 		abort();
 	case OCONST:
@@ -182,8 +200,7 @@
 			l = np->left = load(l);
 		if ((r->flags & (ISTMP|ISCONS)) == 0)
 			r = np->right = load(r);
-		tmpnode(np);
-		code(op, np, l, r);
+		code(op, tmpnode(np), l, r);
 		return np;
 	case ONOP:
 	case OBLOOP:
@@ -198,7 +215,23 @@
 	case ODEC:
 		abort();
 	case OASSIG:
-		code(ASASSIG, l, r, NULL);
+		switch (tp->size) {
+		case 1:
+			op = ASSTB;
+			break;
+		case 2:
+			op = ASSTH;
+			break;
+		case 4:
+			op = (tp->flags & INTF) ? ASSTW : ASSTS;
+			break;
+		case 8:
+			op = (tp->flags & INTF) ? ASSTL : ASSTD;
+			break;
+		default:
+			abort();
+		}
+		code(op, l, r, NULL);
 		return r;
 	case OCALL:
 	case OFIELD:
--- a/cc2/arch/qbe/code.c
+++ b/cc2/arch/qbe/code.c
@@ -16,9 +16,20 @@
 	char *txt;
 	char letter;
 } optbl [] = {
-	[ASLOAD] =  {.fun = load,   .txt = "load", .letter = 'w'},
-	[ASASSIG] = {.fun = store,  .txt = "store", .letter = 'w'},
+	[ASLDB]   =  {.fun = load,  .txt = "load", .letter = 'b'},
+	[ASLDH]   =  {.fun = load,  .txt = "load", .letter = 'h'},
+	[ASLDW]   =  {.fun = load,  .txt = "load", .letter = 'w'},
+	[ASLDL]   =  {.fun = load,  .txt = "load", .letter = 'l'},
+	[ASLDS]   =  {.fun = load,  .txt = "load", .letter = 's'},
+	[ASLDD]   =  {.fun = load,  .txt = "load", .letter = 'd'},
 
+	[ASSTB]   =  {.fun = store,  .txt = "store", .letter = 'b'},
+	[ASSTH]   =  {.fun = store,  .txt = "store", .letter = 'h'},
+	[ASSTW]   =  {.fun = store,  .txt = "store", .letter = 'w'},
+	[ASSTL]   =  {.fun = store,  .txt = "store", .letter = 'l'},
+	[ASSTS]   =  {.fun = store,  .txt = "store", .letter = 's'},
+	[ASSTD]   =  {.fun = store,  .txt = "store", .letter = 'd'},
+
 	[ASADDW]  =  {.fun = binary, .txt = "add", .letter = 'w'},
 	[ASSUBW]  =  {.fun = binary, .txt = "sub", .letter = 'w'},
 	[ASMULW]  =  {.fun = binary, .txt = "mul", .letter = 'w'},
@@ -250,31 +261,53 @@
 	putchar('\n');
 }
 
+static void
+alloc(Symbol *sym)
+{
+	Type *tp = &sym->type;
+
+	printf("\t%s %s=\talloc%lld\t%lld\n",
+	       symname(sym), size2asm(tp),
+	       (long long) tp->size, (long long) tp->align);
+}
+
 void
 writeout(void)
 {
 	Symbol *p;
 	Type *tp;
-	char *sep;
+	char *sep, *name;
 
 	if (curfun->kind == SGLOB)
 		fputs("export ", stdout);
-	printf("function %s %s(", size2asm(&curfun->rtype), symname(curfun));
+	printf("function %s %s(", size2asm(&rtype), symname(curfun));
 
+	/* declare formal parameters */
 	for (sep = "", p = locals; p; p = p->next, sep = ",") {
 		if ((p->type.flags & PARF) == 0)
 			break;
-		printf("%s%s %s", sep, size2asm(&p->type), symname(p));
+		printf("%s%s %s.val", sep, size2asm(&p->type), symname(p));
 	}
-	puts(")");
+	puts(")\n{");
 
-	for ( ; p && p->id != TMPSYM; p = p->next) {
+	/* allocate stack space for parameters */
+	for (p = locals; p && (p->type.flags & PARF) == 0; p = p->next)
+		alloc(p);
+
+	/* allocate stack space for local variables) */
+	for ( ; p && p->id != TMPSYM; p = p->next)
+		alloc(p);
+
+	/* store formal parameters in parameters */
+	for (p = locals; p; p = p->next) {
 		tp = &p->type;
-		printf("\t%s %s=\talloc%lld\t%lld\n",
-		       symname(p), size2asm(tp),
-		       (long long) tp->size, (long long) tp->align);
+		if ((tp->flags & PARF) == 0)
+			break;
+		name = symname(p);
+		printf("\t\tstore%s\t%s.val,%s\n", size2asm(tp), name, name);
 	}
 
+	/* emit assembler instructions */
 	for (pc = prog; pc; pc = pc->next) {
 		if (pc->label)
 			printf("%s:\n", symname(pc->label));
@@ -312,18 +345,23 @@
 static void
 store(void)
 {
-	printf("\t\t%s%c\t", optbl[pc->op].txt, 'w'),
-	fputs(addr2txt(&pc->from1), stdout);
-	putchar(',');
-	fputs(addr2txt(&pc->to), stdout);
-	putchar('\n');
+	struct opdata *p = &optbl[pc->op];
+	char to[ADDR_LEN], from[ADDR_LEN];
+
+	strcpy(to, addr2txt(&pc->to));
+	strcpy(from, addr2txt(&pc->from1));
+	printf("\t\t%s%c\t%s,%s\n", p->txt, p->letter, from, to);
 }
 
 static void
 load(void)
 {
-	printf("\t%s %c=\t", addr2txt(&pc->to), 'w');
-	printf("%s\t%s\n", optbl[pc->op].txt, addr2txt(&pc->from1));
+	struct opdata *p = &optbl[pc->op];
+	char to[ADDR_LEN], from[ADDR_LEN];
+
+	strcpy(to, addr2txt(&pc->to));
+	strcpy(from, addr2txt(&pc->from1));
+	printf("\t%s %c=\t%s\t%s\n", to, p->letter, p->txt, from);
 }
 
 void
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
@@ -132,7 +132,6 @@
 
 struct symbol {
 	Type type;
-	Type rtype;
 	unsigned short id;
 	unsigned short numid;
 	char *name;
@@ -208,7 +207,6 @@
 extern void delnode(Node *np);
 extern void deltree(Node *np);
 extern Node *newnode(void);
-extern Symbol *curfun;
 
 /* symbol.c */
 #define TMPSYM  0
@@ -218,5 +216,7 @@
 extern void freesym(Symbol *sym);
 
 /* globals */
+extern Type rtype;
+extern Symbol *curfun;
 extern Symbol *locals;
 extern Inst *pc, *prog;
--- a/cc2/node.c
+++ b/cc2/node.c
@@ -10,6 +10,7 @@
 #define NNODES   32
 
 Symbol *curfun;
+Type rtype;
 
 struct arena {
 	Node *mem;
--- a/cc2/parser.c
+++ b/cc2/parser.c
@@ -181,10 +181,13 @@
 symbol(char *token, union tokenop u)
 {
 	Node *np;
+	Symbol *sym;
 
 	sclass = u.op >> 8;
 	np = newnode();
-	np->u.sym = getsym(atoi(token+1));
+	sym = getsym(atoi(token+1));
+	np->u.sym = sym;
+	np->type = sym->type;
 	np->op = u.op & 0xFF;
 	push(np);
 }
@@ -534,7 +537,7 @@
 	sym->name = name;
 	sym->type = *tp;
 	if (tp->flags & FUNF)
-		sym->rtype = *rp;
+		rtype = *rp;
 	sym->kind = sclass;
 
 	if (ininit)