ref: 98bc946e4cdf9072897f0971067370fe094701d9
parent: c90ecde37fd10246d10b626bb4018ebee34420fc
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Wed Aug 17 14:01:31 EDT 2016
[cc2-qbe] Remove cgen.c.old All the bits were already taken, so we do not need anymore this file.
--- a/cc2/arch/qbe/cgen.c
+++ b/cc2/arch/qbe/cgen.c
@@ -506,6 +506,14 @@
return load(rhs(l, &aux1), ret);
case OADDR:
return lhs(l, ret);
+ case OFIELD:
+ case OINC:
+ case ODEC:
+ case OCASE:
+ case ODEFAULT:
+ case OESWITCH:
+ case OBSWITCH:
+ /* TODO: implement these operators */
default:
abort();
}
--- a/cc2/arch/qbe/cgen.c.old
+++ /dev/null
@@ -1,568 +1,0 @@
-/* See LICENSE file for copyright and license details. */
-#include <assert.h>
-#include <stdlib.h>
-
-#include "arch.h"
-#include "../../cc2.h"
-#include "../../../inc/sizes.h"
-
-enum lflags {
- FORCE = 1 << 0,
- LOADL = 1 << 1,
- LOADR = 1 << 2
-};
-
-enum sflags {
- ISTMP = 1,
- 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)
-{
- Symbol *sym;
-
- sym = getsym(TMPSYM);
- sym->type = np->type;
- sym->kind = STMP;
- np->u.sym = sym;
- np->op = OTMP;
- np->flags |= ISTMP;
- return np;
-}
-
-/*
- * load() load the address passed in a child of np in a temporary
- * if it is not already in a temporay. It can be forced to load
- * using the FORCE flag
- */
-static Node *
-load(Node *np, int flags)
-{
- int op;
- Type *tp;
- Node *child;
-
- child = (flags & LOADL) ? np->left : np->right;
- if (!child)
- return NULL;
- tp = &child->type;
-
- if ((flags & FORCE) || !(child->flags & (ISTMP|ISCONS))) {
- Node *new = tmpnode(newnode(OTMP));
- new->type = *tp;
- new->left = child;
-
- switch (tp->size) {
- case 1:
- op = ASLDB;
- break;
- case 2:
- op = ASLDH;
- break;
- case 4:
- op = (tp->flags & INTF) ? ASLDW : ASLDS;
- break;
- case 8:
- op = (tp->flags & INTF) ? ASLDL : ASLDD;
- break;
- default:
- abort();
- }
- code(op, new, child, NULL);
- child = new;
- }
-
- return (flags & LOADL) ? (np->left = child) : (np->right = child);
-}
-
-static Node *
-cast(Node *nd)
-{
- Type *ts, *td;
- Node *tmp, *ns;
- int op, disint, sisint;
- extern Type uint32type, int32type;
-
- ns = load(nd, LOADL);
- td = &nd->type;
- ts = &ns->type;
- disint = (td->flags & INTF) != 0;
- sisint = (ts->flags & INTF) != 0;
-
- if (disint && sisint) {
- if (td->size <= ts->size)
- return nd;
- assert(td->size == 4 || td->size == 8);
- switch (ts->size) {
- case 1:
- op = (td->size == 4) ? ASEXTBW : ASEXTBL;
- break;
- case 2:
- op = (td->size == 4) ? ASEXTHW : ASEXTHL;
- break;
- case 4:
- op = ASEXTWL;
- break;
- default:
- abort();
- }
- /*
- * unsigned version of operations are always +1 the
- * signed version
- */
- op += (td->flags & SIGNF) == 0;
- } else if (disint) {
- /* conversion from float to int */
- switch (ts->size) {
- case 4:
- op = (td->size == 8) ? ASSTOL : ASSTOW;
- break;
- case 8:
- op = (td->size == 8) ? ASDTOL : ASDTOW;
- break;
- default:
- abort();
- }
- /* TODO: Add signess */
- } else if (sisint) {
- /* conversion from int to float */
- switch (ts->size) {
- case 1:
- case 2:
- tmp = tmpnode(newnode(ONOP));
- tmp->type = (ts->flags&SIGNF) ? int32type : uint32type;
- tmp->left = ns;
- nd->left = ns = cast(tmp);
- case 4:
- op = (td->size == 8) ? ASSWTOD : ASSWTOS;
- break;
- case 8:
- op = (td->size == 8) ? ASSLTOD : ASSLTOS;
- break;
- default:
- abort();
- }
- /* TODO: Add signess */
- } else {
- /* conversion from float to float */
- op = (td->size == 4) ? ASEXTS : ASTRUNCD;
- }
- code(op, tmpnode(nd), ns, NULL);
- return nd;
-}
-
-static Node *
-call(Node *np)
-{
- int n, op;
- Type *tp = &np->type;
- Node **q, *tmp, *p, *pars[NR_FUNPARAM];
-
- for (n = 0, p = np->right; p; p = p->right) {
- cgen(p->left);
- pars[n++] = load(p, LOADL);
- }
-
- switch (tp->size) {
- case 0:
- np->left = tmpnode(newnode(OTMP));
- op = ASCALLW;
- break;
- case 1:
- op = ASCALLB;
- break;
- case 2:
- op = ASCALLH;
- break;
- case 4:
- op = (tp->flags & INTF) ? ASCALLW : ASCALLS;
- break;
- case 8:
- op = (tp->flags & INTF) ? ASCALLL : ASCALLD;
- break;
- default:
- abort();
- }
- code(op, tmpnode(np), np->left, NULL);
-
- for (q = pars; q < &pars[n]; ++q) {
- op = (q == &pars[n-1]) ? ASPARE : ASPAR;
- p = newnode(OTMP);
- p->type = (*q)->type;
- code(op, NULL, *q, tmpnode(p));
- }
- code(ASCALL, NULL, NULL, NULL);
-
- return np;
-}
-
-static Node *
-abbrev(Node *np)
-{
- Node *tmp;
-
- if (np->u.subop == 0)
- return np->right;
- tmp = newnode(np->u.subop);
- tmp->type = np->type;
- tmp->right = np->right;
- tmp->left = np->left;
- return np->right = cgen(tmp);
-}
-
-static Node *
-assign(Node *to, Node *from)
-{
- Type *tp = &to->type;
- int op;
-
- switch (tp->size) {
- case 1:
- op = ASSTB;
- break;
- case 2:
- op = ASSTH;
- break;
- case 4:
- op = (tp->flags & INTF) ? ASSTW : ASSTS;
- break;
- case 8:
- op = (tp->flags & INTF) ? ASSTL : ASSTD;
- break;
- default:
- abort();
- }
- code(op, to, from, NULL);
- return from;
-}
-
-static Node *
-ternary(Node *np)
-{
- Symbol *yes, *no, *phi;
- Node *ifyes, *ifno, *phinode, *colon;
-
- tmpnode(np);
- phi = newlabel();
- yes = newlabel();
- no = newlabel();
-
- ifyes = label2node(yes);
- ifno = label2node(no);
- phinode = label2node(phi);
-
- colon = np->right;
- cgen(np->left);
- code(ASBRANCH, load(np, LOADL), 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;
-}
-
-static Node *
-function(void)
-{
- Symbol *p;
-
- /* allocate stack space for parameters */
- for (p = locals; p && (p->type.flags & PARF) != 0; p = p->next)
- code(ASALLOC, label2node(p), NULL, NULL);
-
- /* allocate stack space for local variables) */
- for ( ; p && p->id != TMPSYM; p = p->next) {
- if (p->kind != SAUTO)
- continue;
- code(ASALLOC, label2node(p), NULL, NULL);
- }
- /* store formal parameters in parameters */
- for (p = locals; p; p = p->next) {
- if ((p->type.flags & PARF) == 0)
- break;
- code(ASFORM, label2node(p), NULL, NULL);
- }
- return NULL;
-}
-
-/* TODO: Fix "memory leaks" */
-Node *
-cgen(Node *np)
-{
- Node *ifyes, *ifno, *next;
- Symbol *sym;
- Type *tp;
- int op, off;
- char *tbl;
-
- if (!np)
- return NULL;
-
- setlabel(np->label);
- if (np->op != OCALL && np->op != OASK) {
- np->left = cgen(np->left);
- np->right = cgen(np->right);
- }
- tp = &np->type;
-
- switch (np->op) {
- case OSTRING:
- abort();
- case OBFUN:
- return function();
- case OEFUN:
- return NULL;
- case OCONST:
- case OLABEL:
- np->flags |= ISCONS;
- case OMEM:
- case OAUTO:
- return np;
- 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:
- 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;
- code(op, tmpnode(np), load(np, LOADL), load(np, LOADR));
- return np;
- case ONOP:
- case OBLOOP:
- case OELOOP:
- return NULL;
- case OCAST:
- return cast(np);
- case OADDR:
- np->flags |= ISTMP;
- np->op = OTMP;
- np->u.sym = np->left->u.sym;
- return np;
- case OPTR:
- load(np, LOADL);
- load(np, LOADL|FORCE);
- return np->left;
- case OCPL:
- case ONEG:
- case OINC:
- case ODEC:
- abort();
- case OASSIG:
- abbrev(np);
- return assign(np->left, load(np, LOADR));
- case OCOMMA:
- return np->right;
- case OCALL:
- return call(np);
- case OFIELD:
- case OAND:
- case OOR:
- abort();
- case OASK:
- return ternary(np);
- case OBRANCH:
- next = np->next;
- load(np, LOADL);
- if (!next->label)
- next->label = newlabel();
- ifyes = label2node(np->u.sym);
- ifno = label2node(next->label);
- op = ASBRANCH;
- np = np->left;
- goto emit_jump;
- case OJMP:
- ifyes = label2node(np->u.sym);
- op = ASJMP;
- np = ifno = NULL;
- emit_jump:
- code(op, np, ifyes, ifno);
- deltree(ifyes);
- deltree(ifno);
- return NULL;
- case ORET:
- code(ASRET, NULL, load(np, LOADL), NULL);
- return NULL;
- case OCASE:
- case ODEFAULT:
- case OESWITCH:
- case OBSWITCH:
- default:
- abort();
- }
-}
-
-/*
- * This is strongly influenced by
- * http://plan9.bell-labs.com/sys/doc/compiler.ps (/sys/doc/compiler.ps)
- * calculate addresability as follows
- * AUTO => 11 value+fp
- * REG => 11 reg
- * STATIC => 11 (value)
- * CONST => 11 $value
- * These values of addressability are not used in the code generation.
- * They are only used to calculate the Sethi-Ullman numbers. Since
- * QBE is AMD64 targered we could do a better job here, and try to
- * detect some of the complex addressing modes of these processors.
- */
-Node *
-sethi(Node *np)
-{
- Node *lp, *rp;
-
- if (!np)
- return np;
-
- np->complex = 0;
- np->address = 0;
- lp = np->left;
- rp = np->right;
-
- switch (np->op) {
- case OAUTO:
- case OREG:
- case OMEM:
- case OCONST:
- np->address = 11;
- break;
- default:
- sethi(lp);
- sethi(rp);
- break;
- }
-
- if (np->address > 10)
- return np;
- if (lp)
- np->complex = lp->complex;
- if (rp) {
- int d = np->complex - rp->complex;
-
- if (d == 0)
- ++np->complex;
- else if (d < 0)
- np->complex = rp->complex;
- }
- if (np->complex == 0)
- ++np->complex;
- return np;
-}