commit 8773fd15cb4be505d58d95f0839ff7823e1f653f
parent 31072207d906172698d4b214495f71589f4519f9
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Sat, 4 Jan 2025 23:07:50 +0100
cc2: Remove the bool() evaluator from qbe
This code is noved to the generic sethi() function making available
it to any other backend.
Diffstat:
5 files changed, 63 insertions(+), 97 deletions(-)
diff --git a/src/cmd/scc-cc/cc2/cc2.h b/src/cmd/scc-cc/cc2/cc2.h
@@ -295,6 +295,7 @@ extern Node *node(int op);
extern Node *addstmt(Node *);
extern Node *delstmt(Node *);
extern Node *insstmt(Node *, Node *);
+extern Node *prestmt(Node *);
extern void delrange(Node *, Node *);
extern Node *unlinkstmt(Node *);
diff --git a/src/cmd/scc-cc/cc2/node.c b/src/cmd/scc-cc/cc2/node.c
@@ -131,6 +131,12 @@ unlinkstmt(Node *np)
}
Node *
+prestmt(Node *np)
+{
+ return insstmt(np, curstmt->prev);
+}
+
+Node *
addstmt(Node *np)
{
insstmt(np, curstmt);
diff --git a/src/cmd/scc-cc/cc2/qbe/cgen.c b/src/cmd/scc-cc/cc2/qbe/cgen.c
@@ -165,12 +165,9 @@ tsethi(Node *np)
* In QBE we need at the end of a basic block
* a jump, so we have to ensure that the last
* statement of the function is a ret, a jmp
- * or a branch. In the same way, QBE does
- * not accept labels at the end of a function
- * (ONOP is used for labels) so we have to add
- * a ret there, and in the case of branches
- * we need a label for the next statement
+ * or a branch.
*/
+
op = np->prev->op;
if (op == ONOP || op == OBRANCH || (op != ORET && op != OJMP))
addstmt(node(ORET));
@@ -380,37 +377,6 @@ lhs(Node *np)
}
}
-static void
-bool(Node *np, Symbol *true, Symbol *false)
-{
- Node *l = np->left, *r = np->right;
- Node ifyes, ifno;
- Symbol *label;
-
- switch (np->op) {
- case ONEG:
- bool(l, false, true);
- break;
- case OAND:
- label = newlabel();
- bool(l, label, false);
- setlabel(label);
- bool(r, true, false);
- break;
- case OOR:
- label = newlabel();
- bool(l, true, label);
- setlabel(label);
- bool(r, true, false);
- break;
- default:
- label2node(&ifyes, true);
- label2node(&ifno, false);
- code(ASBRANCH, rhs(np), &ifyes, &ifno);
- break;
- }
-}
-
static Node *
ternary(Node *np)
{
@@ -603,25 +569,6 @@ rhs(Node *np)
case OREG:
case OAUTO:
return load(tp, np);
- case ONEG:
- case OAND:
- case OOR:
- true = newlabel();
- false = newlabel();
- phi = label2node(&aux1, NULL);
- tmp = tmpnode(tp, NULL);
-
- bool(np, true, false);
-
- setlabel(true);
- code(ASCOPYW, tmp, constnode(&aux2, 1, tp), NULL);
- code(ASJMP, NULL, phi, NULL);
-
- setlabel(false);
- code(ASCOPYW, tmp, constnode(&aux2, 0, tp), NULL);
-
- setlabel(phi->u.sym);
- return tmp;
case OMOD:
case OSHL:
case OBAND:
@@ -720,6 +667,12 @@ cgen(Node *np)
code(ASJMP, NULL, &true, NULL);
break;
case OBRANCH:
+ /*
+ * QBE does not accept labels at the end of a function
+ * (ONOP is used for labels) so we have to add a ret
+ * there, and in the case of branches we need a label
+ * for the next statement.
+ */
next = np->next;
if (!next->label)
labelstmt(next, NULL);
diff --git a/src/cmd/scc-cc/cc2/sethi.c b/src/cmd/scc-cc/cc2/sethi.c
@@ -15,13 +15,13 @@ bool(Node *np, Symbol *true, Symbol *false)
case OAND:
label = newlabel();
l = bool(l, label, false);
- addstmt(labelstmt(NULL, label));
+ prestmt(labelstmt(NULL, label));
r = bool(r, true, false);
break;
case OOR:
label = newlabel();
l = bool(l, true, label);
- addstmt(labelstmt(NULL, label));
+ prestmt(labelstmt(NULL, label));
r = bool(r, true, false);
break;
default:
@@ -29,12 +29,12 @@ bool(Node *np, Symbol *true, Symbol *false)
p->left = sethi(np);
p->u.sym = true;
true->refcnt++;
- addstmt(p);
+ prestmt(p);
p = node(OJMP);
p->u.sym = false;
false->refcnt++;
- addstmt(p);
+ prestmt(p);
return NULL;
}
@@ -44,6 +44,44 @@ bool(Node *np, Symbol *true, Symbol *false)
}
Node *
+logicexpr(Node *np)
+{
+ Node *tmpvar, *p;
+ Type *tp = &np->type;
+ Symbol *true, *false, *phi;
+
+ true = newlabel();
+ false = newlabel();
+ phi = newlabel();
+
+ bool(np, true, false);
+
+ tmpvar = tmpnode(tp, NULL);
+
+ p = node(OASSIG);
+ p->type = *tp;
+ p->left = tmpnode(tp, tmpvar->u.sym);
+ p->right = constnode(NULL, 0, tp);
+ prestmt(labelstmt(sethi(p), false));
+
+ p = node(OJMP);
+ p->u.sym = phi;
+ phi->refcnt++;
+ prestmt(p);
+
+ p = node(OASSIG);
+ p->type = *tp;
+ p->left = tmpnode(tp, tmpvar->u.sym);
+ p->right = constnode(NULL, 1, tp);
+ prestmt(labelstmt(sethi(p), true));
+
+ prestmt(labelstmt(NULL, phi));
+ delstmt(np);
+
+ return sethi(tmpvar);
+}
+
+Node *
sethi(Node *np)
{
int op;
@@ -73,6 +111,11 @@ sethi(Node *np)
bool(np->left, np->u.sym, next->label);
np->u.sym->refcnt--;
return NULL;
+ case ONEG:
+ case OAND:
+ case OOR:
+ np = logicexpr(np);
+ break;
default:
np = tsethi(np);
break;
diff --git a/src/cmd/scc-cc/cc2/z80-scc/cgen.c b/src/cmd/scc-cc/cc2/z80-scc/cgen.c
@@ -416,9 +416,6 @@ rhs(Node *np)
case OTMP:
case OCONST:
case OREG:
- case ONEG:
- case OAND:
- case OOR:
case OMOD:
case OSHL:
case OBAND:
@@ -472,37 +469,6 @@ lhs(Node *np)
}
static void
-bool(Node *np, Symbol *true, Symbol *false)
-{
- Node *l = np->left, *r = np->right;
- Node ret, ifyes, ifno;
- Symbol *label;
-
- switch (np->op) {
- case ONEG:
- bool(l, false, true);
- break;
- case OAND:
- label = newlabel();
- bool(l, label, false);
- setlabel(label);
- bool(r, true, false);
- break;
- case OOR:
- label = newlabel();
- bool(l, true, label);
- setlabel(label);
- bool(r, true, false);
- break;
- default:
- label2node(&ifyes, true);
- label2node(&ifno, false);
- code(ASBRANCH, rhs(np), &ifyes, &ifno);
- break;
- }
-}
-
-static void
ret(Node *np)
{
Node aux;
@@ -535,10 +501,7 @@ cgen(Node *np)
code(ASJP, NULL, &aux, NULL);
break;
case OBRANCH:
- next = np->next;
- if (!next->label)
- next->label = newlabel();
- bool(np->left, np->u.sym, next->label);
+ /* TODO */
break;
case ORET:
ret(np);