shithub: scc

Download patch

ref: 3921cb9b1dcf2f448c59c391ad182c6eb474b303
parent: b02c8d26d90e1db6ac3115adb35f7b0c01b15acc
author: Roberto E. Vargas Caballero <[email protected]>
date: Wed May 4 16:25:50 EDT 2016

[cc2-qbe] Add return statements to qbe

We need return statements because qne doesn't support orphan labels
at the end of functions, so we have to add return statements in these
cases.

--- a/cc2/arch/qbe/arch.h
+++ b/cc2/arch/qbe/arch.h
@@ -130,5 +130,6 @@
 	ASEXTS,
 	ASTRUNCD,
 
-	ASJMP
+	ASJMP,
+	ASRET,
 };
--- a/cc2/arch/qbe/cgen.c
+++ b/cc2/arch/qbe/cgen.c
@@ -225,7 +225,15 @@
 	if (!np)
 		return NULL;
 
-	setlabel(np->label);
+	if (np->label) {
+		setlabel(np->label);
+		if (np->next == NULL) {
+			Node *tmp = newnode();
+			tmp->op = ORET;
+			addstmt(tmp);
+			prevstmt();
+		}
+	}
 	l = cgen(np->left);
 	r = cgen(np->right);
 	tp = &np->type;
@@ -333,6 +341,10 @@
 		code(ASJMP, np, NULL, NULL);
 		return NULL;
 	case ORET:
+		if (l && (l->flags & (ISTMP|ISCONS)) == 0)
+			l = np->left = load(l);
+		code(ASRET, l, NULL, NULL);
+		return NULL;
 	case OCASE:
 	case ODEFAULT:
 	case OTABLE:
--- a/cc2/arch/qbe/code.c
+++ b/cc2/arch/qbe/code.c
@@ -9,7 +9,7 @@
 
 #define ADDR_LEN (IDENTSIZ+64)
 
-static void binary(void), unary(void), store(void), jmp(void);
+static void binary(void), unary(void), store(void), jmp(void), ret(void);
 
 static struct opdata {
 	void (*fun)(void);
@@ -123,6 +123,7 @@
 	[ASSLTOS]= {.fun = unary, .txt = "truncd", .letter = 's'},
 
 	[ASJMP]  = {.fun = jmp},
+	[ASRET]  = {.fun = ret},
 };
 
 static char buff[ADDR_LEN];
@@ -388,6 +389,15 @@
 	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
+ret(void)
+{
+	if (pc->from1.kind == SNONE)
+		puts("\t\tret");
+	else
+		printf("\t\tret\t%s\n", addr2txt(&pc->from1));
 }
 
 static void
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
@@ -210,6 +210,8 @@
 extern void deltree(Node *np);
 extern Node *newnode(void);
 extern Node *addstmt(Node *np);
+extern Node *prevstmt(void), *nextstmt(void);
+
 
 /* symbol.c */
 #define TMPSYM  0
--- a/cc2/node.c
+++ b/cc2/node.c
@@ -83,6 +83,12 @@
 	return curstmt = curstmt->next;
 }
 
+Node *
+prevstmt(void)
+{
+	return curstmt = curstmt->prev;
+}
+
 void
 delnode(Node *np)
 {