[hackers] [scc] [cc2] Addapt cc2 to new switch IR || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Thu, 26 May 2016 10:02:54 +0200 (CEST)

commit c3ac196c2df6f14678f295beba7031d2e17eacdd
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Thu May 26 09:38:47 2016 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Thu May 26 10:02:45 2016 +0200

    [cc2] Addapt cc2 to new switch IR
    
    In the new switch IR all the jump table is written interlaced
    with the body statements, and this code moves all the switch
    related statements in order to get them at the beginning and
    in consecutive positions.

diff --git a/cc2/arch/qbe/cgen.c b/cc2/arch/qbe/cgen.c
index b63036a..3827e7d 100644
--- a/cc2/arch/qbe/cgen.c
+++ b/cc2/arch/qbe/cgen.c
_AT_@ -387,8 +387,8 @@ cgen(Node *np)
                 return NULL;
         case OCASE:
         case ODEFAULT:
- case OTABLE:
- case OSWITCH:
+ case OESWITCH:
+ case OBSWITCH:
         default:
                 abort();
         }
diff --git a/cc2/cc2.h b/cc2/cc2.h
index 931586f..98ad094 100644
--- a/cc2/cc2.h
+++ b/cc2/cc2.h
_AT_@ -99,8 +99,8 @@ enum op {
         OELOOP = 'e',
         OCASE = 'v',
         ODEFAULT = 'f',
- OTABLE = 't',
- OSWITCH = 's',
+ OBSWITCH = 's',
+ OESWITCH = 't',
 };
 
 enum nerrors {
_AT_@ -116,6 +116,9 @@ enum nerrors {
         ELNBLNE, /* line without new line */
         EFERROR, /* error reading from file:%s*/
         EBADID, /* incorrect symbol id */
+ EWTACKO, /* switch stack overflow */
+ EWTACKU, /* switch stack underflow */
+ ENOSWTC, /* Out of switch statement */
         ENUMERR
 };
 
diff --git a/cc2/parser.c b/cc2/parser.c
index 6969d59..1709ce1 100644
--- a/cc2/parser.c
+++ b/cc2/parser.c
_AT_@ -30,10 +30,18 @@ union tokenop {
         unsigned op;
 };
 
+struct swtch {
+ int nr;
+ Node *last;
+};
+
+static struct swtch swtbl[NR_BLOCK], *swp = swtbl;
+
 typedef void parsefun(char *, union tokenop);
 static parsefun type, symbol, getname, unary, binary, ternary, call,
                 constant, composed, binit, einit,
- jump, oreturn, loop, assign, casetbl;
+ jump, oreturn, loop, assign,
+ ocase, bswitch, eswitch;
 
 typedef void evalfun(void);
 static evalfun vardecl, beginfun, endfun, endpars, stmt,
_AT_@ -123,22 +131,21 @@ static struct decoc {
         ['b'] = { NULL, loop, .u.op = OBLOOP},
         ['e'] = { NULL, loop, .u.op = OELOOP},
 
- ['v'] = { NULL, jump, .u.op = OCASE},
- ['s'] = { NULL, jump, .u.op = OSWITCH},
-
- ['f'] = { NULL, casetbl, .u.op = ODEFAULT},
- ['t'] = { NULL, casetbl, .u.op = OTABLE}
+ ['v'] = { NULL, ocase, .u.op = OCASE},
+ ['f'] = { NULL, ocase, .u.op = ODEFAULT},
+ ['t'] = { NULL, eswitch, .u.op = OESWITCH},
+ ['s'] = { NULL, bswitch, .u.op = OBSWITCH},
 };
 
 static int sclass, inpars, ininit, endf, lineno;
 static void *stack[STACKSIZ], **sp = stack;
 
-static void
+static Node *
 push(void *elem)
 {
         if (sp == stack[STACKSIZ])
                 error(ESTACKO);
- *sp++ = elem;
+ return *sp++ = elem;
 }
 
 static void *
_AT_@ -327,13 +334,55 @@ oreturn(char *token, union tokenop u)
 }
 
 static void
+waft(Node *np)
+{
+ Node *p;
+
+ if (swp == swtbl)
+ error(EWTACKU);
+ p = swp[-1].last;
+
+ np->next = p->next;
+ np->prev = p;
+ p->next = np;
+ swp->last = np;
+}
+
+static void
+bswitch(char *token, union tokenop u)
+{
+ if (swp++ == &swtbl[NR_BLOCK+1])
+ error(EWTACKO);
+ jump(token, u);
+ swp->nr = 0;
+ swp->last = push(pop());
+}
+
+static void
+eswitch(char *token, union tokenop u)
+{
+ if (swp == swtbl)
+ error(EWTACKU);
+ jump(token, u);
+ waft(pop());
+ --swp;
+}
+
+static void
+ocase(char *token, union tokenop u)
+{
+ jump(token, u);
+ waft(pop());
+}
+
+static void
 jump(char *token, union tokenop u)
 {
         Node *aux, *np = newnode(u.op);
 
         eval(strtok(NULL, "\t\n"));
 
- if (u.op != OJMP)
+ if (u.op == OBRANCH || u.op == OCASE)
                 np->left = pop();
         aux = pop();
         np->u.sym = aux->u.sym;
_AT_@ -342,16 +391,6 @@ jump(char *token, union tokenop u)
 }
 
 static void
-casetbl(char *token, union tokenop u)
-{
- Node *np = newnode(u.op);
-
- eval(strtok(NULL, "\t\n"));
- np->left = pop();
- push(np);
-}
-
-static void
 loop(char *token, union tokenop u)
 {
         push(newnode(u.op));
_AT_@ -564,6 +603,8 @@ stmt(void)
 {
         Node *np;
 
+ if (empty())
+ return;
         np = pop();
         if (ininit) {
                 data(np);
Received on Thu May 26 2016 - 10:02:54 CEST

This archive was generated by hypermail 2.3.0 : Thu May 26 2016 - 10:12:13 CEST