shithub: scc

Download patch

ref: 98aaedf3e0768a8a57374415c43c9d166f03dee0
parent: 5bbaaae3a28915960257ddf5da06b928df377be1
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue May 31 04:39:44 EDT 2016

[cc2-qbe] Add basic support for calls in qbe

This is a preliminar patch which add supports for calls in qbe,
but it does not pass the parameters to the function call, so it
only can be used for functions without parameters. It also
does not support void functions.

--- a/cc2/arch/qbe/arch.h
+++ b/cc2/arch/qbe/arch.h
@@ -132,4 +132,11 @@
 	ASJMP,
 	ASBRANCH,
 	ASRET,
+	ASCALLB,
+	ASCALLH,
+	ASCALLW,
+	ASCALLS,
+	ASCALLL,
+	ASCALLD,
+	ASCALL,
 };
--- a/cc2/arch/qbe/cgen.c
+++ b/cc2/arch/qbe/cgen.c
@@ -4,6 +4,7 @@
 
 #include "arch.h"
 #include "../../cc2.h"
+#include "../../../inc/sizes.h"
 
 enum lflags {
 	FORCE = 1 << 0,
@@ -232,6 +233,38 @@
 }
 
 static Node *
+call(Node *np)
+{
+	int n, op;
+	Type *tp = &np->type;
+	Node *tmp, *p, *pars[NR_FUNPARAM];
+
+	for (n = 0, p = np->right; p; p = p->right)
+		pars[n] = cgen(p->left);
+
+	switch (tp->size) {
+	case 1:
+		op = ASCALLB;
+		break;
+	case 2:
+		op = ASCALLH;
+		break;
+	case 4:
+		op = (tp->flags & INTF) ? ASCALLW : ASCALLS;
+		break;
+	case 8:
+		op = (tp->flags & INTF) ? ASCALLL : ASCALLD;
+		break;
+	default:
+		abort();
+	}
+	code(op, tmpnode(np), np->left, NULL);
+	code(ASCALL, NULL, NULL, NULL);
+
+	return np;
+}
+
+static Node *
 abbrev(Node *np)
 {
 	Node *tmp;
@@ -259,8 +292,10 @@
 		return NULL;
 
 	setlabel(np->label);
-	np->left = cgen(np->left);
-	np->right = cgen(np->right);
+	 if (np->op != OCALL) {
+		np->left = cgen(np->left);
+		np->right = cgen(np->right);
+	}
 	tp = &np->type;
 
 	switch (np->op) {
@@ -354,6 +389,7 @@
 	case OCOMMA:
 		return np->right;
 	case OCALL:
+		return call(np);
 	case OFIELD:
 	case OASK:
 	case OCOLON:
--- a/cc2/arch/qbe/code.c
+++ b/cc2/arch/qbe/code.c
@@ -10,7 +10,7 @@
 #define ADDR_LEN (INTIDENTSIZ+64)
 
 static void binary(void), unary(void), store(void), jmp(void), ret(void),
-            branch(void);
+            branch(void), call(void), ecall(void);
 
 static struct opdata {
 	void (*fun)(void);
@@ -126,6 +126,13 @@
 	[ASBRANCH] = {.fun = branch},
 	[ASJMP]  = {.fun = jmp},
 	[ASRET]  = {.fun = ret},
+	[ASCALLB] = {.fun = call, .letter = 'b'},
+	[ASCALLH] = {.fun = call, .letter = 'h'},
+	[ASCALLW] = {.fun = call, .letter = 'w'},
+	[ASCALLS] = {.fun = call, .letter = 's'},
+	[ASCALLL] = {.fun = call, .letter = 'l'},
+	[ASCALLD] = {.fun = call, .letter = 'd'},
+	[ASCALL] = {.fun = ecall},
 };
 
 static char buff[ADDR_LEN];
@@ -393,6 +400,23 @@
 	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);
+}
+
+static void
+call(void)
+{
+       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\tcall\t%s(", to, p->letter, from);
+}
+
+static void
+ecall(void)
+{
+	puts(")");
 }
 
 static void