OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [tags/] [eco32-0.26/] [fp/] [investigate/] [dag.c] - Diff between revs 15 and 270

Only display areas with differences | Details | Blame | View Log

Rev 15 Rev 270
#include "c.h"
#include "c.h"
 
 
static char rcsid[] = "$Id: dag.c,v 1.1 2002/08/28 23:12:42 drh Exp $";
static char rcsid[] = "$Id: dag.c,v 1.1 2002/08/28 23:12:42 drh Exp $";
 
 
#define iscall(op) (generic(op) == CALL \
#define iscall(op) (generic(op) == CALL \
        || IR->mulops_calls \
        || IR->mulops_calls \
        && (generic(op)==DIV||generic(op)==MOD||generic(op)==MUL) \
        && (generic(op)==DIV||generic(op)==MOD||generic(op)==MUL) \
        && ( optype(op)==U  || optype(op)==I))
        && ( optype(op)==U  || optype(op)==I))
static Node forest;
static Node forest;
static struct dag {
static struct dag {
        struct node node;
        struct node node;
        struct dag *hlink;
        struct dag *hlink;
} *buckets[16];
} *buckets[16];
int nodecount;
int nodecount;
static Tree firstarg;
static Tree firstarg;
int assignargs = 1;
int assignargs = 1;
int prunetemps = -1;
int prunetemps = -1;
static Node *tail;
static Node *tail;
 
 
static int depth = 0;
static int depth = 0;
static Node replace(Node);
static Node replace(Node);
static Node prune(Node);
static Node prune(Node);
static Node asgnnode(Symbol, Node);
static Node asgnnode(Symbol, Node);
static struct dag *dagnode(int, Node, Node, Symbol);
static struct dag *dagnode(int, Node, Node, Symbol);
static Symbol equated(Symbol);
static Symbol equated(Symbol);
static void fixup(Node);
static void fixup(Node);
static void labelnode(int);
static void labelnode(int);
static void list(Node);
static void list(Node);
static void killnodes(Symbol);
static void killnodes(Symbol);
static Node node(int, Node, Node, Symbol);
static Node node(int, Node, Node, Symbol);
static void printdag1(Node, int, int);
static void printdag1(Node, int, int);
static void printnode(Node, int, int);
static void printnode(Node, int, int);
static void reset(void);
static void reset(void);
static Node tmpnode(Node);
static Node tmpnode(Node);
static void typestab(Symbol, void *);
static void typestab(Symbol, void *);
static Node undag(Node);
static Node undag(Node);
static Node visit(Node, int);
static Node visit(Node, int);
static void unlist(void);
static void unlist(void);
void walk(Tree tp, int tlab, int flab) {
void walk(Tree tp, int tlab, int flab) {
        listnodes(tp, tlab, flab);
        listnodes(tp, tlab, flab);
        if (forest) {
        if (forest) {
                Node list = forest->link;
                Node list = forest->link;
                forest->link = NULL;
                forest->link = NULL;
                if (!IR->wants_dag && errcnt == 0)
                if (!IR->wants_dag && errcnt == 0)
                        list = undag(list);
                        list = undag(list);
                code(Gen)->u.forest = list;
                code(Gen)->u.forest = list;
                forest = NULL;
                forest = NULL;
        }
        }
        reset();
        reset();
        deallocate(STMT);
        deallocate(STMT);
}
}
 
 
static Node node(int op, Node l, Node r, Symbol sym) {
static Node node(int op, Node l, Node r, Symbol sym) {
        int i;
        int i;
        struct dag *p;
        struct dag *p;
 
 
        i = (opindex(op)^((unsigned long)sym>>2))&(NELEMS(buckets)-1);
        i = (opindex(op)^((unsigned long)sym>>2))&(NELEMS(buckets)-1);
        for (p = buckets[i]; p; p = p->hlink)
        for (p = buckets[i]; p; p = p->hlink)
                if (p->node.op      == op && p->node.syms[0] == sym
                if (p->node.op      == op && p->node.syms[0] == sym
                &&  p->node.kids[0] == l  && p->node.kids[1] == r)
                &&  p->node.kids[0] == l  && p->node.kids[1] == r)
                        return &p->node;
                        return &p->node;
        p = dagnode(op, l, r, sym);
        p = dagnode(op, l, r, sym);
        p->hlink = buckets[i];
        p->hlink = buckets[i];
        buckets[i] = p;
        buckets[i] = p;
        ++nodecount;
        ++nodecount;
        return &p->node;
        return &p->node;
}
}
static struct dag *dagnode(int op, Node l, Node r, Symbol sym) {
static struct dag *dagnode(int op, Node l, Node r, Symbol sym) {
        struct dag *p;
        struct dag *p;
 
 
        NEW0(p, FUNC);
        NEW0(p, FUNC);
        p->node.op = op;
        p->node.op = op;
        if ((p->node.kids[0] = l) != NULL)
        if ((p->node.kids[0] = l) != NULL)
                ++l->count;
                ++l->count;
        if ((p->node.kids[1] = r) != NULL)
        if ((p->node.kids[1] = r) != NULL)
                ++r->count;
                ++r->count;
        p->node.syms[0] = sym;
        p->node.syms[0] = sym;
        return p;
        return p;
}
}
Node newnode(int op, Node l, Node r, Symbol sym) {
Node newnode(int op, Node l, Node r, Symbol sym) {
        return &dagnode(op, l, r, sym)->node;
        return &dagnode(op, l, r, sym)->node;
}
}
static void killnodes(Symbol p) {
static void killnodes(Symbol p) {
        int i;
        int i;
        struct dag **q;
        struct dag **q;
 
 
        for (i = 0; i < NELEMS(buckets); i++)
        for (i = 0; i < NELEMS(buckets); i++)
                for (q = &buckets[i]; *q; )
                for (q = &buckets[i]; *q; )
                        if (generic((*q)->node.op) == INDIR &&
                        if (generic((*q)->node.op) == INDIR &&
                            (!isaddrop((*q)->node.kids[0]->op)
                            (!isaddrop((*q)->node.kids[0]->op)
                             || (*q)->node.kids[0]->syms[0] == p)) {
                             || (*q)->node.kids[0]->syms[0] == p)) {
                                *q = (*q)->hlink;
                                *q = (*q)->hlink;
                                --nodecount;
                                --nodecount;
                        } else
                        } else
                                q = &(*q)->hlink;
                                q = &(*q)->hlink;
}
}
static void reset(void) {
static void reset(void) {
        if (nodecount > 0)
        if (nodecount > 0)
                memset(buckets, 0, sizeof buckets);
                memset(buckets, 0, sizeof buckets);
        nodecount = 0;
        nodecount = 0;
}
}
Node listnodes(Tree tp, int tlab, int flab) {
Node listnodes(Tree tp, int tlab, int flab) {
        Node p = NULL, l, r;
        Node p = NULL, l, r;
        int op;
        int op;
 
 
        assert(tlab || flab || tlab == 0 && flab == 0);
        assert(tlab || flab || tlab == 0 && flab == 0);
        if (tp == NULL)
        if (tp == NULL)
                return NULL;
                return NULL;
        if (tp->node)
        if (tp->node)
                return tp->node;
                return tp->node;
        if (isarray(tp->type))
        if (isarray(tp->type))
                op = tp->op + sizeop(voidptype->size);
                op = tp->op + sizeop(voidptype->size);
        else
        else
                op = tp->op + sizeop(tp->type->size);
                op = tp->op + sizeop(tp->type->size);
        switch (generic(tp->op)) {
        switch (generic(tp->op)) {
        case AND:   { if (depth++ == 0) reset();
        case AND:   { if (depth++ == 0) reset();
                      if (flab) {
                      if (flab) {
                        listnodes(tp->kids[0], 0, flab);
                        listnodes(tp->kids[0], 0, flab);
                        listnodes(tp->kids[1], 0, flab);
                        listnodes(tp->kids[1], 0, flab);
                      } else {
                      } else {
                        listnodes(tp->kids[0], 0, flab = genlabel(1));
                        listnodes(tp->kids[0], 0, flab = genlabel(1));
                        listnodes(tp->kids[1], tlab, 0);
                        listnodes(tp->kids[1], tlab, 0);
                        labelnode(flab);
                        labelnode(flab);
                      }
                      }
                      depth--; } break;
                      depth--; } break;
        case OR:    { if (depth++ == 0)
        case OR:    { if (depth++ == 0)
                        reset();
                        reset();
                      if (tlab) {
                      if (tlab) {
                        listnodes(tp->kids[0], tlab, 0);
                        listnodes(tp->kids[0], tlab, 0);
                        listnodes(tp->kids[1], tlab, 0);
                        listnodes(tp->kids[1], tlab, 0);
                      } else {
                      } else {
                        tlab = genlabel(1);
                        tlab = genlabel(1);
                        listnodes(tp->kids[0], tlab, 0);
                        listnodes(tp->kids[0], tlab, 0);
                        listnodes(tp->kids[1], 0, flab);
                        listnodes(tp->kids[1], 0, flab);
                        labelnode(tlab);
                        labelnode(tlab);
                      }
                      }
                      depth--;
                      depth--;
 } break;
 } break;
        case NOT:   { return listnodes(tp->kids[0], flab, tlab); }
        case NOT:   { return listnodes(tp->kids[0], flab, tlab); }
        case COND:  { Tree q = tp->kids[1];
        case COND:  { Tree q = tp->kids[1];
                      assert(tlab == 0 && flab == 0);
                      assert(tlab == 0 && flab == 0);
                      if (tp->u.sym)
                      if (tp->u.sym)
                        addlocal(tp->u.sym);
                        addlocal(tp->u.sym);
                      flab = genlabel(2);
                      flab = genlabel(2);
                      listnodes(tp->kids[0], 0, flab);
                      listnodes(tp->kids[0], 0, flab);
                      assert(q && q->op == RIGHT);
                      assert(q && q->op == RIGHT);
                      reset();
                      reset();
                      listnodes(q->kids[0], 0, 0);
                      listnodes(q->kids[0], 0, 0);
                      if (forest->op == LABEL+V) {
                      if (forest->op == LABEL+V) {
                        equatelab(forest->syms[0], findlabel(flab + 1));
                        equatelab(forest->syms[0], findlabel(flab + 1));
                        unlist();
                        unlist();
                      }
                      }
                      list(jump(flab + 1));
                      list(jump(flab + 1));
                      labelnode(flab);
                      labelnode(flab);
                      listnodes(q->kids[1], 0, 0);
                      listnodes(q->kids[1], 0, 0);
                      if (forest->op == LABEL+V) {
                      if (forest->op == LABEL+V) {
                        equatelab(forest->syms[0], findlabel(flab + 1));
                        equatelab(forest->syms[0], findlabel(flab + 1));
                        unlist();
                        unlist();
                      }
                      }
                      labelnode(flab + 1);
                      labelnode(flab + 1);
 
 
                      if (tp->u.sym)
                      if (tp->u.sym)
                        p = listnodes(idtree(tp->u.sym), 0, 0); } break;
                        p = listnodes(idtree(tp->u.sym), 0, 0); } break;
        case CNST:  { Type ty = unqual(tp->type);
        case CNST:  { Type ty = unqual(tp->type);
                      assert(ty->u.sym);
                      assert(ty->u.sym);
                      if (tlab || flab) {
                      if (tlab || flab) {
                        assert(ty == inttype);
                        assert(ty == inttype);
                        if (tlab && tp->u.v.i != 0)
                        if (tlab && tp->u.v.i != 0)
                                list(jump(tlab));
                                list(jump(tlab));
                        else if (flab && tp->u.v.i == 0)
                        else if (flab && tp->u.v.i == 0)
                                list(jump(flab));
                                list(jump(flab));
                      }
                      }
                      else if (ty->u.sym->addressed)
                      else if (ty->u.sym->addressed)
                        p = listnodes(cvtconst(tp), 0, 0);
                        p = listnodes(cvtconst(tp), 0, 0);
                      else
                      else
                        p = node(op, NULL, NULL, constant(ty, tp->u.v)); } break;
                        p = node(op, NULL, NULL, constant(ty, tp->u.v)); } break;
        case RIGHT: { if (   tp->kids[0] && tp->kids[1]
        case RIGHT: { if (   tp->kids[0] && tp->kids[1]
                          &&  generic(tp->kids[1]->op) == ASGN
                          &&  generic(tp->kids[1]->op) == ASGN
                          && (generic(tp->kids[0]->op) == INDIR
                          && (generic(tp->kids[0]->op) == INDIR
                          && tp->kids[0]->kids[0] == tp->kids[1]->kids[0]
                          && tp->kids[0]->kids[0] == tp->kids[1]->kids[0]
                          || (tp->kids[0]->op == FIELD
                          || (tp->kids[0]->op == FIELD
                          &&  tp->kids[0] == tp->kids[1]->kids[0]))) {
                          &&  tp->kids[0] == tp->kids[1]->kids[0]))) {
                        assert(tlab == 0 && flab == 0);
                        assert(tlab == 0 && flab == 0);
                        if (generic(tp->kids[0]->op) == INDIR) {
                        if (generic(tp->kids[0]->op) == INDIR) {
                                p = listnodes(tp->kids[0], 0, 0);
                                p = listnodes(tp->kids[0], 0, 0);
                                list(p);
                                list(p);
                                listnodes(tp->kids[1], 0, 0);
                                listnodes(tp->kids[1], 0, 0);
                        }
                        }
                        else {
                        else {
                                assert(generic(tp->kids[0]->kids[0]->op) == INDIR);
                                assert(generic(tp->kids[0]->kids[0]->op) == INDIR);
                                list(listnodes(tp->kids[0]->kids[0], 0, 0));
                                list(listnodes(tp->kids[0]->kids[0], 0, 0));
                                p = listnodes(tp->kids[0], 0, 0);
                                p = listnodes(tp->kids[0], 0, 0);
                                listnodes(tp->kids[1], 0, 0);
                                listnodes(tp->kids[1], 0, 0);
                        }
                        }
                      } else if (tp->kids[1]) {
                      } else if (tp->kids[1]) {
                        listnodes(tp->kids[0], 0, 0);
                        listnodes(tp->kids[0], 0, 0);
                        p = listnodes(tp->kids[1], tlab, flab);
                        p = listnodes(tp->kids[1], tlab, flab);
                      } else
                      } else
                        p = listnodes(tp->kids[0], tlab, flab); } break;
                        p = listnodes(tp->kids[0], tlab, flab); } break;
        case JUMP:  { assert(tlab == 0 && flab == 0);
        case JUMP:  { assert(tlab == 0 && flab == 0);
                      assert(tp->u.sym == 0);
                      assert(tp->u.sym == 0);
                      assert(tp->kids[0]);
                      assert(tp->kids[0]);
                      l = listnodes(tp->kids[0], 0, 0);
                      l = listnodes(tp->kids[0], 0, 0);
                      list(newnode(JUMP+V, l, NULL, NULL));
                      list(newnode(JUMP+V, l, NULL, NULL));
                      reset(); } break;
                      reset(); } break;
        case CALL:  { Tree save = firstarg;
        case CALL:  { Tree save = firstarg;
                      firstarg = NULL;
                      firstarg = NULL;
                      assert(tlab == 0 && flab == 0);
                      assert(tlab == 0 && flab == 0);
                      if (tp->op == CALL+B && !IR->wants_callb) {
                      if (tp->op == CALL+B && !IR->wants_callb) {
                        Tree arg0 = tree(ARG+P, tp->kids[1]->type,
                        Tree arg0 = tree(ARG+P, tp->kids[1]->type,
                                tp->kids[1], NULL);
                                tp->kids[1], NULL);
                        if (IR->left_to_right)
                        if (IR->left_to_right)
                                firstarg = arg0;
                                firstarg = arg0;
                        l = listnodes(tp->kids[0], 0, 0);
                        l = listnodes(tp->kids[0], 0, 0);
                        if (!IR->left_to_right || firstarg) {
                        if (!IR->left_to_right || firstarg) {
                                firstarg = NULL;
                                firstarg = NULL;
                                listnodes(arg0, 0, 0);
                                listnodes(arg0, 0, 0);
                        }
                        }
                        p = newnode(CALL+V, l, NULL, NULL);
                        p = newnode(CALL+V, l, NULL, NULL);
                      } else {
                      } else {
                        l = listnodes(tp->kids[0], 0, 0);
                        l = listnodes(tp->kids[0], 0, 0);
                        r = listnodes(tp->kids[1], 0, 0);
                        r = listnodes(tp->kids[1], 0, 0);
                        p = newnode(tp->op == CALL+B ? tp->op : op, l, r, NULL);
                        p = newnode(tp->op == CALL+B ? tp->op : op, l, r, NULL);
                      }
                      }
                      NEW0(p->syms[0], FUNC);
                      NEW0(p->syms[0], FUNC);
                      assert(isptr(tp->kids[0]->type));
                      assert(isptr(tp->kids[0]->type));
                      assert(isfunc(tp->kids[0]->type->type));
                      assert(isfunc(tp->kids[0]->type->type));
                      p->syms[0]->type = tp->kids[0]->type->type;
                      p->syms[0]->type = tp->kids[0]->type->type;
                      list(p);
                      list(p);
                      reset();
                      reset();
                      cfunc->u.f.ncalls++;
                      cfunc->u.f.ncalls++;
                      firstarg = save;
                      firstarg = save;
 } break;
 } break;
        case ARG:   { assert(tlab == 0 && flab == 0);
        case ARG:   { assert(tlab == 0 && flab == 0);
                      if (IR->left_to_right)
                      if (IR->left_to_right)
                        listnodes(tp->kids[1], 0, 0);
                        listnodes(tp->kids[1], 0, 0);
                      if (firstarg) {
                      if (firstarg) {
                        Tree arg = firstarg;
                        Tree arg = firstarg;
                        firstarg = NULL;
                        firstarg = NULL;
                        listnodes(arg, 0, 0);
                        listnodes(arg, 0, 0);
                      }
                      }
                      l = listnodes(tp->kids[0], 0, 0);
                      l = listnodes(tp->kids[0], 0, 0);
                      list(newnode(tp->op == ARG+B ? tp->op : op, l, NULL, NULL));
                      list(newnode(tp->op == ARG+B ? tp->op : op, l, NULL, NULL));
                      forest->syms[0] = intconst(tp->type->size);
                      forest->syms[0] = intconst(tp->type->size);
                      forest->syms[1] = intconst(tp->type->align);
                      forest->syms[1] = intconst(tp->type->align);
                      if (!IR->left_to_right)
                      if (!IR->left_to_right)
                        listnodes(tp->kids[1], 0, 0); } break;
                        listnodes(tp->kids[1], 0, 0); } break;
        case EQ:  case NE: case GT: case GE: case LE:
        case EQ:  case NE: case GT: case GE: case LE:
        case LT:    { assert(tp->u.sym == 0);
        case LT:    { assert(tp->u.sym == 0);
                      assert(errcnt || tlab || flab);
                      assert(errcnt || tlab || flab);
                      l = listnodes(tp->kids[0], 0, 0);
                      l = listnodes(tp->kids[0], 0, 0);
                      r = listnodes(tp->kids[1], 0, 0);
                      r = listnodes(tp->kids[1], 0, 0);
                      assert(errcnt || opkind(l->op) == opkind(r->op));
                      assert(errcnt || opkind(l->op) == opkind(r->op));
                      assert(errcnt || optype(op) == optype(l->op));
                      assert(errcnt || optype(op) == optype(l->op));
                      if (tlab)
                      if (tlab)
                        assert(flab == 0),
                        assert(flab == 0),
                        list(newnode(generic(tp->op) + opkind(l->op), l, r, findlabel(tlab)));
                        list(newnode(generic(tp->op) + opkind(l->op), l, r, findlabel(tlab)));
                      else if (flab) {
                      else if (flab) {
                        switch (generic(tp->op)) {
                        switch (generic(tp->op)) {
                        case EQ: op = NE; break;
                        case EQ: op = NE; break;
                        case NE: op = EQ; break;
                        case NE: op = EQ; break;
                        case GT: op = LE; break;
                        case GT: op = LE; break;
                        case LT: op = GE; break;
                        case LT: op = GE; break;
                        case GE: op = LT; break;
                        case GE: op = LT; break;
                        case LE: op = GT; break;
                        case LE: op = GT; break;
                        default: assert(0);
                        default: assert(0);
                        }
                        }
                        list(newnode(op + opkind(l->op), l, r, findlabel(flab)));
                        list(newnode(op + opkind(l->op), l, r, findlabel(flab)));
                      }
                      }
                      if (forest && forest->syms[0])
                      if (forest && forest->syms[0])
                        forest->syms[0]->ref++; } break;
                        forest->syms[0]->ref++; } break;
        case ASGN:  { assert(tlab == 0 && flab == 0);
        case ASGN:  { assert(tlab == 0 && flab == 0);
                      if (tp->kids[0]->op == FIELD) {
                      if (tp->kids[0]->op == FIELD) {
                        Tree  x = tp->kids[0]->kids[0];
                        Tree  x = tp->kids[0]->kids[0];
                        Field f = tp->kids[0]->u.field;
                        Field f = tp->kids[0]->u.field;
                        assert(generic(x->op) == INDIR);
                        assert(generic(x->op) == INDIR);
                        reset();
                        reset();
                        l = listnodes(lvalue(x), 0, 0);
                        l = listnodes(lvalue(x), 0, 0);
                        if (fieldsize(f) < 8*f->type->size) {
                        if (fieldsize(f) < 8*f->type->size) {
                                unsigned int fmask = fieldmask(f);
                                unsigned int fmask = fieldmask(f);
                                unsigned int  mask = fmask<<fieldright(f);
                                unsigned int  mask = fmask<<fieldright(f);
                                Tree q = tp->kids[1];
                                Tree q = tp->kids[1];
                                if (q->op == CNST+I && q->u.v.i == 0
                                if (q->op == CNST+I && q->u.v.i == 0
                                ||  q->op == CNST+U && q->u.v.u == 0)
                                ||  q->op == CNST+U && q->u.v.u == 0)
                                        q = bittree(BAND, x, cnsttree(unsignedtype, (unsigned long)~mask));
                                        q = bittree(BAND, x, cnsttree(unsignedtype, (unsigned long)~mask));
                                else if (q->op == CNST+I && (q->u.v.i&fmask) == fmask
                                else if (q->op == CNST+I && (q->u.v.i&fmask) == fmask
                                ||       q->op == CNST+U && (q->u.v.u&fmask) == fmask)
                                ||       q->op == CNST+U && (q->u.v.u&fmask) == fmask)
                                        q = bittree(BOR, x, cnsttree(unsignedtype, (unsigned long)mask));
                                        q = bittree(BOR, x, cnsttree(unsignedtype, (unsigned long)mask));
                                else {
                                else {
                                        listnodes(q, 0, 0);
                                        listnodes(q, 0, 0);
                                        q = bittree(BOR,
                                        q = bittree(BOR,
                                                bittree(BAND, rvalue(lvalue(x)),
                                                bittree(BAND, rvalue(lvalue(x)),
                                                        cnsttree(unsignedtype, (unsigned long)~mask)),
                                                        cnsttree(unsignedtype, (unsigned long)~mask)),
                                                bittree(BAND, shtree(LSH, cast(q, unsignedtype),
                                                bittree(BAND, shtree(LSH, cast(q, unsignedtype),
                                                        cnsttree(unsignedtype, (unsigned long)fieldright(f))),
                                                        cnsttree(unsignedtype, (unsigned long)fieldright(f))),
                                                        cnsttree(unsignedtype, (unsigned long)mask)));
                                                        cnsttree(unsignedtype, (unsigned long)mask)));
                                }
                                }
                                r = listnodes(q, 0, 0);
                                r = listnodes(q, 0, 0);
                                op = ASGN + ttob(q->type);
                                op = ASGN + ttob(q->type);
                        } else {
                        } else {
                                r = listnodes(tp->kids[1], 0, 0);
                                r = listnodes(tp->kids[1], 0, 0);
                                op = ASGN + ttob(tp->kids[1]->type);
                                op = ASGN + ttob(tp->kids[1]->type);
                        }
                        }
                      } else {
                      } else {
                        l = listnodes(tp->kids[0], 0, 0);
                        l = listnodes(tp->kids[0], 0, 0);
                        r = listnodes(tp->kids[1], 0, 0);
                        r = listnodes(tp->kids[1], 0, 0);
                      }
                      }
                      list(newnode(tp->op == ASGN+B ? tp->op : op, l, r, NULL));
                      list(newnode(tp->op == ASGN+B ? tp->op : op, l, r, NULL));
                      forest->syms[0] = intconst(tp->kids[1]->type->size);
                      forest->syms[0] = intconst(tp->kids[1]->type->size);
                      forest->syms[1] = intconst(tp->kids[1]->type->align);
                      forest->syms[1] = intconst(tp->kids[1]->type->align);
                      if (isaddrop(tp->kids[0]->op)
                      if (isaddrop(tp->kids[0]->op)
                      && !tp->kids[0]->u.sym->computed)
                      && !tp->kids[0]->u.sym->computed)
                        killnodes(tp->kids[0]->u.sym);
                        killnodes(tp->kids[0]->u.sym);
                      else
                      else
                        reset();
                        reset();
                      p = listnodes(tp->kids[1], 0, 0); } break;
                      p = listnodes(tp->kids[1], 0, 0); } break;
        case BOR: case BAND: case BXOR:
        case BOR: case BAND: case BXOR:
        case ADD: case SUB:  case RSH:
        case ADD: case SUB:  case RSH:
        case LSH:   { assert(tlab == 0 && flab == 0);
        case LSH:   { assert(tlab == 0 && flab == 0);
                      l = listnodes(tp->kids[0], 0, 0);
                      l = listnodes(tp->kids[0], 0, 0);
                      r = listnodes(tp->kids[1], 0, 0);
                      r = listnodes(tp->kids[1], 0, 0);
                      p = node(op, l, r, NULL); } break;
                      p = node(op, l, r, NULL); } break;
        case DIV: case MUL:
        case DIV: case MUL:
        case MOD:   { assert(tlab == 0 && flab == 0);
        case MOD:   { assert(tlab == 0 && flab == 0);
                      l = listnodes(tp->kids[0], 0, 0);
                      l = listnodes(tp->kids[0], 0, 0);
                      r = listnodes(tp->kids[1], 0, 0);
                      r = listnodes(tp->kids[1], 0, 0);
                      p = node(op, l, r, NULL);
                      p = node(op, l, r, NULL);
                      if (IR->mulops_calls && isint(tp->type)) {
                      if (IR->mulops_calls && isint(tp->type)) {
                        list(p);
                        list(p);
                        cfunc->u.f.ncalls++;
                        cfunc->u.f.ncalls++;
                      } } break;
                      } } break;
        case RET:   { assert(tlab == 0 && flab == 0);
        case RET:   { assert(tlab == 0 && flab == 0);
                      l = listnodes(tp->kids[0], 0, 0);
                      l = listnodes(tp->kids[0], 0, 0);
                      list(newnode(op, l, NULL, NULL)); } break;
                      list(newnode(op, l, NULL, NULL)); } break;
        case CVF: case CVI: case CVP:
        case CVF: case CVI: case CVP:
        case CVU:   { assert(tlab == 0 && flab == 0);
        case CVU:   { assert(tlab == 0 && flab == 0);
                      assert(optype(tp->kids[0]->op) != optype(tp->op) || tp->kids[0]->type->size != tp->type->size);
                      assert(optype(tp->kids[0]->op) != optype(tp->op) || tp->kids[0]->type->size != tp->type->size);
                      l = listnodes(tp->kids[0], 0, 0);
                      l = listnodes(tp->kids[0], 0, 0);
                      p = node(op, l, NULL, intconst(tp->kids[0]->type->size));
                      p = node(op, l, NULL, intconst(tp->kids[0]->type->size));
 } break;
 } break;
        case BCOM:
        case BCOM:
        case NEG:   { assert(tlab == 0 && flab == 0);
        case NEG:   { assert(tlab == 0 && flab == 0);
                      l = listnodes(tp->kids[0], 0, 0);
                      l = listnodes(tp->kids[0], 0, 0);
                      p = node(op, l, NULL, NULL); } break;
                      p = node(op, l, NULL, NULL); } break;
        case INDIR: { Type ty = tp->kids[0]->type;
        case INDIR: { Type ty = tp->kids[0]->type;
                      assert(tlab == 0 && flab == 0);
                      assert(tlab == 0 && flab == 0);
                      l = listnodes(tp->kids[0], 0, 0);
                      l = listnodes(tp->kids[0], 0, 0);
                      if (isptr(ty))
                      if (isptr(ty))
                        ty = unqual(ty)->type;
                        ty = unqual(ty)->type;
                      if (isvolatile(ty)
                      if (isvolatile(ty)
                      || (isstruct(ty) && unqual(ty)->u.sym->u.s.vfields))
                      || (isstruct(ty) && unqual(ty)->u.sym->u.s.vfields))
                        p = newnode(tp->op == INDIR+B ? tp->op : op, l, NULL, NULL);
                        p = newnode(tp->op == INDIR+B ? tp->op : op, l, NULL, NULL);
                      else
                      else
                        p = node(tp->op == INDIR+B ? tp->op : op, l, NULL, NULL); } break;
                        p = node(tp->op == INDIR+B ? tp->op : op, l, NULL, NULL); } break;
        case FIELD: { Tree q = tp->kids[0];
        case FIELD: { Tree q = tp->kids[0];
                      if (tp->type == inttype) {
                      if (tp->type == inttype) {
                        long n = fieldleft(tp->u.field);
                        long n = fieldleft(tp->u.field);
                        q = shtree(RSH,
                        q = shtree(RSH,
                                shtree(LSH, q, cnsttree(inttype, n)),
                                shtree(LSH, q, cnsttree(inttype, n)),
                                cnsttree(inttype, n + fieldright(tp->u.field)));
                                cnsttree(inttype, n + fieldright(tp->u.field)));
                      } else if (fieldsize(tp->u.field) < 8*tp->u.field->type->size)
                      } else if (fieldsize(tp->u.field) < 8*tp->u.field->type->size)
                        q = bittree(BAND,
                        q = bittree(BAND,
                                shtree(RSH, q, cnsttree(inttype, (long)fieldright(tp->u.field))),
                                shtree(RSH, q, cnsttree(inttype, (long)fieldright(tp->u.field))),
                                cnsttree(unsignedtype, (unsigned long)fieldmask(tp->u.field)));
                                cnsttree(unsignedtype, (unsigned long)fieldmask(tp->u.field)));
                      assert(tlab == 0 && flab == 0);
                      assert(tlab == 0 && flab == 0);
                      p = listnodes(q, 0, 0); } break;
                      p = listnodes(q, 0, 0); } break;
        case ADDRG:
        case ADDRG:
        case ADDRF: { assert(tlab == 0 && flab == 0);
        case ADDRF: { assert(tlab == 0 && flab == 0);
                      p = node(tp->op + sizeop(voidptype->size), NULL, NULL, tp->u.sym);
                      p = node(tp->op + sizeop(voidptype->size), NULL, NULL, tp->u.sym);
 } break;
 } break;
        case ADDRL: { assert(tlab == 0 && flab == 0);
        case ADDRL: { assert(tlab == 0 && flab == 0);
                      if (tp->u.sym->generated)
                      if (tp->u.sym->generated)
                        addlocal(tp->u.sym);
                        addlocal(tp->u.sym);
                      p = node(tp->op + sizeop(voidptype->size), NULL, NULL, tp->u.sym); } break;
                      p = node(tp->op + sizeop(voidptype->size), NULL, NULL, tp->u.sym); } break;
        default:assert(0);
        default:assert(0);
        }
        }
        tp->node = p;
        tp->node = p;
        return p;
        return p;
}
}
static void list(Node p) {
static void list(Node p) {
        if (p && p->link == NULL) {
        if (p && p->link == NULL) {
                if (forest) {
                if (forest) {
                        p->link = forest->link;
                        p->link = forest->link;
                        forest->link = p;
                        forest->link = p;
                } else
                } else
                        p->link = p;
                        p->link = p;
                forest = p;
                forest = p;
        }
        }
}
}
static void labelnode(int lab) {
static void labelnode(int lab) {
        assert(lab);
        assert(lab);
        if (forest && forest->op == LABEL+V)
        if (forest && forest->op == LABEL+V)
                equatelab(findlabel(lab), forest->syms[0]);
                equatelab(findlabel(lab), forest->syms[0]);
        else
        else
                list(newnode(LABEL+V, NULL, NULL, findlabel(lab)));
                list(newnode(LABEL+V, NULL, NULL, findlabel(lab)));
        reset();
        reset();
}
}
static void unlist(void) {
static void unlist(void) {
        Node p;
        Node p;
 
 
        assert(forest);
        assert(forest);
        assert(forest != forest->link);
        assert(forest != forest->link);
        p = forest->link;
        p = forest->link;
        while (p->link != forest)
        while (p->link != forest)
                p = p->link;
                p = p->link;
        p->link = forest->link;
        p->link = forest->link;
        forest = p;
        forest = p;
}
}
Tree cvtconst(Tree p) {
Tree cvtconst(Tree p) {
        Symbol q = constant(p->type, p->u.v);
        Symbol q = constant(p->type, p->u.v);
        Tree e;
        Tree e;
 
 
        if (q->u.c.loc == NULL)
        if (q->u.c.loc == NULL)
                q->u.c.loc = genident(STATIC, p->type, GLOBAL);
                q->u.c.loc = genident(STATIC, p->type, GLOBAL);
        if (isarray(p->type)) {
        if (isarray(p->type)) {
                e = simplify(ADDRG, atop(p->type), NULL, NULL);
                e = simplify(ADDRG, atop(p->type), NULL, NULL);
                e->u.sym = q->u.c.loc;
                e->u.sym = q->u.c.loc;
        } else
        } else
                e = idtree(q->u.c.loc);
                e = idtree(q->u.c.loc);
        return e;
        return e;
}
}
void gencode(Symbol caller[], Symbol callee[]) {
void gencode(Symbol caller[], Symbol callee[]) {
        Code cp;
        Code cp;
        Coordinate save;
        Coordinate save;
 
 
        if (prunetemps == -1)
        if (prunetemps == -1)
                prunetemps = !IR->wants_dag;
                prunetemps = !IR->wants_dag;
        save = src;
        save = src;
        if (assignargs) {
        if (assignargs) {
                int i;
                int i;
                Symbol p, q;
                Symbol p, q;
                cp = codehead.next->next;
                cp = codehead.next->next;
                codelist = codehead.next;
                codelist = codehead.next;
                for (i = 0; (p = callee[i]) != NULL
                for (i = 0; (p = callee[i]) != NULL
                         && (q = caller[i]) != NULL; i++)
                         && (q = caller[i]) != NULL; i++)
                        if (p->sclass != q->sclass || p->type != q->type)
                        if (p->sclass != q->sclass || p->type != q->type)
                                walk(asgn(p, idtree(q)), 0, 0);
                                walk(asgn(p, idtree(q)), 0, 0);
                codelist->next = cp;
                codelist->next = cp;
                cp->prev = codelist;
                cp->prev = codelist;
        }
        }
        if (glevel && IR->stabsym) {
        if (glevel && IR->stabsym) {
                int i;
                int i;
                Symbol p, q;
                Symbol p, q;
                for (i = 0; (p = callee[i]) != NULL
                for (i = 0; (p = callee[i]) != NULL
                         && (q = caller[i]) != NULL; i++) {
                         && (q = caller[i]) != NULL; i++) {
                        (*IR->stabsym)(p);
                        (*IR->stabsym)(p);
                        if (p->sclass != q->sclass || p->type != q->type)
                        if (p->sclass != q->sclass || p->type != q->type)
                                (*IR->stabsym)(q);
                                (*IR->stabsym)(q);
                }
                }
                swtoseg(CODE);
                swtoseg(CODE);
        }
        }
        cp = codehead.next;
        cp = codehead.next;
        for ( ; errcnt <= 0 && cp; cp = cp->next)
        for ( ; errcnt <= 0 && cp; cp = cp->next)
                switch (cp->kind) {
                switch (cp->kind) {
                case Address:  assert(IR->address);
                case Address:  assert(IR->address);
                               (*IR->address)(cp->u.addr.sym, cp->u.addr.base,
                               (*IR->address)(cp->u.addr.sym, cp->u.addr.base,
                                cp->u.addr.offset); break;
                                cp->u.addr.offset); break;
                case Blockbeg: {
                case Blockbeg: {
                                Symbol *p = cp->u.block.locals;
                                Symbol *p = cp->u.block.locals;
                                (*IR->blockbeg)(&cp->u.block.x);
                                (*IR->blockbeg)(&cp->u.block.x);
                                for ( ; *p; p++)
                                for ( ; *p; p++)
                                        if ((*p)->ref != 0.0)
                                        if ((*p)->ref != 0.0)
                                                (*IR->local)(*p);
                                                (*IR->local)(*p);
                                        else if (glevel) (*IR->local)(*p);
                                        else if (glevel) (*IR->local)(*p);
                               }
                               }
 break;
 break;
                case Blockend: (*IR->blockend)(&cp->u.begin->u.block.x); break;
                case Blockend: (*IR->blockend)(&cp->u.begin->u.block.x); break;
                case Defpoint: src = cp->u.point.src; break;
                case Defpoint: src = cp->u.point.src; break;
                case Gen: case Jump:
                case Gen: case Jump:
                case Label:    if (prunetemps)
                case Label:    if (prunetemps)
                                cp->u.forest = prune(cp->u.forest);
                                cp->u.forest = prune(cp->u.forest);
                               fixup(cp->u.forest);
                               fixup(cp->u.forest);
                               cp->u.forest = (*IR->gen)(cp->u.forest); break;
                               cp->u.forest = (*IR->gen)(cp->u.forest); break;
                case Local:    (*IR->local)(cp->u.var); break;
                case Local:    (*IR->local)(cp->u.var); break;
                case Switch:   break;
                case Switch:   break;
                default: assert(0);
                default: assert(0);
                }
                }
        src = save;
        src = save;
}
}
static void fixup(Node p) {
static void fixup(Node p) {
        for ( ; p; p = p->link)
        for ( ; p; p = p->link)
                switch (generic(p->op)) {
                switch (generic(p->op)) {
                case JUMP:
                case JUMP:
                        if (specific(p->kids[0]->op) == ADDRG+P)
                        if (specific(p->kids[0]->op) == ADDRG+P)
                                p->kids[0]->syms[0] =
                                p->kids[0]->syms[0] =
                                        equated(p->kids[0]->syms[0]);
                                        equated(p->kids[0]->syms[0]);
                        break;
                        break;
                case LABEL: assert(p->syms[0] == equated(p->syms[0])); break;
                case LABEL: assert(p->syms[0] == equated(p->syms[0])); break;
                case EQ: case GE: case GT: case LE: case LT: case NE:
                case EQ: case GE: case GT: case LE: case LT: case NE:
                        assert(p->syms[0]);
                        assert(p->syms[0]);
                        p->syms[0] = equated(p->syms[0]);
                        p->syms[0] = equated(p->syms[0]);
                }
                }
}
}
static Symbol equated(Symbol p) {
static Symbol equated(Symbol p) {
        { Symbol q; for (q = p->u.l.equatedto; q; q = q->u.l.equatedto) assert(p != q); }
        { Symbol q; for (q = p->u.l.equatedto; q; q = q->u.l.equatedto) assert(p != q); }
        while (p->u.l.equatedto)
        while (p->u.l.equatedto)
                p = p->u.l.equatedto;
                p = p->u.l.equatedto;
        return p;
        return p;
}
}
void emitcode(void) {
void emitcode(void) {
        Code cp;
        Code cp;
        Coordinate save;
        Coordinate save;
 
 
        save = src;
        save = src;
        cp = codehead.next;
        cp = codehead.next;
        for ( ; errcnt <= 0 && cp; cp = cp->next)
        for ( ; errcnt <= 0 && cp; cp = cp->next)
                switch (cp->kind) {
                switch (cp->kind) {
                case Address: break;
                case Address: break;
                case Blockbeg: if (glevel && IR->stabblock) {
                case Blockbeg: if (glevel && IR->stabblock) {
                                (*IR->stabblock)('{',  cp->u.block.level - LOCAL, cp->u.block.locals);
                                (*IR->stabblock)('{',  cp->u.block.level - LOCAL, cp->u.block.locals);
                                swtoseg(CODE);
                                swtoseg(CODE);
                               }
                               }
 break;
 break;
                case Blockend: if (glevel && IR->stabblock) {
                case Blockend: if (glevel && IR->stabblock) {
                                Code bp = cp->u.begin;
                                Code bp = cp->u.begin;
                                foreach(bp->u.block.identifiers, bp->u.block.level, typestab, NULL);
                                foreach(bp->u.block.identifiers, bp->u.block.level, typestab, NULL);
                                foreach(bp->u.block.types,       bp->u.block.level, typestab, NULL);
                                foreach(bp->u.block.types,       bp->u.block.level, typestab, NULL);
                                (*IR->stabblock)('}', bp->u.block.level - LOCAL, bp->u.block.locals);
                                (*IR->stabblock)('}', bp->u.block.level - LOCAL, bp->u.block.locals);
                                swtoseg(CODE);
                                swtoseg(CODE);
                               }
                               }
 break;
 break;
                case Defpoint: src = cp->u.point.src;
                case Defpoint: src = cp->u.point.src;
                               if (glevel > 0 && IR->stabline) {
                               if (glevel > 0 && IR->stabline) {
                                (*IR->stabline)(&cp->u.point.src); swtoseg(CODE); } break;
                                (*IR->stabline)(&cp->u.point.src); swtoseg(CODE); } break;
                case Gen: case Jump:
                case Gen: case Jump:
                case Label:    if (cp->u.forest)
                case Label:    if (cp->u.forest)
                                (*IR->emit)(cp->u.forest); break;
                                (*IR->emit)(cp->u.forest); break;
                case Local:    if (glevel && IR->stabsym) {
                case Local:    if (glevel && IR->stabsym) {
                                (*IR->stabsym)(cp->u.var);
                                (*IR->stabsym)(cp->u.var);
                                swtoseg(CODE);
                                swtoseg(CODE);
                               } break;
                               } break;
                case Switch:   {        int i;
                case Switch:   {        int i;
                                defglobal(cp->u.swtch.table, LIT);
                                defglobal(cp->u.swtch.table, LIT);
                                (*IR->defaddress)(equated(cp->u.swtch.labels[0]));
                                (*IR->defaddress)(equated(cp->u.swtch.labels[0]));
                                for (i = 1; i < cp->u.swtch.size; i++) {
                                for (i = 1; i < cp->u.swtch.size; i++) {
                                        long k = cp->u.swtch.values[i-1];
                                        long k = cp->u.swtch.values[i-1];
                                        while (++k < cp->u.swtch.values[i])
                                        while (++k < cp->u.swtch.values[i])
                                                assert(k < LONG_MAX),
                                                assert(k < LONG_MAX),
                                                (*IR->defaddress)(equated(cp->u.swtch.deflab));
                                                (*IR->defaddress)(equated(cp->u.swtch.deflab));
                                        (*IR->defaddress)(equated(cp->u.swtch.labels[i]));
                                        (*IR->defaddress)(equated(cp->u.swtch.labels[i]));
                                }
                                }
                                swtoseg(CODE);
                                swtoseg(CODE);
                               } break;
                               } break;
                default: assert(0);
                default: assert(0);
                }
                }
        src = save;
        src = save;
}
}
 
 
static Node undag(Node forest) {
static Node undag(Node forest) {
        Node p;
        Node p;
 
 
        tail = &forest;
        tail = &forest;
        for (p = forest; p; p = p->link)
        for (p = forest; p; p = p->link)
                if (generic(p->op) == INDIR) {
                if (generic(p->op) == INDIR) {
                        assert(p->count >= 1);
                        assert(p->count >= 1);
                        visit(p, 1);
                        visit(p, 1);
                        if (p->syms[2]) {
                        if (p->syms[2]) {
                                assert(p->syms[2]->u.t.cse);
                                assert(p->syms[2]->u.t.cse);
                                p->syms[2]->u.t.cse = NULL;
                                p->syms[2]->u.t.cse = NULL;
                                addlocal(p->syms[2]);
                                addlocal(p->syms[2]);
                        }
                        }
                } else if (iscall(p->op) && p->count >= 1)
                } else if (iscall(p->op) && p->count >= 1)
                        visit(p, 1);
                        visit(p, 1);
                else {
                else {
                        assert(p->count == 0),
                        assert(p->count == 0),
                        visit(p, 1);
                        visit(p, 1);
                        *tail = p;
                        *tail = p;
                        tail = &p->link;
                        tail = &p->link;
                }
                }
        *tail = NULL;
        *tail = NULL;
        return forest;
        return forest;
}
}
static Node replace(Node p) {
static Node replace(Node p) {
        if (p && (  generic(p->op) == INDIR
        if (p && (  generic(p->op) == INDIR
                 && generic(p->kids[0]->op) == ADDRL
                 && generic(p->kids[0]->op) == ADDRL
                 && p->kids[0]->syms[0]->temporary
                 && p->kids[0]->syms[0]->temporary
                 && p->kids[0]->syms[0]->u.t.replace)) {
                 && p->kids[0]->syms[0]->u.t.replace)) {
                p = p->kids[0]->syms[0]->u.t.cse;
                p = p->kids[0]->syms[0]->u.t.cse;
                if (generic(p->op) == INDIR && isaddrop(p->kids[0]->op))
                if (generic(p->op) == INDIR && isaddrop(p->kids[0]->op))
                        p = newnode(p->op, newnode(p->kids[0]->op, NULL, NULL,
                        p = newnode(p->op, newnode(p->kids[0]->op, NULL, NULL,
                                p->kids[0]->syms[0]), NULL, NULL);
                                p->kids[0]->syms[0]), NULL, NULL);
                else if (generic(p->op) == ADDRG)
                else if (generic(p->op) == ADDRG)
                        p = newnode(p->op, NULL, NULL, p->syms[0]);
                        p = newnode(p->op, NULL, NULL, p->syms[0]);
                else
                else
                        assert(0);
                        assert(0);
                p->count = 1;
                p->count = 1;
        } else if (p) {
        } else if (p) {
                p->kids[0] = replace(p->kids[0]);
                p->kids[0] = replace(p->kids[0]);
                p->kids[1] = replace(p->kids[1]);
                p->kids[1] = replace(p->kids[1]);
        }
        }
        return p;
        return p;
}
}
static Node prune(Node forest) {
static Node prune(Node forest) {
        Node p, *tail = &forest;
        Node p, *tail = &forest;
        int count = 0;
        int count = 0;
 
 
        for (p = forest; p; p = p->link) {
        for (p = forest; p; p = p->link) {
                if (count > 0) {
                if (count > 0) {
                        p->kids[0] = replace(p->kids[0]);
                        p->kids[0] = replace(p->kids[0]);
                        p->kids[1] = replace(p->kids[1]);
                        p->kids[1] = replace(p->kids[1]);
                }
                }
                if ((  generic(p->op) == ASGN
                if ((  generic(p->op) == ASGN
                    && generic(p->kids[0]->op) == ADDRL
                    && generic(p->kids[0]->op) == ADDRL
                    && p->kids[0]->syms[0]->temporary
                    && p->kids[0]->syms[0]->temporary
                    && p->kids[0]->syms[0]->u.t.cse == p->kids[1])) {
                    && p->kids[0]->syms[0]->u.t.cse == p->kids[1])) {
                        Symbol tmp = p->kids[0]->syms[0];
                        Symbol tmp = p->kids[0]->syms[0];
                        if (!tmp->defined)
                        if (!tmp->defined)
                                (*IR->local)(tmp);
                                (*IR->local)(tmp);
                        tmp->defined = 1;
                        tmp->defined = 1;
                        if ((  generic(p->kids[1]->op) == INDIR
                        if ((  generic(p->kids[1]->op) == INDIR
                            && isaddrop(p->kids[1]->kids[0]->op)
                            && isaddrop(p->kids[1]->kids[0]->op)
                            && p->kids[1]->kids[0]->syms[0]->sclass == REGISTER)
                            && p->kids[1]->kids[0]->syms[0]->sclass == REGISTER)
                        || ((  generic(p->kids[1]->op) == INDIR
                        || ((  generic(p->kids[1]->op) == INDIR
                            && isaddrop(p->kids[1]->kids[0]->op)) && tmp->sclass == AUTO)
                            && isaddrop(p->kids[1]->kids[0]->op)) && tmp->sclass == AUTO)
                        || (generic(p->kids[1]->op) == ADDRG && tmp->sclass == AUTO)) {
                        || (generic(p->kids[1]->op) == ADDRG && tmp->sclass == AUTO)) {
                                tmp->u.t.replace = 1;
                                tmp->u.t.replace = 1;
                                count++;
                                count++;
                                continue;       /* and omit the assignment */
                                continue;       /* and omit the assignment */
                        }
                        }
                }
                }
                /* keep the assignment and other roots */
                /* keep the assignment and other roots */
                *tail = p;
                *tail = p;
                tail = &(*tail)->link;
                tail = &(*tail)->link;
        }
        }
        assert(*tail == NULL);
        assert(*tail == NULL);
        return forest;
        return forest;
}
}
static Node visit(Node p, int listed) {
static Node visit(Node p, int listed) {
        if (p)
        if (p)
                if (p->syms[2])
                if (p->syms[2])
                        p = tmpnode(p);
                        p = tmpnode(p);
                else if (p->count <= 1 && !iscall(p->op)
                else if (p->count <= 1 && !iscall(p->op)
                ||       p->count == 0 &&  iscall(p->op)) {
                ||       p->count == 0 &&  iscall(p->op)) {
                        p->kids[0] = visit(p->kids[0], 0);
                        p->kids[0] = visit(p->kids[0], 0);
                        p->kids[1] = visit(p->kids[1], 0);
                        p->kids[1] = visit(p->kids[1], 0);
                }
                }
 
 
                else if (specific(p->op) == ADDRL+P || specific(p->op) == ADDRF+P) {
                else if (specific(p->op) == ADDRL+P || specific(p->op) == ADDRF+P) {
                        assert(!listed);
                        assert(!listed);
                        p = newnode(p->op, NULL, NULL, p->syms[0]);
                        p = newnode(p->op, NULL, NULL, p->syms[0]);
                        p->count = 1;
                        p->count = 1;
                }
                }
                else if (p->op == INDIR+B) {
                else if (p->op == INDIR+B) {
                        p = newnode(p->op, p->kids[0], NULL, NULL);
                        p = newnode(p->op, p->kids[0], NULL, NULL);
                        p->count = 1;
                        p->count = 1;
                        p->kids[0] = visit(p->kids[0], 0);
                        p->kids[0] = visit(p->kids[0], 0);
                        p->kids[1] = visit(p->kids[1], 0);
                        p->kids[1] = visit(p->kids[1], 0);
                }
                }
                else {
                else {
                        p->kids[0] = visit(p->kids[0], 0);
                        p->kids[0] = visit(p->kids[0], 0);
                        p->kids[1] = visit(p->kids[1], 0);
                        p->kids[1] = visit(p->kids[1], 0);
                        p->syms[2] = temporary(REGISTER, btot(p->op, opsize(p->op)));
                        p->syms[2] = temporary(REGISTER, btot(p->op, opsize(p->op)));
                        assert(!p->syms[2]->defined);
                        assert(!p->syms[2]->defined);
                        p->syms[2]->ref = 1;
                        p->syms[2]->ref = 1;
                        p->syms[2]->u.t.cse = p;
                        p->syms[2]->u.t.cse = p;
 
 
                        *tail = asgnnode(p->syms[2], p);
                        *tail = asgnnode(p->syms[2], p);
                        tail = &(*tail)->link;
                        tail = &(*tail)->link;
                        if (!listed)
                        if (!listed)
                                p = tmpnode(p);
                                p = tmpnode(p);
                };
                };
        return p;
        return p;
}
}
static Node tmpnode(Node p) {
static Node tmpnode(Node p) {
        Symbol tmp = p->syms[2];
        Symbol tmp = p->syms[2];
 
 
        assert(tmp);
        assert(tmp);
        if (--p->count == 0)
        if (--p->count == 0)
                p->syms[2] = NULL;
                p->syms[2] = NULL;
        p = newnode(INDIR + ttob(tmp->type),
        p = newnode(INDIR + ttob(tmp->type),
                newnode(ADDRL + ttob(voidptype), NULL, NULL, tmp), NULL, NULL);
                newnode(ADDRL + ttob(voidptype), NULL, NULL, tmp), NULL, NULL);
        p->count = 1;
        p->count = 1;
        return p;
        return p;
}
}
static Node asgnnode(Symbol tmp, Node p) {
static Node asgnnode(Symbol tmp, Node p) {
        p = newnode(ASGN + ttob(tmp->type),
        p = newnode(ASGN + ttob(tmp->type),
                newnode(ADDRL + ttob(voidptype), NULL, NULL, tmp), p, NULL);
                newnode(ADDRL + ttob(voidptype), NULL, NULL, tmp), p, NULL);
        p->syms[0] = intconst(tmp->type->size);
        p->syms[0] = intconst(tmp->type->size);
        p->syms[1] = intconst(tmp->type->align);
        p->syms[1] = intconst(tmp->type->align);
        return p;
        return p;
}
}
/* printdag - print dag p on fd, or the node list if p == 0 */
/* printdag - print dag p on fd, or the node list if p == 0 */
void printdag(Node p, int fd) {
void printdag(Node p, int fd) {
        FILE *f = fd == 1 ? stdout : stderr;
        FILE *f = fd == 1 ? stdout : stderr;
 
 
        printed(0);
        printed(0);
        if (p == 0) {
        if (p == 0) {
                if ((p = forest) != NULL)
                if ((p = forest) != NULL)
                        do {
                        do {
                                p = p->link;
                                p = p->link;
                                printdag1(p, fd, 0);
                                printdag1(p, fd, 0);
                        } while (p != forest);
                        } while (p != forest);
        } else if (*printed(nodeid((Tree)p)))
        } else if (*printed(nodeid((Tree)p)))
                fprint(f, "node'%d printed above\n", nodeid((Tree)p));
                fprint(f, "node'%d printed above\n", nodeid((Tree)p));
        else
        else
                printdag1(p, fd, 0);
                printdag1(p, fd, 0);
}
}
 
 
/* printdag1 - recursively print dag p */
/* printdag1 - recursively print dag p */
static void printdag1(Node p, int fd, int lev) {
static void printdag1(Node p, int fd, int lev) {
        int id, i;
        int id, i;
 
 
        if (p == 0 || *printed(id = nodeid((Tree)p)))
        if (p == 0 || *printed(id = nodeid((Tree)p)))
                return;
                return;
        *printed(id) = 1;
        *printed(id) = 1;
        for (i = 0; i < NELEMS(p->kids); i++)
        for (i = 0; i < NELEMS(p->kids); i++)
                printdag1(p->kids[i], fd, lev + 1);
                printdag1(p->kids[i], fd, lev + 1);
        printnode(p, fd, lev);
        printnode(p, fd, lev);
}
}
 
 
/* printnode - print fields of dag p */
/* printnode - print fields of dag p */
static void printnode(Node p, int fd, int lev) {
static void printnode(Node p, int fd, int lev) {
        if (p) {
        if (p) {
                FILE *f = fd == 1 ? stdout : stderr;
                FILE *f = fd == 1 ? stdout : stderr;
                int i, id = nodeid((Tree)p);
                int i, id = nodeid((Tree)p);
                fprint(f, "%c%d%s", lev == 0 ? '\'' : '#', id,
                fprint(f, "%c%d%s", lev == 0 ? '\'' : '#', id,
                        &"   "[id < 10 ? 0 : id < 100 ? 1 : 2]);
                        &"   "[id < 10 ? 0 : id < 100 ? 1 : 2]);
                fprint(f, "%s count=%d", opname(p->op), p->count);
                fprint(f, "%s count=%d", opname(p->op), p->count);
                for (i = 0; i < NELEMS(p->kids) && p->kids[i]; i++)
                for (i = 0; i < NELEMS(p->kids) && p->kids[i]; i++)
                        fprint(f, " #%d", nodeid((Tree)p->kids[i]));
                        fprint(f, " #%d", nodeid((Tree)p->kids[i]));
                if (generic(p->op) == CALL && p->syms[0] && p->syms[0]->type)
                if (generic(p->op) == CALL && p->syms[0] && p->syms[0]->type)
                        fprint(f, " {%t}", p->syms[0]->type);
                        fprint(f, " {%t}", p->syms[0]->type);
                else
                else
                        for (i = 0; i < NELEMS(p->syms) && p->syms[i]; i++)
                        for (i = 0; i < NELEMS(p->syms) && p->syms[i]; i++)
                                if (p->syms[i]->name)
                                if (p->syms[i]->name)
                                        fprint(f, " %s", p->syms[i]->name);
                                        fprint(f, " %s", p->syms[i]->name);
                                else
                                else
                                        fprint(f, " %p", p->syms[i]);
                                        fprint(f, " %p", p->syms[i]);
                fprint(f, "\n");
                fprint(f, "\n");
        }
        }
}
}
 
 
/* typestab - emit stab entries for p */
/* typestab - emit stab entries for p */
static void typestab(Symbol p, void *cl) {
static void typestab(Symbol p, void *cl) {
        if (!isfunc(p->type) && (p->sclass == EXTERN || p->sclass == STATIC) && IR->stabsym)
        if (!isfunc(p->type) && (p->sclass == EXTERN || p->sclass == STATIC) && IR->stabsym)
                (*IR->stabsym)(p);
                (*IR->stabsym)(p);
        else if ((p->sclass == TYPEDEF || p->sclass == 0) && IR->stabtype)
        else if ((p->sclass == TYPEDEF || p->sclass == 0) && IR->stabtype)
                (*IR->stabtype)(p);
                (*IR->stabtype)(p);
}
}
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.