#include "c.h"
Include dependency graph for dag.c:

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) |
| dag * | dagnode (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 |
| dag * | buckets [16] |
| int | depth = 0 |
| Tree | firstarg |
| Node | forest |
| int | nodecount |
| int | prunetemps = -1 |
| Node * | tail |
|
|
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 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:

|
|
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:

|
||||||||||||||||||||
|
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 }
|
|
|
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:

|
|
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 }
|
|
|
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:

|
||||||||||||
|
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:

|
|
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 }
|
|
|
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:

|
|
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 }
|
|
||||||||||||||||
|
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-> |