scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

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:
Msrc/cmd/scc-cc/cc2/cc2.h | 1+
Msrc/cmd/scc-cc/cc2/node.c | 6++++++
Msrc/cmd/scc-cc/cc2/qbe/cgen.c | 63++++++++-------------------------------------------------------
Msrc/cmd/scc-cc/cc2/sethi.c | 51+++++++++++++++++++++++++++++++++++++++++++++++----
Msrc/cmd/scc-cc/cc2/z80-scc/cgen.c | 39+--------------------------------------
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);