[hackers] [scc] [cc2-qbe] Add OBRANCH generation || Roberto E. Vargas Caballero
commit 217331e8371160ff041a36e348b9a50ce3b81043
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Mon May 9 14:20:21 2016 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Mon May 9 14:20:21 2016 +0200
[cc2-qbe] Add OBRANCH generation
OBRANCH is similar to OJMP, but it has a condition expression
and two labels instead of only one. A new function label()
is created to convert labels into nodes, which are needed
for jumps. Before this commit the code was making tricks
to link labels and nodes. This is not the best solution,
but it is the simpler.
diff --git a/cc2/arch/qbe/arch.h b/cc2/arch/qbe/arch.h
index 9a1bbdb..e046597 100644
--- a/cc2/arch/qbe/arch.h
+++ b/cc2/arch/qbe/arch.h
_AT_@ -131,5 +131,6 @@ enum asmop {
ASTRUNCD,
ASJMP,
+ ASBRANCH,
ASRET,
};
diff --git a/cc2/arch/qbe/cgen.c b/cc2/arch/qbe/cgen.c
index 43c5f85..15a703c 100644
--- a/cc2/arch/qbe/cgen.c
+++ b/cc2/arch/qbe/cgen.c
_AT_@ -216,7 +216,7 @@ cast(Node *nd, Node *ns)
Node *
cgen(Node *np)
{
- Node *l, *r;
+ Node *l, *r, *ifyes, *ifno, *next;
Symbol *sym;
Type *tp;
int op, off;
_AT_@ -335,9 +335,27 @@ cgen(Node *np)
case OOR:
abort();
case OBRANCH:
- abort();
+ if (l && (l->flags & (ISTMP|ISCONS)) == 0)
+ l = np->left = load(l);
+ next = np->next;
+ if (next->label) {
+ sym = getsym(TMPSYM);
+ sym->kind = SLABEL;
+ next->label = sym;
+ }
+ ifyes = label(np->u.sym);
+ ifno = label(next->label);
+ op = ASBRANCH;
+ np = np->left;
+ goto emit_jump;
case OJMP:
- code(ASJMP, np, NULL, NULL);
+ ifyes = label(np->u.sym);
+ op = ASJMP;
+ np = ifno = NULL;
+ emit_jump:
+ code(op, np, ifyes, ifno);
+ deltree(ifyes);
+ deltree(ifno);
return NULL;
case ORET:
if (l && (l->flags & (ISTMP|ISCONS)) == 0)
diff --git a/cc2/arch/qbe/code.c b/cc2/arch/qbe/code.c
index 92828b3..7cdf575 100644
--- a/cc2/arch/qbe/code.c
+++ b/cc2/arch/qbe/code.c
_AT_@ -9,7 +9,8 @@
#define ADDR_LEN (IDENTSIZ+64)
-static void binary(void), unary(void), store(void), jmp(void), ret(void);
+static void binary(void), unary(void), store(void), jmp(void), ret(void),
+ branch(void);
static struct opdata {
void (*fun)(void);
_AT_@ -122,6 +123,7 @@ static struct opdata {
[ASEXTS] = {.fun = unary, .txt = "exts", .letter = 'd'},
[ASSLTOS]= {.fun = unary, .txt = "truncd", .letter = 's'},
+ [ASBRANCH] = {.fun = branch},
[ASJMP] = {.fun = jmp},
[ASRET] = {.fun = ret},
};
_AT_@ -403,7 +405,18 @@ ret(void)
static void
jmp(void)
{
- printf("\t\tjmp\t%s\n", addr2txt(&pc->to));
+ printf("\t\tjmp\t%s\n", addr2txt(&pc->from1));
+}
+
+static void
+branch(void)
+{
+ char to[ADDR_LEN], from1[ADDR_LEN], from2[ADDR_LEN];
+
+ strcpy(to, addr2txt(&pc->to));
+ strcpy(from1, addr2txt(&pc->from1));
+ strcpy(from2, addr2txt(&pc->from2));
+ printf("\t\tjnz\t%s,%s,%s\n", to, from1, from2);
}
void
diff --git a/cc2/cc2.h b/cc2/cc2.h
index 5e7cdc1..c9933e3 100644
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
_AT_@ -202,6 +202,7 @@ extern void writeout(void), endinit(void), newfun(void);
extern void code(int op, Node *to, Node *from1, Node *from2);
extern void defvar(Symbol *), defpar(Symbol *), defglobal(Symbol *);
extern void setlabel(Symbol *sym);
+extern Node *label(Symbol *sym);
/* node.c */
#define SETCUR 1
diff --git a/cc2/code.c b/cc2/code.c
index a2b5b34..71abc49 100644
--- a/cc2/code.c
+++ b/cc2/code.c
_AT_@ -38,7 +38,6 @@ addr(Node *np, Addr *addr)
addr->kind = OCONST;
addr->u.i = np->u.i;
break;
- case OJMP:
case OLABEL:
addr->kind = SLABEL;
goto symbol;
_AT_@ -50,11 +49,21 @@ addr(Node *np, Addr *addr)
symbol:
addr->u.sym = np->u.sym;
break;
- default:
- abort();
}
}
+Node *
+label(Symbol *sym)
+{
+ Node *np;
+
+ np = newnode();
+ np->op = OLABEL;
+ np->u.sym = sym;
+
+ return np;
+}
+
void
setlabel(Symbol *sym)
{
Received on Mon May 09 2016 - 17:00:22 CEST
This archive was generated by hypermail 2.3.0
: Mon May 09 2016 - 17:12:23 CEST