scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 2390716a3f75f8cbf38b5269a51491b6376d5cac
parent d58dc621c7bab54a868b43eba4f5da6b4d8ba5dc
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon, 18 Jul 2016 18:05:11 +0200

[cc2-qbe] Add binary operators in qbe

This patch only re-introduce the binary operators
and move code from rhs to cgen.

Diffstat:
Mcc2/arch/qbe/cgen.c | 182++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 166 insertions(+), 16 deletions(-)

diff --git a/cc2/arch/qbe/cgen.c b/cc2/arch/qbe/cgen.c @@ -11,6 +11,85 @@ enum sflags { ISCONS = 2 }; +static char opasmw[] = { + [OADD] = ASADDW, + [OSUB] = ASSUBW, + [OMUL] = ASMULW, + [OMOD] = ASMODW, + [ODIV] = ASDIVW, + [OSHL] = ASSHLW, + [OSHR] = ASSHRW, + [OLT] = ASLTW, + [OGT] = ASGTW, + [OLE] = ASLEW, + [OGE] = ASGEW, + [OEQ] = ASEQW, + [ONE] = ASNEW, + [OBAND] = ASBANDW, + [OBOR] = ASBORW, + [OBXOR] = ASBXORW, + [OCPL] = ASCPLW +}; + +static char opasml[] = { + [OADD] = ASADDL, + [OSUB] = ASSUBL, + [OMUL] = ASMULL, + [OMOD] = ASMODL, + [ODIV] = ASDIVL, + [OSHL] = ASSHLL, + [OSHR] = ASSHRL, + [OLT] = ASLTL, + [OGT] = ASGTL, + [OLE] = ASLEL, + [OGE] = ASGEL, + [OEQ] = ASEQL, + [ONE] = ASNEL, + [OBAND] = ASBANDL, + [OBOR] = ASBORL, + [OBXOR] = ASBXORL, + [OCPL] = ASCPLL +}; + +static char opasms[] = { + [OADD] = ASADDS, + [OSUB] = ASSUBS, + [OMUL] = ASMULS, + [OMOD] = ASMODS, + [ODIV] = ASDIVS, + [OSHL] = ASSHLS, + [OSHR] = ASSHRS, + [OLT] = ASLTS, + [OGT] = ASGTS, + [OLE] = ASLES, + [OGE] = ASGES, + [OEQ] = ASEQS, + [ONE] = ASNES, + [OBAND] = ASBANDS, + [OBOR] = ASBORS, + [OBXOR] = ASBXORS, + [OCPL] = ASCPLS +}; +static char opasmd[] = { + [OADD] = ASADDD, + [OSUB] = ASSUBD, + [OMUL] = ASMULD, + [OMOD] = ASMODD, + [ODIV] = ASDIVD, + [OSHL] = ASSHLD, + [OSHR] = ASSHRD, + [OLT] = ASLTD, + [OGT] = ASGTD, + [OLE] = ASLED, + [OGE] = ASGED, + [OEQ] = ASEQD, + [ONE] = ASNED, + [OBAND] = ASBANDD, + [OBOR] = ASBORD, + [OBXOR] = ASBXORD, + [OCPL] = ASCPLD +}; + static Node * tmpnode(Node *np) { @@ -56,15 +135,11 @@ load(Node *np, Node *new) } static Node * -assign(Node *np, Node *new) +assign(Node *to, Node *from) { - Node *to, *from; Type *tp; int op; - to = np->left; - from = np->right; - tp = &to->type; switch (tp->size) { case 1: @@ -159,40 +234,115 @@ function(void) } static Node * -rhs(Node *np, Node *new) +rhs(Node *np, Node *ret) { - Node aux; + Node aux1, aux2, *l = np->left, *r = np->right; + Type *tp; + int off, op; + char *tbl; + Symbol *true, *false; + + setlabel(np->label); + tp = &np->type; switch (np->op) { case OBFUN: return function(); + case ONOP: case OEFUN: return NULL; + case OCONST: case OMEM: case OAUTO: - return load(np, new); + return load(np, ret); + case OAND: + case OOR: + true = newlabel(); + false = newlabel(); + bool(np, ret, true, false); + setlabel(true); + setlabel(false); + return ret; + case OSHR: + case OMOD: + case ODIV: + case OLT: + case OGT: + case OLE: + case OGE: + /* + * unsigned version of operations are always +1 the + * signed version + */ + off = (tp->flags & SIGNF) == 0; + goto binary; + case OADD: + case OSUB: + case OMUL: + case OSHL: + case OBAND: + case OBOR: + case OBXOR: + case OEQ: + case ONE: + off = 0; + binary: + if (l->complex >= r->complex) { + rhs(l, &aux1); + rhs(r, &aux2); + } else { + rhs(r, &aux2); + rhs(l, &aux1); + } + switch (tp->size) { + case 4: + tbl = (tp->flags & INTF) ? opasmw : opasms; + break; + case 8: + tbl = (tp->flags & INTF) ? opasml : opasmd; + break; + default: + abort(); + } + op = tbl[np->op] + off; + ret = tmpnode(ret); + code(op, ret, &aux1, &aux2); + return ret; case OASSIG: - lhs(np->left, new); - rhs(np->right, &aux); - assign(&aux, new); - return new; + lhs(l, &aux1); + rhs(r, ret); + return assign(&aux1, ret); default: abort(); } + abort(); } Node * cgen(Node *np) { - Node n, *aux; + Node n, *aux, *next, *ifyes, *ifno; Symbol *label1, *label2; switch (np->op) { case OJMP: - code(ASJMP, NULL, NULL, NULL); - break; - case OBRANCH: + ifyes = label2node(np->u.sym); + code(ASJMP, NULL, ifyes, NULL); + deltree(ifyes); break; + case OBRANCH: + next = np->next; + if (!next->label) + next->label = newlabel(); + ifyes = label2node(np->u.sym); + ifno = label2node(next->label); + bool(np->left, &n, ifyes->u.sym, ifno->u.sym); + code(ASBRANCH, &n, ifyes, ifno); + setlabel(ifyes->u.sym); + setlabel(ifno->u.sym); + deltree(ifyes); + deltree(ifno); + break; case ORET: aux = (np->left) ? rhs(np->left, &n) : NULL; code(ASRET, aux, NULL, NULL);