Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

dag.c File Reference

#include "c.h"

Include dependency graph for dag.c:

Include dependency graph

Go to the source code of this file.

Data Structures

struct  dag

Defines

#define iscall(op)

Functions

Node asgnnode (Symbol, Node)
Tree cvtconst (Tree p)
dagdagnode (int, Node, Node, Symbol)
void emitcode (void)
Symbol equated (Symbol)
void fixup (Node)
void gencode (Symbol caller[], Symbol callee[])
void kill (Symbol)
void labelnode (int)
void list (Node)
Node listnodes (Tree tp, int tlab, int flab)
Node newnode (int op, Node l, Node r, Symbol sym)
Node node (int, Node, Node, Symbol)
void printdag (Node p, int fd)
void printdag1 (Node, int, int)
void printnode (Node, int, int)
Node prune (Node)
Node replace (Node)
void reset (void)
Node tmpnode (Node)
void typestab (Symbol, void *)
Node undag (Node)
void unlist (void)
Node visit (Node, int)
void walk (Tree tp, int tlab, int flab)

Variables

int assignargs = 1
dagbuckets [16]
int depth = 0
Tree firstarg
Node forest
int nodecount
int prunetemps = -1
Nodetail


Define Documentation

#define iscall op   ) 
 

Value:

(generic(op) == CALL \
    || IR->mulops_calls \
    && (generic(op)==DIV||generic(op)==MOD||generic(op)==MUL) \
    && ( optype(op)==U  || optype(op)==I))

Definition at line 4 of file dag.c.

Referenced by undag(), and visit().


Function Documentation

Node asgnnode Symbol  ,
Node 
[static]
 

Definition at line 670 of file dag.c.

References ADDRL, type::align, ASGN, intconst(), newnode(), Node, NULL, p, type::size, Symbol, node::syms, ttob(), symbol::type, and voidptype.

Referenced by visit().

00670                                          {
00671     p = newnode(ASGN + ttob(tmp->type),
00672         newnode(ADDRL + ttob(voidptype), NULL, NULL, tmp), p, NULL);
00673     p->syms[0] = intconst(tmp->type->size);
00674     p->syms[1] = intconst(tmp->type->align);
00675     return p;
00676 }

Here is the call graph for this function:

Tree cvtconst Tree  p  ) 
 

Definition at line 405 of file dag.c.

References ADDRG, atop(), symbol::c, constant(), e, genident(), GLOBAL, idtree(), isarray, symbol::loc, NULL, p, q, simplify(), tree::sym, Symbol, Tree, tree::type, symbol::u, tree::u, and tree::v.

Referenced by genconst(), and listnodes().

00405                       {
00406     Symbol q = constant(p->type, p->u.v);
00407     Tree e;
00408 
00409     if (q->u.c.loc == NULL)
00410         q->u.c.loc = genident(STATIC, p->type, GLOBAL);
00411     if (isarray(p->type)) {
00412         e = simplify(ADDRG, atop(p->type), NULL, NULL);
00413         e->u.sym = q->u.c.loc;
00414     } else
00415         e = idtree(q->u.c.loc);
00416     return e;
00417 }

Here is the call graph for this function:

struct dag * dagnode int  ,
Node  ,
Node  ,
Symbol 
[static]
 

Definition at line 67 of file dag.c.

References node::count, FUNC, node::kids, l, NEW0, dag::node, Node, node::op, p, r, Symbol, and node::syms.

Referenced by newnode(), and node().

00067                                                                {
00068     struct dag *p;
00069 
00070     NEW0(p, FUNC);
00071     p->node.op = op;
00072     if ((p->node.kids[0] = l) != NULL)
00073         ++l->count;
00074     if ((p->node.kids[1] = r) != NULL)
00075         ++r->count;
00076     p->node.syms[0] = sym;
00077     return p;
00078 }

void emitcode void   ) 
 

Definition at line 495 of file dag.c.

References assert, code::begin, code::block, CODE, Code, codehead, Coordinate, cp, interface::defaddress, defglobal(), code::deflab, interface::emit, equated(), errcnt, foreach(), code::forest, glevel, i, code::identifiers, IR, k, code::kind, code::labels, code::level, LIT, code::locals, LONG_MAX, code::next, NULL, code::point, code::size, code::src, src, interface::stabblock, interface::stabline, interface::stabsym, code::swtch, swtoseg(), code::table, code::types, typestab(), code::u, code::values, and code::var.

Referenced by asdl_function().

00495                     {
00496     Code cp;
00497     Coordinate save;
00498 
00499     save = src;
00500     cp = codehead.next;
00501     for ( ; errcnt <= 0 && cp; cp = cp->next)
00502         switch (cp->kind) {
00503         case Address: break;
00504         case Blockbeg: if (glevel && IR->stabblock) {
00505                     (*IR->stabblock)('{',  cp->u.block.level - LOCAL, cp->u.block.locals);
00506                     swtoseg(CODE);
00507                    }
00508  break;
00509         case Blockend: if (glevel && IR->stabblock) {
00510                     Code bp = cp->u.begin;
00511                     foreach(bp->u.block.identifiers, bp->u.block.level, typestab, NULL);
00512                     foreach(bp->u.block.types,       bp->u.block.level, typestab, NULL);
00513                     (*IR->stabblock)('}', bp->u.block.level - LOCAL, bp->u.block.locals);
00514                     swtoseg(CODE);
00515                    }
00516  break;
00517         case Defpoint: src = cp->u.point.src;
00518                    if (glevel > 0 && IR->stabline) {
00519                     (*IR->stabline)(&cp->u.point.src); swtoseg(CODE); } break;
00520         case Gen: case Jump:
00521         case Label:    if (cp->u.forest)
00522                     (*IR->emit)(cp->u.forest); break;
00523         case Local:    if (glevel && IR->stabsym) {
00524                     (*IR->stabsym)(cp->u.var);
00525                     swtoseg(CODE);
00526                    } break;
00527         case Switch:   {    int i;
00528                     defglobal(cp->u.swtch.table, LIT);
00529                     (*IR->defaddress)(equated(cp->u.swtch.labels[0]));
00530                     for (i = 1; i < cp->u.swtch.size; i++) {
00531                         long k = cp->u.swtch.values[i-1];
00532                         while (++k < cp->u.swtch.values[i])
00533                             assert(k < LONG_MAX),
00534                             (*IR->defaddress)(equated(cp->u.swtch.deflab));
00535                         (*IR->defaddress)(equated(cp->u.swtch.labels[i]));
00536                     }
00537                     swtoseg(CODE);
00538                    } break;
00539         default: assert(0);
00540         }
00541     src = save;
00542 }

Here is the call graph for this function:

Symbol equated Symbol   )  [static]
 

Definition at line 489 of file dag.c.

References assert, symbol::equatedto, symbol::l, p, q, Symbol, and symbol::u.

Referenced by emitcode(), and fixup().

00489                                 {
00490     { Symbol q; for (q = p->u.l.equatedto; q; q = q->u.l.equatedto) assert(p != q); }
00491     while (p->u.l.equatedto)
00492         p = p->u.l.equatedto;
00493     return p;
00494 }

void fixup Node   )  [static]
 

Definition at line 475 of file dag.c.

References ADDRG, assert, EQ, equated(), GE, generic, GT, JUMP, node::kids, LABEL, LE, node::link, LT, NE, Node, node::op, p, specific, and node::syms.

Referenced by gencode().

00475                           {
00476     for ( ; p; p = p->link)
00477         switch (generic(p->op)) {
00478         case JUMP:
00479             if (specific(p->kids[0]->op) == ADDRG+P)
00480                 p->kids[0]->syms[0] =
00481                     equated(p->kids[0]->syms[0]);
00482             break;
00483         case LABEL: assert(p->syms[0] == equated(p->syms[0])); break;
00484         case EQ: case GE: case GT: case LE: case LT: case NE:
00485             assert(p->syms[0]);
00486             p->syms[0] = equated(p->syms[0]);
00487         }
00488 }

Here is the call graph for this function:

void gencode Symbol  caller[],
Symbol  callee[]
 

Definition at line 418 of file dag.c.

References code::addr, interface::address, asgn(), assert, code::base, code::begin, code::block, interface::blockbeg, interface::blockend, CODE, Code, codehead, codelist, Coordinate, cp, errcnt, fixup(), code::forest, interface::gen, glevel, i, idtree(), IR, code::kind, interface::local, code::locals, code::next, NULL, code::offset, p, code::point, code::prev, prune(), prunetemps, q, symbol::sclass, code::src, src, interface::stabsym, swtoseg(), code::sym, Symbol, type::type, symbol::type, code::u, code::var, walk(), interface::wants_dag, and code::x.

Referenced by asdl_function().

00418                                                {
00419     Code cp;
00420     Coordinate save;
00421 
00422     if (prunetemps == -1)
00423         prunetemps = !IR->wants_dag;
00424     save = src;
00425     if (assignargs) {
00426         int i;
00427         Symbol p, q;
00428         cp = codehead.next->next;
00429         codelist = codehead.next;
00430         for (i = 0; (p = callee[i]) != NULL
00431                  && (q = caller[i]) != NULL; i++)
00432             if (p->sclass != q->sclass || p->type != q->type)
00433                 walk(asgn(p, idtree(q)), 0, 0);
00434         codelist->next = cp;
00435         cp->prev = codelist;
00436     }
00437     if (glevel && IR->stabsym) {
00438         int i;
00439         Symbol p, q;
00440         for (i = 0; (p = callee[i]) != NULL
00441                  && (q = caller[i]) != NULL; i++) {
00442             (*IR->stabsym)(p);
00443             if (p->sclass != q->sclass || p->type != q->type)
00444                 (*IR->stabsym)(q);
00445         }
00446         swtoseg(CODE);
00447     }
00448     cp = codehead.next;
00449     for ( ; errcnt <= 0 && cp; cp = cp->next)
00450         switch (cp->kind) {
00451         case Address:  (*IR->address)(cp->u.addr.sym, cp->u.addr.base,
00452                     cp->u.addr.offset); break;
00453         case Blockbeg: {
00454                     Symbol *p = cp->u.block.locals;
00455                     (*IR->blockbeg)(&cp->u.block.x);
00456                     for ( ; *p; p++)
00457                         if ((*p)->ref != 0.0)
00458                             (*IR->local)(*p);
00459                         else if (glevel) (*IR->local)(*p);
00460                    }
00461  break;
00462         case Blockend: (*IR->blockend)(&cp->u.begin->u.block.x); break;
00463         case Defpoint: src = cp->u.point.src; break;
00464         case Gen: case Jump:
00465         case Label:    if (prunetemps)
00466                     cp->u.forest = prune(cp->u.forest);
00467                    fixup(cp->u.forest);
00468                    cp->u.forest = (*IR->gen)(cp->u.forest); break;
00469         case Local:    (*IR->local)(cp->u.var); break;
00470         case Switch:   break;
00471         default: assert(0);
00472         }
00473     src = save;
00474 }

Here is the call graph for this function:

void kill Symbol   )  [static]
 

Definition at line 82 of file dag.c.

References buckets, generic, dag::hlink, i, INDIR, isaddrop, NELEMS, q, and Symbol.

Referenced by listnodes().

00082                            {
00083     int i;
00084     struct dag **q;
00085 
00086     for (i = 0; i < NELEMS(buckets); i++)
00087         for (q = &buckets[i]; *q; )
00088             if (generic((*q)->node.op) == INDIR &&
00089                 (!isaddrop((*q)->node.kids[0]->op)
00090                  || (*q)->node.kids[0]->syms[0] == p)) {
00091                 *q = (*q)->hlink;
00092                 --nodecount;
00093             } else
00094                 q = &(*q)->hlink;
00095 }

void labelnode int   )  [static]
 

Definition at line 386 of file dag.c.

References assert, equatelab(), findlabel(), forest, LABEL, list(), newnode(), NULL, node::op, reset(), node::syms, and V.

Referenced by listnodes().

00386                                {
00387     assert(lab);
00388     if (forest && forest->op == LABEL+V)
00389         equatelab(findlabel(lab), forest->syms[0]);
00390     else
00391         list(newnode(LABEL+V, NULL, NULL, findlabel(lab)));
00392     reset();
00393 }

Here is the call graph for this function:

void list Node   )  [static]
 

Definition at line 376 of file dag.c.

References forest, node::link, Node, and p.

Referenced by labelnode(), listnodes(), and walk().

00376                          {
00377     if (p && p->link == NULL) {
00378         if (forest) {
00379             p->link = forest->link;
00380             forest->link = p;
00381         } else
00382             p->link = p;
00383         forest = p;
00384     }
00385 }

Node listnodes Tree  tp,
int  tlab,
int  flab
 

Definition at line 101 of file dag.c.

References ADD, addlocal(), symbol::addressed, ADDRF, ADDRG, ADDRL, type::align, AND, ARG, ASGN, assert, B, BAND, BCOM, bittree(), BOR, BXOR, CALL, cast(), cfunc, CNST, cnsttree(), symbol::computed, COND, constant(), CVF, CVI, CVP, cvtconst(), CVU, depth, DIV, EQ, equatelab(), errcnt, f, symbol::f, tree::field, Field, FIELD, fieldleft, fieldmask, fieldright, fieldsize, findlabel(), firstarg, forest, FUNC, GE, generic, genlabel(), GT, I, value::i, idtree(), INDIR, intconst(), inttype, IR, isaddrop, isfunc, isint, isptr, isstruct, isvolatile, JUMP, jump(), tree::kids, kill(), l, LABEL, labelnode(), LE, interface::left_to_right, list(), LSH, LT, lvalue(), mask, MOD, MUL, interface::mulops_calls, n, symbol::ncalls, NE, NEG, NEW0, newnode(), node(), tree::node, Node, NOT, NULL, node::op, tree::op, op, opkind, optype, OR, P, p, q, r, symbol::ref, reset(), RET, RIGHT, RSH, rvalue(), shtree(), type::size, sizeop, SUB, type::sym, tree::sym, node::syms, symbol::temporary, tree(), Tree, ttob(), field::type, symbol::type, type::type, Type, tree::type, value::u, U, symbol::u, type::u, tree::u, unlist(), unqual, unsignedtype, V, tree::v, voidptype, interface::wants_callb, and x.

Referenced by cmp(), definept(), statement(), and walk().

00101                                             {
00102     Node p = NULL, l, r;
00103     int op;
00104 
00105     assert(tlab || flab || tlab == 0 && flab == 0);
00106     if (tp == NULL)
00107         return NULL;
00108     if (tp->node)
00109         return tp->node;
00110     op = tp->op + sizeop(tp->type->size);
00111     switch (generic(tp->op)) {
00112     case AND:   { if (depth++ == 0) reset();
00113               if (flab) {
00114                 listnodes(tp->kids[0], 0, flab);
00115                 listnodes(tp->kids[1], 0, flab);
00116               } else {
00117                 listnodes(tp->kids[0], 0, flab = genlabel(1));
00118                 listnodes(tp->kids[1], tlab, 0);
00119                 labelnode(flab);
00120               }
00121               depth--; } break;
00122     case OR:    { if (depth++ == 0)
00123                 reset();
00124               if (tlab) {
00125                 listnodes(tp->kids[0], tlab, 0);
00126                 listnodes(tp->kids[1], tlab, 0);
00127               } else {
00128                 tlab = genlabel(1);
00129                 listnodes(tp->kids[0], tlab, 0);
00130                 listnodes(tp->kids[1], 0, flab);
00131                 labelnode(tlab);
00132               }
00133               depth--;
00134  } break;
00135     case NOT:   { return listnodes(tp->kids[0], flab, tlab); }
00136     case COND:  { Tree q = tp->kids[1];
00137               assert(tlab == 0 && flab == 0);
00138               if (tp->u.sym)
00139                 addlocal(tp->u.sym);
00140               flab = genlabel(2);
00141               listnodes(tp->kids[0], 0, flab);
00142               assert(q && q->op == RIGHT);
00143               reset();
00144               listnodes(q->kids[0], 0, 0);
00145               if (forest->op == LABEL+V) {
00146                 equatelab(forest->syms[0], findlabel(flab + 1));
00147                 unlist();
00148               }
00149               list(jump(flab + 1));
00150               labelnode(flab);
00151               listnodes(q->kids[1], 0, 0);
00152               if (forest->op == LABEL+V) {
00153                 equatelab(forest->syms[0], findlabel(flab + 1));
00154                 unlist();
00155               }
00156               labelnode(flab + 1);
00157 
00158               if (tp->u.sym)
00159                 p = listnodes(idtree(tp->u.sym), 0, 0); } break;
00160     case CNST:  { Type ty = unqual(tp->type);
00161               assert(ty->u.sym);
00162               if (tlab || flab) {
00163                 assert(ty == inttype);
00164                 if (tlab && tp->u.v.i != 0)
00165                     list(jump(tlab));
00166                 else if (flab && tp->u.v.i == 0)
00167                     list(jump(flab));
00168               }
00169               else if (ty->u.sym->addressed)
00170                 p = listnodes(cvtconst(tp), 0, 0);
00171               else
00172                 p = node(op, NULL, NULL, constant(ty, tp->u.v)); } break;
00173     case RIGHT: { if (   tp->kids[0] && tp->kids[1]
00174               &&  generic(tp->kids[1]->op) == ASGN
00175               && (generic(tp->kids[0]->op) == INDIR
00176               && tp->kids[0]->kids[0] == tp->kids[1]->kids[0]
00177               || (tp->kids[0]->op == FIELD
00178               &&  tp->kids[0] == tp->kids[1]->kids[0]))) {
00179                 assert(tlab == 0 && flab == 0);
00180             if (generic(tp->kids[0]->op) == INDIR) {
00181                 p = listnodes(tp->kids[0], 0, 0);
00182                 list(p);
00183                 listnodes(tp->kids[1], 0, 0);
00184             }
00185             else {
00186                 assert(generic(tp->kids[0]->kids[0]->op) == INDIR);
00187                 list(listnodes(tp->kids[0]->kids[0], 0, 0));
00188                 p = listnodes(tp->kids[0], 0, 0);
00189                 listnodes(tp->kids[1], 0, 0);
00190             }
00191               } else if (tp->kids[1]) {
00192                 listnodes(tp->kids[0], 0, 0);
00193                 p = listnodes(tp->kids[1], tlab, flab);
00194               } else
00195                 p = listnodes(tp->kids[0], tlab, flab); } break;
00196     case JUMP:  { assert(tlab == 0 && flab == 0);
00197               assert(tp->u.sym == 0);
00198               assert(tp->kids[0]);
00199               l = listnodes(tp->kids[0], 0, 0);
00200               list(newnode(JUMP+V, l, NULL, NULL));
00201               reset(); } break;
00202     case CALL:  { Tree save = firstarg;
00203               firstarg = NULL;
00204               assert(tlab == 0 && flab == 0);
00205               if (tp->op == CALL+B && !IR->wants_callb) {
00206                 Tree arg0 = tree(ARG+P, tp->kids[1]->type,
00207                 tp->kids[1], NULL);
00208             if (IR->left_to_right)
00209                 firstarg = arg0;
00210             l = listnodes(tp->kids[0], 0, 0);
00211             if (!IR->left_to_right || firstarg) {
00212                 firstarg = NULL;
00213                 listnodes(arg0, 0, 0);
00214             }
00215                 p = newnode(CALL+V, l, NULL, NULL);
00216               } else {
00217                 l = listnodes(tp->kids[0], 0, 0);
00218                 r = listnodes(tp->kids[1], 0, 0);
00219                 p = newnode(tp->op == CALL+B ? tp->op : op, l, r, NULL);
00220               }
00221               NEW0(p->syms[0], FUNC);
00222               assert(isptr(tp->kids[0]->type));
00223               assert(isfunc(tp->kids[0]->type->type));
00224               p->syms[0]->type = tp->kids[0]->type->type;
00225               list(p);
00226               reset();
00227               cfunc->u.f.ncalls++;
00228               firstarg = save;
00229  } break;
00230     case ARG:   { assert(tlab == 0 && flab == 0);
00231               if (IR->left_to_right)
00232                 listnodes(tp->kids[1], 0, 0);
00233               if (firstarg) {
00234                 Tree arg = firstarg;
00235                 firstarg = NULL;
00236                 listnodes(arg, 0, 0);
00237               }
00238               l = listnodes(tp->kids[0], 0, 0);
00239               list(newnode(tp->op == ARG+B ? tp->op : op, l, NULL, NULL));
00240               forest->syms[0] = intconst(tp->type->size);
00241               forest->syms[1] = intconst(tp->type->align);
00242               if (!IR->left_to_right)
00243                 listnodes(tp->kids[1], 0, 0); } break;
00244     case EQ:  case NE: case GT: case GE: case LE:
00245     case LT:    { assert(tp->u.sym == 0);
00246               assert(errcnt || tlab || flab);
00247               l = listnodes(tp->kids[0], 0, 0);
00248               r = listnodes(tp->kids[1], 0, 0);
00249               assert(errcnt || opkind(l->op) == opkind(r->op));
00250               assert(errcnt || optype(op) == optype(l->op));
00251               if (tlab)
00252                 assert(flab == 0),
00253                 list(newnode(generic(tp->op) + opkind(l->op), l, r, findlabel(tlab)));
00254               else if (flab) {
00255                 switch (generic(tp->op)) {
00256                 case EQ: op = NE; break;
00257                 case NE: op = EQ; break;
00258                 case GT: op = LE; break;
00259                 case LT: op = GE; break;
00260                 case GE: op = LT; break;
00261                 case LE: op = GT; break;
00262                 default: assert(0);
00263                 }
00264                 list(newnode(op + opkind(l->op), l, r, findlabel(flab)));
00265               }
00266               if (forest && forest->syms[0])
00267                 forest->syms[0]->ref++; } break;
00268     case ASGN:  { assert(tlab == 0 && flab == 0);
00269               if (tp->kids[0]->op == FIELD) {
00270                 Tree  x = tp->kids[0]->kids[0];
00271             Field f = tp->kids[0]->u.field;
00272             assert(generic(x->op) == INDIR);
00273             reset();
00274             l = listnodes(lvalue(x), 0, 0);
00275             if (fieldsize(f) < 8*f->type->size) {
00276                 unsigned int fmask = fieldmask(f);
00277                 unsigned int  mask = fmask<<fieldright(f);
00278                 Tree q = tp->kids[1];
00279                 if (q->op == CNST+I && q->u.v.i == 0
00280                 ||  q->op == CNST+U && q->u.v.u == 0)
00281                     q = bittree(BAND, x, cnsttree(unsignedtype, (unsigned long)~mask));
00282                 else if (q->op == CNST+I && (q->u.v.i&fmask) == fmask
00283                 ||       q->op == CNST+U && (q->u.v.u&fmask) == fmask)
00284                     q = bittree(BOR, x, cnsttree(unsignedtype, (unsigned long)mask));
00285                 else {
00286                     listnodes(q, 0, 0);
00287                     q = bittree(BOR,
00288                         bittree(BAND, rvalue(lvalue(x)),
00289                             cnsttree(unsignedtype, (unsigned long)~mask)),
00290                         bittree(BAND, shtree(LSH, cast(q, unsignedtype),
00291                             cnsttree(unsignedtype, (unsigned long)fieldright(f))),
00292                             cnsttree(unsignedtype, (unsigned long)mask)));
00293                 }
00294                 r = listnodes(q, 0, 0);
00295                 op = ASGN + ttob(q->type);
00296             } else {
00297                 r = listnodes(tp->kids[1], 0, 0);
00298                 op = ASGN + ttob(tp->kids[1]->type);
00299             }
00300               } else {
00301                 l = listnodes(tp->kids[0], 0, 0);
00302                 r = listnodes(tp->kids[1], 0, 0);
00303               }
00304               list(newnode(tp->op == ASGN+B ? tp->op : op, l, r, NULL));
00305               forest->syms[0] = intconst(tp->kids[1]->type->size);
00306               forest->syms[1] = intconst(tp->kids[1]->type->align);
00307               if (isaddrop(tp->kids[0]->op)
00308               && !tp->kids[0]->u.sym->computed)
00309                 kill(tp->kids[0]->u.sym);
00310               else
00311                 reset();
00312               p = listnodes(tp->kids[1], 0, 0); } break;
00313     case BOR: case BAND: case BXOR:
00314     case ADD: case SUB:  case RSH:
00315     case LSH:   { assert(tlab == 0 && flab == 0);
00316               l = listnodes(tp->kids[0], 0, 0);
00317               r = listnodes(tp->kids[1], 0, 0);
00318               p = node(op, l, r, NULL); } break;
00319     case DIV: case MUL:
00320     case MOD:   { assert(tlab == 0 && flab == 0);
00321               l = listnodes(tp->kids[0], 0, 0);
00322               r = listnodes(tp->kids[1], 0, 0);
00323               p = node(op, l, r, NULL);
00324               if (IR->mulops_calls && isint(tp->type)) {
00325                 list(p);
00326                 cfunc->u.f.ncalls++;
00327               } } break;
00328     case RET:   { assert(tlab == 0 && flab == 0);
00329               l = listnodes(tp->kids[0], 0, 0);
00330               list(newnode(op, l, NULL, NULL)); } break;
00331     case CVF: case CVI: case CVP:
00332     case CVU:   { assert(tlab == 0 && flab == 0);
00333               assert(optype(tp->kids[0]->op) != optype(tp->op) || tp->kids[0]->type->size != tp->type->size);
00334               l = listnodes(tp->kids[0], 0, 0);
00335               p = node(op, l, NULL, intconst(tp->kids[0]->type->size));
00336  } break;
00337     case BCOM:
00338     case NEG:   { assert(tlab == 0 && flab == 0);
00339               l = listnodes(tp->kids[0], 0, 0);
00340               p = node(op, l, NULL, NULL); } break;
00341     case INDIR: { Type ty = tp->kids[0]->type;
00342               assert(tlab == 0 && flab == 0);
00343               l = listnodes(tp->kids[0], 0, 0);
00344               if (isptr(ty))
00345                 ty = unqual(ty)->type;
00346               if (isvolatile(ty)
00347               || (isstruct(ty) && unqual(ty)->u.sym->u.s.vfields))
00348                 p = newnode(tp->op == INDIR+B ? tp->op : op, l, NULL, NULL);
00349               else
00350                 p = node(tp->op == INDIR+B ? tp->op : op, l, NULL, NULL); } break;
00351     case FIELD: { Tree q = tp->kids[0];
00352               if (tp->type == inttype) {
00353                 long n = fieldleft(tp->u.field);
00354                 q = shtree(RSH,
00355                     shtree(LSH, q, cnsttree(inttype, n)),
00356                     cnsttree(inttype, n + fieldright(tp->u.field)));
00357               } else if (fieldsize(tp->