commit aeb22ab4157f5e6f61991b8c1205e65960f52ba8
parent 16e75931200e52fb455e4293e812bc73602c2d34
Author: Roberto E. Vargas Caballero <Roberto E. Vargas Caballero>
Date: Wed, 4 May 2016 20:25:50 +0200
[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.
Diffstat:
5 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/cc2/arch/qbe/arch.h b/cc2/arch/qbe/arch.h
@@ -130,5 +130,6 @@ enum asmop {
ASEXTS,
ASTRUNCD,
- ASJMP
+ ASJMP,
+ ASRET,
};
diff --git a/cc2/arch/qbe/cgen.c b/cc2/arch/qbe/cgen.c
@@ -225,7 +225,15 @@ cgen(Node *np)
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 @@ cgen(Node *np)
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:
diff --git 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 @@ static struct opdata {
[ASSLTOS]= {.fun = unary, .txt = "truncd", .letter = 's'},
[ASJMP] = {.fun = jmp},
+ [ASRET] = {.fun = ret},
};
static char buff[ADDR_LEN];
@@ -391,6 +392,15 @@ unary(void)
}
static void
+ret(void)
+{
+ if (pc->from1.kind == SNONE)
+ puts("\t\tret");
+ else
+ printf("\t\tret\t%s\n", addr2txt(&pc->from1));
+}
+
+static void
jmp(void)
{
printf("\t\tjmp\t%s\n", addr2txt(&pc->to));
diff --git a/cc2/cc2.h b/cc2/cc2.h
@@ -210,6 +210,8 @@ extern void delnode(Node *np);
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
diff --git a/cc2/node.c b/cc2/node.c
@@ -83,6 +83,12 @@ nextstmt(void)
return curstmt = curstmt->next;
}
+Node *
+prevstmt(void)
+{
+ return curstmt = curstmt->prev;
+}
+
void
delnode(Node *np)
{