[hackers] [scc] [cc2-qbe] Implement ternary operator || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Tue, 7 Jun 2016 09:34:13 +0200 (CEST)

commit 12586fdbde8bc3b7715a93dadf32a051699c04c8
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Tue Jun 7 09:32:16 2016 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Tue Jun 7 09:32:16 2016 +0200

    [cc2-qbe] Implement ternary operator
    
    The ternary operator is basically an if-else chain, where both
    branches assign to the same variable. This could be done with
    a phi instruction in qbe, but using the same temporary in both
    branches was more similar to the rest of the code.

diff --git a/cc2/arch/qbe/cgen.c b/cc2/arch/qbe/cgen.c
index d8b0821..acca4e8 100644
--- a/cc2/arch/qbe/cgen.c
+++ b/cc2/arch/qbe/cgen.c
_AT_@ -315,6 +315,43 @@ assign(Node *to, Node *from)
         return from;
 }
 
+static Node *
+ternary(Node *np)
+{
+ Symbol *yes, *no, *phi;
+ Node *ifyes, *ifno, *phinode, *yesval, *colon;
+
+ tmpnode(np);
+ phi = newlabel();
+ yes = newlabel();
+ no = newlabel();
+
+ ifyes = label2node(yes);
+ ifno = label2node(no);
+ phinode = label2node(phi);
+
+ colon = np->right;
+ cgen(np->left);
+ load(np, LOADL);
+ code(ASBRANCH, np->left, ifyes, ifno);
+
+ setlabel(yes);
+ cgen(colon->left);
+ assign(np, load(colon, LOADL));
+ code(ASJMP, NULL, phinode, NULL);
+
+ setlabel(no);
+ cgen(colon->right);
+ assign(np, load(colon, LOADR));
+ setlabel(phi);
+
+ deltree(ifyes);
+ deltree(ifno);
+ deltree(phinode);
+
+ return np;
+}
+
 /* TODO: Fix "memory leaks" */
 Node *
 cgen(Node *np)
_AT_@ -329,7 +366,7 @@ cgen(Node *np)
                 return NULL;
 
         setlabel(np->label);
- if (np->op != OCALL) {
+ if (np->op != OCALL && np->op != OASK) {
                 np->left = cgen(np->left);
                 np->right = cgen(np->right);
         }
_AT_@ -411,11 +448,11 @@ cgen(Node *np)
         case OCALL:
                 return call(np);
         case OFIELD:
- case OASK:
- case OCOLON:
         case OAND:
         case OOR:
                 abort();
+ case OASK:
+ return ternary(np);
         case OBRANCH:
                 next = np->next;
                 load(np, LOADL);
Received on Tue Jun 07 2016 - 09:34:13 CEST

This archive was generated by hypermail 2.3.0 : Tue Jun 07 2016 - 09:36:18 CEST