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)
{