[hackers] [scc] [cc2-qbe] Add OBRANCH generation || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Mon, 9 May 2016 17:00:22 +0200 (CEST)

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