1/* Id: trees.c,v 1.306 2012/03/22 18:51:40 plunky Exp */ 2/* $NetBSD: trees.c,v 1.1.1.5 2012/03/26 14:26:54 plunky Exp $ */ 3/* 4 * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30/* 31 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. 32 * 33 * Redistribution and use in source and binary forms, with or without 34 * modification, are permitted provided that the following conditions 35 * are met: 36 * 37 * Redistributions of source code and documentation must retain the above 38 * copyright notice, this list of conditions and the following disclaimer. 39 * Redistributions in binary form must reproduce the above copyright 40 * notice, this list of conditionsand the following disclaimer in the 41 * documentation and/or other materials provided with the distribution. 42 * All advertising materials mentioning features or use of this software 43 * must display the following acknowledgement: 44 * This product includes software developed or owned by Caldera 45 * International, Inc. 46 * Neither the name of Caldera International, Inc. nor the names of other 47 * contributors may be used to endorse or promote products derived from 48 * this software without specific prior written permission. 49 * 50 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA 51 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR 52 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 53 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 54 * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE 55 * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58 * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT, 59 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 60 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 61 * POSSIBILITY OF SUCH DAMAGE. 62 */ 63/* 64 * Some of the changes from 32V include: 65 * - Understand "void" as type. 66 * - Handle enums as ints everywhere. 67 * - Convert some C-specific ops into branches. 68 */ 69 70# include "pass1.h" 71# include "pass2.h" 72 73# include <stdarg.h> 74# include <string.h> 75 76static void chkpun(NODE *p); 77static int opact(NODE *p); 78static int moditype(TWORD); 79static NODE *strargs(NODE *); 80static void rmcops(NODE *p); 81static NODE *tymatch(NODE *p); 82void putjops(NODE *, void *); 83static struct symtab *findmember(struct symtab *, char *); 84int inftn; /* currently between epilog/prolog */ 85 86static char *tnames[] = { 87 "undef", 88 "farg", 89 "char", 90 "unsigned char", 91 "short", 92 "unsigned short", 93 "int", 94 "unsigned int", 95 "long", 96 "unsigned long", 97 "long long", 98 "unsigned long long", 99 "float", 100 "double", 101 "long double", 102 "strty", 103 "unionty", 104 "enumty", 105 "moety", 106 "void", 107 "signed", /* pass1 */ 108 "bool", /* pass1 */ 109 "fimag", /* pass1 */ 110 "dimag", /* pass1 */ 111 "limag", /* pass1 */ 112 "fcomplex", /* pass1 */ 113 "dcomplex", /* pass1 */ 114 "lcomplex", /* pass1 */ 115 "enumty", /* pass1 */ 116 "?", "?" 117}; 118 119/* some special actions, used in finding the type of nodes */ 120# define NCVT 01 121# define PUN 02 122# define TYPL 04 123# define TYPR 010 124# define TYMATCH 040 125# define LVAL 0100 126# define CVTO 0200 127# define CVTL 0400 128# define CVTR 01000 129# define PTMATCH 02000 130# define OTHER 04000 131# define NCVTR 010000 132# define PROML 020000 /* promote left operand */ 133 134/* node conventions: 135 136 NAME: rval>0 is stab index for external 137 rval<0 is -inlabel number 138 lval is offset in bits 139 ICON: lval has the value 140 rval has the STAB index, or - label number, 141 if a name whose address is in the constant 142 rval = NONAME means no name 143 REG: rval is reg. identification cookie 144 145 */ 146 147extern int negrel[]; 148 149/* Have some defaults for most common targets */ 150#ifndef WORD_ADDRESSED 151#define offcon(o,t,d,ap) xbcon((o/SZCHAR), NULL, INTPTR) 152#define VBLOCK(p,b,t,d,a) buildtree(DIV, p, b) 153#define MBLOCK(p,b,t,d,a) buildtree(MUL, p, b) 154#else 155#define VBLOCK(p,b,t,d,a) block(PVCONV, p, b, t, d, a) 156#define MBLOCK(p,b,t,d,a) block(PMCONV, p, b, t, d, a) 157#endif 158 159NODE * 160buildtree(int o, NODE *l, NODE *r) 161{ 162 NODE *p, *q; 163 int actions; 164 int opty, n; 165 struct symtab *sp = NULL; /* XXX gcc */ 166 NODE *lr, *ll; 167 168#ifdef PCC_DEBUG 169 if (bdebug) { 170 printf("buildtree(%s, %p, %p)\n", copst(o), l, r); 171 if (l) fwalk(l, eprint, 0); 172 if (r) fwalk(r, eprint, 0); 173 } 174#endif 175 opty = coptype(o); 176 177 /* check for constants */ 178 179 if (o == ANDAND || o == OROR || o == NOT) { 180 if (l->n_op == FCON) { 181 p = bcon(!FLOAT_ISZERO(l->n_dcon)); 182 nfree(l); 183 l = p; 184 } 185 if (o != NOT && r->n_op == FCON) { 186 p = bcon(!FLOAT_ISZERO(r->n_dcon)); 187 nfree(r); 188 r = p; 189 } 190 } 191 192 if( opty == UTYPE && l->n_op == ICON ){ 193 194 switch( o ){ 195 196 case NOT: 197 case UMINUS: 198 case COMPL: 199 if( conval( l, o, l ) ) return(l); 200 break; 201 } 202 } else if (o == NOT && l->n_op == FCON) { 203 l = clocal(block(SCONV, l, NIL, INT, 0, 0)); 204 } else if( o == UMINUS && l->n_op == FCON ){ 205 l->n_dcon = FLOAT_NEG(l->n_dcon); 206 return(l); 207 208 } else if( o==QUEST && 209 (l->n_op==ICON || (l->n_op==NAME && ISARY(l->n_type)))) { 210 CONSZ c = l->n_lval; 211 if (l->n_op==NAME) 212 c = 1; /* will become constant later */ 213 nfree(l); 214 if (c) { 215 walkf(r->n_right, putjops, 0); 216 tfree(r->n_right); 217 l = r->n_left; 218 } else { 219 walkf(r->n_left, putjops, 0); 220 tfree(r->n_left); 221 l = r->n_right; 222 } 223 nfree(r); 224 return(l); 225 } else if( opty == BITYPE && l->n_op == ICON && r->n_op == ICON ){ 226 227 switch( o ){ 228 229 case PLUS: 230 case MINUS: 231 case MUL: 232 case DIV: 233 case MOD: 234 /* 235 * Do type propagation for simple types here. 236 * The constant value is correct anyway. 237 * Maybe this op shortcut should be removed? 238 */ 239 if (l->n_sp == NULL && r->n_sp == NULL && 240 l->n_type < BTMASK && r->n_type < BTMASK) { 241 if (l->n_type > r->n_type) 242 r->n_type = l->n_type; 243 else 244 l->n_type = r->n_type; 245 } 246 /* FALLTHROUGH */ 247 case ULT: 248 case UGT: 249 case ULE: 250 case UGE: 251 case LT: 252 case GT: 253 case LE: 254 case GE: 255 case EQ: 256 case NE: 257 case ANDAND: 258 case OROR: 259 case AND: 260 case OR: 261 case ER: 262 case LS: 263 case RS: 264 if (!ISPTR(l->n_type) && !ISPTR(r->n_type)) { 265 if( conval( l, o, r ) ) { 266 nfree(r); 267 return(l); 268 } 269 } 270 break; 271 } 272 } else if (opty == BITYPE && (l->n_op == FCON || l->n_op == ICON) && 273 (r->n_op == FCON || r->n_op == ICON) && (o == PLUS || o == MINUS || 274 o == MUL || o == DIV || (o >= EQ && o <= GT) )) { 275 TWORD t; 276#ifndef CC_DIV_0 277 if (o == DIV && 278 ((r->n_op == ICON && r->n_lval == 0) || 279 (r->n_op == FCON && r->n_dcon == 0.0))) 280 goto runtime; /* HW dependent */ 281#endif 282 if (l->n_op == ICON) 283 l->n_dcon = FLOAT_CAST(l->n_lval, l->n_type); 284 if (r->n_op == ICON) 285 r->n_dcon = FLOAT_CAST(r->n_lval, r->n_type); 286 switch(o){ 287 case PLUS: 288 case MINUS: 289 case MUL: 290 case DIV: 291 switch (o) { 292 case PLUS: 293 l->n_dcon = FLOAT_PLUS(l->n_dcon, r->n_dcon); 294 break; 295 case MINUS: 296 l->n_dcon = FLOAT_MINUS(l->n_dcon, r->n_dcon); 297 break; 298 case MUL: 299 l->n_dcon = FLOAT_MUL(l->n_dcon, r->n_dcon); 300 break; 301 case DIV: 302 l->n_dcon = FLOAT_DIV(l->n_dcon, r->n_dcon); 303 break; 304 } 305 t = (l->n_type > r->n_type ? l->n_type : r->n_type); 306 l->n_op = FCON; 307 l->n_type = t; 308 nfree(r); 309 return(l); 310 case EQ: 311 case NE: 312 case LE: 313 case LT: 314 case GE: 315 case GT: 316 switch (o) { 317 case EQ: 318 n = FLOAT_EQ(l->n_dcon, r->n_dcon); 319 break; 320 case NE: 321 n = FLOAT_NE(l->n_dcon, r->n_dcon); 322 break; 323 case LE: 324 n = FLOAT_LE(l->n_dcon, r->n_dcon); 325 break; 326 case LT: 327 n = FLOAT_LT(l->n_dcon, r->n_dcon); 328 break; 329 case GE: 330 n = FLOAT_GE(l->n_dcon, r->n_dcon); 331 break; 332 case GT: 333 n = FLOAT_GT(l->n_dcon, r->n_dcon); 334 break; 335 default: 336 n = 0; /* XXX flow analysis */ 337 } 338 nfree(r); 339 nfree(l); 340 return bcon(n); 341 } 342 } 343#ifndef CC_DIV_0 344runtime: 345#endif 346 /* its real; we must make a new node */ 347 348 p = block(o, l, r, INT, 0, 0); 349 350 actions = opact(p); 351 352 if (actions & PROML) 353 p->n_left = intprom(p->n_left); 354 355 if (actions & LVAL) { /* check left descendent */ 356 if (notlval(p->n_left)) { 357 uerror("lvalue required"); 358 nfree(p); 359 return l; 360#ifdef notyet 361 } else { 362 if ((l->n_type > BTMASK && ISCON(l->n_qual)) || 363 (l->n_type <= BTMASK && ISCON(l->n_qual << TSHIFT))) 364 if (blevel > 0) 365 uerror("lvalue is declared const"); 366#endif 367 } 368 } 369 370 if( actions & NCVTR ){ 371 p->n_left = pconvert( p->n_left ); 372 } 373 else if( !(actions & NCVT ) ){ 374 switch( opty ){ 375 376 case BITYPE: 377 p->n_right = pconvert( p->n_right ); 378 case UTYPE: 379 p->n_left = pconvert( p->n_left ); 380 381 } 382 } 383 384 if ((actions&PUN) && (o!=CAST)) 385 chkpun(p); 386 387 if( actions & (TYPL|TYPR) ){ 388 389 q = (actions&TYPL) ? p->n_left : p->n_right; 390 391 p->n_type = q->n_type; 392 p->n_qual = q->n_qual; 393 p->n_df = q->n_df; 394 p->n_ap = q->n_ap; 395 } 396 397 if( actions & CVTL ) p = convert( p, CVTL ); 398 if( actions & CVTR ) p = convert( p, CVTR ); 399 if( actions & TYMATCH ) p = tymatch(p); 400 if( actions & PTMATCH ) p = ptmatch(p); 401 402 if( actions & OTHER ){ 403 struct symtab *sp1; 404 405 l = p->n_left; 406 r = p->n_right; 407 408 switch(o){ 409 410 case NAME: 411 cerror("buildtree NAME"); 412 413 case STREF: 414 /* p->x turned into *(p+offset) */ 415 /* rhs must be a name; check correctness */ 416 417 /* Find member symbol struct */ 418 if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){ 419 uerror("struct or union required"); 420 break; 421 } 422 423 if ((sp1 = strmemb(l->n_ap)) == NULL) { 424 uerror("undefined struct or union"); 425 break; 426 } 427 428 if ((sp = findmember(sp1, r->n_name)) == NULL) { 429 uerror("member '%s' not declared", r->n_name); 430 break; 431 } 432 433 r->n_sp = sp; 434 p = stref(p); 435 break; 436 437 case UMUL: 438 if (l->n_op == ADDROF) { 439 nfree(p); 440 p = nfree(l); 441 } 442 if( !ISPTR(l->n_type))uerror("illegal indirection"); 443 p->n_type = DECREF(l->n_type); 444 p->n_qual = DECREF(l->n_qual); 445 p->n_df = l->n_df; 446 p->n_ap = l->n_ap; 447 break; 448 449 case ADDROF: 450 switch( l->n_op ){ 451 452 case UMUL: 453 nfree(p); 454 p = nfree(l); 455 /* FALLTHROUGH */ 456 case TEMP: 457 case NAME: 458 p->n_type = INCREF(l->n_type); 459 p->n_qual = INCQAL(l->n_qual); 460 p->n_df = l->n_df; 461 p->n_ap = l->n_ap; 462 break; 463 464 case COMOP: 465 nfree(p); 466 lr = buildtree(ADDROF, l->n_right, NIL); 467 p = buildtree( COMOP, l->n_left, lr ); 468 nfree(l); 469 break; 470 471 case QUEST: 472 lr = buildtree( ADDROF, l->n_right->n_right, NIL ); 473 ll = buildtree( ADDROF, l->n_right->n_left, NIL ); 474 nfree(p); nfree(l->n_right); 475 p = buildtree( QUEST, l->n_left, buildtree( COLON, ll, lr ) ); 476 nfree(l); 477 break; 478 479 default: 480 uerror("unacceptable operand of &: %d", l->n_op ); 481 break; 482 } 483 break; 484 485 case LS: 486 case RS: /* must make type size at least int... */ 487 if (p->n_type == CHAR || p->n_type == SHORT) { 488 p->n_left = makety(l, INT, 0, 0, 0); 489 } else if (p->n_type == UCHAR || p->n_type == USHORT) { 490 p->n_left = makety(l, UNSIGNED, 0, 0, 0); 491 } 492 l = p->n_left; 493 p->n_type = l->n_type; 494 p->n_qual = l->n_qual; 495 p->n_df = l->n_df; 496 p->n_ap = l->n_ap; 497 498 /* FALLTHROUGH */ 499 case LSEQ: 500 case RSEQ: /* ...but not for assigned types */ 501 if(tsize(r->n_type, r->n_df, r->n_ap) > SZINT) 502 p->n_right = makety(r, INT, 0, 0, 0); 503 break; 504 505 case RETURN: 506 case ASSIGN: 507 case CAST: 508 /* structure assignment */ 509 /* take the addresses of the two sides; then make an 510 * operator using STASG and 511 * the addresses of left and right */ 512 513 if (strmemb(l->n_ap) != strmemb(r->n_ap)) 514 uerror("assignment of different structures"); 515 516 r = buildtree(ADDROF, r, NIL); 517 518 l = block(STASG, l, r, r->n_type, r->n_df, r->n_ap); 519 l = clocal(l); 520 521 if( o == RETURN ){ 522 nfree(p); 523 p = l; 524 break; 525 } 526 527 p->n_op = UMUL; 528 p->n_left = l; 529 p->n_right = NIL; 530 break; 531 532 case QUEST: /* fixup types of : */ 533 if (r->n_left->n_type != p->n_type) 534 r->n_left = makety(r->n_left, p->n_type, 535 p->n_qual, p->n_df, p->n_ap); 536 if (r->n_right->n_type != p->n_type) 537 r->n_right = makety(r->n_right, p->n_type, 538 p->n_qual, p->n_df, p->n_ap); 539 break; 540 541 case COLON: 542 /* structure colon */ 543 544 if (strmemb(l->n_ap) != strmemb(r->n_ap)) 545 uerror( "type clash in conditional" ); 546 break; 547 548 case CALL: 549 p->n_right = r = strargs(p->n_right); 550 p = funcode(p); 551 /* FALLTHROUGH */ 552 case UCALL: 553 if (!ISPTR(l->n_type)) 554 uerror("illegal function"); 555 p->n_type = DECREF(l->n_type); 556 if (!ISFTN(p->n_type)) 557 uerror("illegal function"); 558 p->n_type = DECREF(p->n_type); 559 p->n_df = l->n_df+1; /* add one for prototypes */ 560 p->n_ap = l->n_ap; 561 if (p->n_type == STRTY || p->n_type == UNIONTY) { 562 /* function returning structure */ 563 /* make function really return ptr to str., with * */ 564 565 p->n_op += STCALL-CALL; 566 p->n_type = INCREF(p->n_type); 567 p = clocal(p); /* before recursing */ 568 p = buildtree(UMUL, p, NIL); 569 570 } 571 break; 572 573 default: 574 cerror( "other code %d", o ); 575 } 576 577 } 578 579 /* 580 * Allow (void)0 casts. 581 * XXX - anything on the right side must be possible to cast. 582 * XXX - remove void types further on. 583 */ 584 if (p->n_op == CAST && p->n_type == VOID && 585 p->n_right->n_op == ICON) 586 p->n_right->n_type = VOID; 587 588 if (actions & CVTO) 589 p = oconvert(p); 590 p = clocal(p); 591 592#ifdef PCC_DEBUG 593 if (bdebug) { 594 printf("End of buildtree:\n"); 595 fwalk(p, eprint, 0); 596 } 597#endif 598 599 return(p); 600 601 } 602 603/* Find a member in a struct or union. May be an unnamed member */ 604static struct symtab * 605findmember(struct symtab *sp, char *s) 606{ 607 struct symtab *sp2, *sp3; 608 609 for (; sp != NULL; sp = sp->snext) { 610 if (sp->sname[0] == '*') { 611 /* unnamed member, recurse down */ 612 if ((sp2 = findmember(strmemb(sp->sap), s))) { 613 sp3 = tmpalloc(sizeof (struct symtab)); 614 *sp3 = *sp2; 615 sp3->soffset += sp->soffset; 616 return sp3; 617 } 618 } else if (sp->sname == s) 619 return sp; 620 } 621 return NULL; 622} 623 624 625/* 626 * Check if there will be a lost label destination inside of a ?: 627 * It cannot be reached so just print it out. 628 */ 629void 630putjops(NODE *p, void *arg) 631{ 632 if (p->n_op == COMOP && p->n_left->n_op == GOTO) 633 plabel((int)p->n_left->n_left->n_lval+1); 634} 635 636/* 637 * Build a name node based on a symtab entry. 638 * broken out from buildtree(). 639 */ 640NODE * 641nametree(struct symtab *sp) 642{ 643 NODE *p; 644 645 p = block(NAME, NIL, NIL, sp->stype, sp->sdf, sp->sap); 646 p->n_qual = sp->squal; 647 p->n_sp = sp; 648 649#ifndef NO_C_BUILTINS 650 if (sp->sname[0] == '_' && strncmp(sp->sname, "__builtin_", 10) == 0) 651 return p; /* do not touch builtins here */ 652 653#endif 654 655 if (sp->sflags & STNODE) { 656 /* Generated for optimizer */ 657 p->n_op = TEMP; 658 p->n_rval = sp->soffset; 659 } 660 661#ifdef GCC_COMPAT 662 /* Get a label name */ 663 if (sp->sflags == SLBLNAME) { 664 p->n_type = VOID; 665 } 666#endif 667 if (sp->stype == UNDEF) { 668 uerror("%s undefined", sp->sname); 669 /* make p look reasonable */ 670 p->n_type = INT; 671 p->n_df = NULL; 672 defid(p, SNULL); 673 } 674 if (sp->sclass == MOE) { 675 p->n_op = ICON; 676 p->n_lval = sp->soffset; 677 p->n_df = NULL; 678 p->n_sp = NULL; 679 } 680 return clocal(p); 681} 682 683/* 684 * Cast a node to another type by inserting a cast. 685 * Just a nicer interface to buildtree. 686 * Returns the new tree. 687 */ 688NODE * 689cast(NODE *p, TWORD t, TWORD u) 690{ 691 NODE *q; 692 693 q = block(NAME, NIL, NIL, t, 0, 0); 694 q->n_qual = u; 695 q = buildtree(CAST, q, p); 696 p = q->n_right; 697 nfree(q->n_left); 698 nfree(q); 699 return p; 700} 701 702/* 703 * Cast and complain if necessary by not inserining a cast. 704 */ 705NODE * 706ccast(NODE *p, TWORD t, TWORD u, union dimfun *df, struct attr *ap) 707{ 708 NODE *q; 709 710 /* let buildtree do typechecking (and casting) */ 711 q = block(NAME, NIL, NIL, t, df, ap); 712 p = buildtree(ASSIGN, q, p); 713 nfree(p->n_left); 714 q = optim(p->n_right); 715 nfree(p); 716 return q; 717} 718 719/* 720 * Do an actual cast of a constant (if possible). 721 * Routine assumes 2-complement (is there anything else today?) 722 * Returns 1 if handled, 0 otherwise. 723 */ 724int 725concast(NODE *p, TWORD t) 726{ 727 extern short sztable[]; 728 CONSZ val; 729 730 if (p->n_op != ICON && p->n_op != FCON) /* only constants */ 731 return 0; 732 if (p->n_op == ICON && p->n_sp != NULL) { /* no addresses */ 733 if (t == BOOL) { 734 p->n_lval = 1, p->n_type = BOOL, p->n_sp = NULL; 735 return 1; 736 } 737 return 0; 738 } 739 if (((p->n_type & TMASK) && t != BOOL) || (t & TMASK)) /* no pointers */ 740 return 0; 741 742//printf("concast till %d\n", t); 743//fwalk(p, eprint, 0); 744 745#define TYPMSK(y) ((((1LL << (y-1))-1) << 1) | 1) 746 if (p->n_op == ICON) { 747 val = p->n_lval; 748 749 if (t == BOOL) { 750 if (val) 751 p->n_lval = 1; 752 } else if (t <= ULONGLONG) { 753 p->n_lval = val & TYPMSK(sztable[t]); 754 if (!ISUNSIGNED(t)) { 755 if (val & (1LL << (sztable[t]-1))) 756 p->n_lval |= ~TYPMSK(sztable[t]); 757 } 758 } else if (t <= LDOUBLE) { 759 p->n_op = FCON; 760 p->n_dcon = FLOAT_CAST(val, p->n_type); 761 } 762 } else { /* p->n_op == FCON */ 763 if (t == BOOL) { 764 p->n_op = ICON; 765 p->n_lval = FLOAT_NE(p->n_dcon,0.0); 766 p->n_sp = NULL; 767 } else if (t <= ULONGLONG) { 768 p->n_op = ICON; 769 p->n_lval = ISUNSIGNED(t) ? /* XXX FIXME */ 770 ((U_CONSZ)p->n_dcon) : p->n_dcon; 771 p->n_sp = NULL; 772 } else { 773 p->n_dcon = t == FLOAT ? (float)p->n_dcon : 774 t == DOUBLE ? (double)p->n_dcon : p->n_dcon; 775 } 776 } 777 p->n_type = t; 778//fwalk(p, eprint, 0); 779 return 1; 780} 781 782/* 783 * Do a conditional branch. 784 */ 785void 786cbranch(NODE *p, NODE *q) 787{ 788 p = buildtree(CBRANCH, p, q); 789 if (p->n_left->n_op == ICON) { 790 if (p->n_left->n_lval != 0) { 791 branch((int)q->n_lval); /* branch always */ 792 reached = 0; 793 } 794 tfree(p); 795 tfree(q); 796 return; 797 } 798 ecomp(p); 799} 800 801NODE * 802strargs( p ) register NODE *p; { /* rewrite structure flavored arguments */ 803 804 if( p->n_op == CM ){ 805 p->n_left = strargs( p->n_left ); 806 p->n_right = strargs( p->n_right ); 807 return( p ); 808 } 809 810 if( p->n_type == STRTY || p->n_type == UNIONTY ){ 811 p = block(STARG, p, NIL, p->n_type, p->n_df, p->n_ap); 812 p->n_left = buildtree( ADDROF, p->n_left, NIL ); 813 p = clocal(p); 814 } 815 return( p ); 816} 817 818/* 819 * apply the op o to the lval part of p; if binary, rhs is val 820 */ 821int 822conval(NODE *p, int o, NODE *q) 823{ 824 TWORD tl = p->n_type, tr = q->n_type, td; 825 int i, u; 826 CONSZ val; 827 U_CONSZ v1, v2; 828 829 val = q->n_lval; 830 831 /* make both sides same type */ 832 if (tl < BTMASK && tr < BTMASK) { 833 td = tl > tr ? tl : tr; 834 if (td < INT) 835 td = INT; 836 u = ISUNSIGNED(td); 837 if (tl != td) 838 p = makety(p, td, 0, 0, 0); 839 if (tr != td) 840 q = makety(q, td, 0, 0, 0); 841 } else 842 u = ISUNSIGNED(tl) || ISUNSIGNED(tr); 843 if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE); 844 845 if (p->n_sp != NULL && q->n_sp != NULL) 846 return(0); 847 if (q->n_sp != NULL && o != PLUS) 848 return(0); 849 if (p->n_sp != NULL && o != PLUS && o != MINUS) 850 return(0); 851 852 v1 = p->n_lval; 853 v2 = q->n_lval; 854 if (v2 == 0 && (cdope(o) & DIVFLG)) 855 return 0; /* leave division by zero to runtime */ 856 switch( o ){ 857 858 case PLUS: 859 p->n_lval += val; 860 if (p->n_sp == NULL) { 861 p->n_right = q->n_right; 862 p->n_type = q->n_type; 863 } 864 break; 865 case MINUS: 866 p->n_lval -= val; 867 break; 868 case MUL: 869 p->n_lval *= val; 870 break; 871 case DIV: 872 if (u) { 873 v1 /= v2; 874 p->n_lval = v1; 875 } else 876 p->n_lval /= val; 877 break; 878 case MOD: 879 if (u) { 880 v1 %= v2; 881 p->n_lval = v1; 882 } else 883 p->n_lval %= val; 884 break; 885 case AND: 886 p->n_lval &= val; 887 break; 888 case OR: 889 p->n_lval |= val; 890 break; 891 case ER: 892 p->n_lval ^= val; 893 break; 894 case LS: 895 i = (int)val; 896 p->n_lval = p->n_lval << i; 897 break; 898 case RS: 899 i = (int)val; 900 if (u) { 901 v1 = v1 >> i; 902 p->n_lval = v1; 903 } else 904 p->n_lval = p->n_lval >> i; 905 break; 906 907 case UMINUS: 908 p->n_lval = - p->n_lval; 909 break; 910 case COMPL: 911 p->n_lval = ~p->n_lval; 912 break; 913 case NOT: 914 p->n_lval = !p->n_lval; 915 break; 916 case LT: 917 p->n_lval = p->n_lval < val; 918 break; 919 case LE: 920 p->n_lval = p->n_lval <= val; 921 break; 922 case GT: 923 p->n_lval = p->n_lval > val; 924 break; 925 case GE: 926 p->n_lval = p->n_lval >= val; 927 break; 928 case ULT: 929 p->n_lval = v1 < v2; 930 break; 931 case ULE: 932 p->n_lval = v1 <= v2; 933 break; 934 case UGT: 935 p->n_lval = v1 > v2; 936 break; 937 case UGE: 938 p->n_lval = v1 >= v2; 939 break; 940 case EQ: 941 p->n_lval = p->n_lval == val; 942 break; 943 case NE: 944 p->n_lval = p->n_lval != val; 945 break; 946 case ANDAND: 947 p->n_lval = p->n_lval && val; 948 break; 949 case OROR: 950 p->n_lval = p->n_lval || val; 951 break; 952 default: 953 return(0); 954 } 955 /* Do the best in making everything type correct after calc */ 956 if (p->n_sp == NULL && q->n_sp == NULL) 957 p->n_lval = valcast(p->n_lval, p->n_type); 958 return(1); 959 } 960 961/* 962 * Ensure that v matches the type t; sign- or zero-extended 963 * as suitable to CONSZ. 964 * Only to be used for integer types. 965 */ 966CONSZ 967valcast(CONSZ v, TWORD t) 968{ 969 CONSZ r; 970 int sz; 971 972 if (t < CHAR || t > ULONGLONG) 973 return v; /* cannot cast */ 974 975 if (t >= LONGLONG) 976 return v; /* already largest */ 977 978#define M(x) ((((1ULL << ((x)-1)) - 1) << 1) + 1) 979#define NOTM(x) (~M(x)) 980#define SBIT(x) (1ULL << ((x)-1)) 981 982 sz = (int)tsize(t, NULL, NULL); 983 r = v & M(sz); 984 if (!ISUNSIGNED(t) && (SBIT(sz) & r)) 985 r = r | NOTM(sz); 986 return r; 987} 988 989/* 990 * Checks p for the existance of a pun. This is called when the op of p 991 * is ASSIGN, RETURN, CAST, COLON, or relational. 992 * One case is when enumerations are used: this applies only to lint. 993 * In the other case, one operand is a pointer, the other integer type 994 * we check that this integer is in fact a constant zero... 995 * in the case of ASSIGN, any assignment of pointer to integer is illegal 996 * this falls out, because the LHS is never 0. 997 * XXX - check for COMOPs in assignment RHS? 998 */ 999void 1000chkpun(NODE *p) 1001{ 1002 union dimfun *d1, *d2; 1003 NODE *q; 1004 int t1, t2; 1005 1006 t1 = p->n_left->n_type; 1007 t2 = p->n_right->n_type; 1008 1009 switch (p->n_op) { 1010 case RETURN: 1011 /* return of void allowed but nothing else */ 1012 if (t1 == VOID && t2 == VOID) 1013 return; 1014 if (t1 == VOID) { 1015 werror("returning value from void function"); 1016 return; 1017 } 1018 if (t2 == VOID) { 1019 uerror("using void value"); 1020 return; 1021 } 1022 case COLON: 1023 if (t1 == VOID && t2 == VOID) 1024 return; 1025 break; 1026 default: 1027 if ((t1 == VOID && t2 != VOID) || (t1 != VOID && t2 == VOID)) { 1028 uerror("value of void expression used"); 1029 return; 1030 } 1031 break; 1032 } 1033 1034 /* allow void pointer assignments in any direction */ 1035 if (BTYPE(t1) == VOID && (t2 & TMASK)) 1036 return; 1037 if (BTYPE(t2) == VOID && (t1 & TMASK)) 1038 return; 1039 1040 /* boolean have special syntax */ 1041 if (t1 == BOOL) { 1042 if (!ISARY(t2)) /* Anything scalar */ 1043 return; 1044 } 1045 1046 if (ISPTR(t1) || ISARY(t1)) 1047 q = p->n_right; 1048 else 1049 q = p->n_left; 1050 1051 if (!ISPTR(q->n_type) && !ISARY(q->n_type)) { 1052 if (q->n_op != ICON || q->n_lval != 0) 1053 werror("illegal combination of pointer and integer"); 1054 } else { 1055 if (t1 == t2) { 1056 if (ISSOU(BTYPE(t1)) && 1057 !suemeq(p->n_left->n_ap, p->n_right->n_ap)) 1058 werror("illegal structure pointer combination"); 1059 return; 1060 } 1061 d1 = p->n_left->n_df; 1062 d2 = p->n_right->n_df; 1063 for (;;) { 1064 if (ISARY(t1) || ISPTR(t1)) { 1065 if (!ISARY(t2) && !ISPTR(t2)) 1066 break; 1067 if (ISARY(t1) && ISARY(t2) && d1->ddim != d2->ddim) { 1068 werror("illegal array size combination"); 1069 return; 1070 } 1071 if (ISARY(t1)) 1072 ++d1; 1073 if (ISARY(t2)) 1074 ++d2; 1075 } else if (ISFTN(t1)) { 1076 if (chkftn(d1->dfun, d2->dfun)) { 1077 werror("illegal function " 1078 "pointer combination"); 1079 return; 1080 } 1081 ++d1; 1082 ++d2; 1083 } else 1084 break; 1085 t1 = DECREF(t1); 1086 t2 = DECREF(t2); 1087 } 1088 if (DEUNSIGN(t1) != DEUNSIGN(t2)) 1089 warner(Wpointer_sign, NULL); 1090 } 1091} 1092 1093static NODE * 1094offplus(NODE *p, int off, TWORD t, TWORD q, union dimfun *d, struct attr *ap) { 1095 if (off != 0) { 1096 p = block(PLUS, p, offcon(off, t, d, ap), t, d, ap); 1097 p->n_qual = q; 1098 p = optim(p); 1099 } 1100 1101 return buildtree(UMUL, p, NIL); 1102} 1103 1104NODE * 1105stref(NODE *p) 1106{ 1107 NODE *r; 1108 struct attr *ap, *xap, *yap; 1109 union dimfun *d; 1110 TWORD t, q; 1111 int dsc; 1112 OFFSZ off; 1113 struct symtab *s; 1114 1115 /* make p->x */ 1116 /* this is also used to reference automatic variables */ 1117 1118 s = p->n_right->n_sp; 1119 nfree(p->n_right); 1120 r = nfree(p); 1121 xap = attr_find(r->n_ap, GCC_ATYP_PACKED); 1122 1123 p = pconvert(r); 1124 1125 /* make p look like ptr to x */ 1126 1127 if (!ISPTR(p->n_type)) 1128 p->n_type = PTR+UNIONTY; 1129 1130 t = INCREF(s->stype); 1131 q = INCQAL(s->squal); 1132 d = s->sdf; 1133 ap = s->sap; 1134 if ((yap = attr_find(ap, GCC_ATYP_PACKED)) != NULL) 1135 xap = yap; 1136 else if (xap != NULL) 1137 ap = attr_add(ap, attr_dup(xap, 3)); 1138 /* xap set if packed struct */ 1139 1140 p = makety(p, t, q, d, ap); 1141 1142 /* compute the offset to be added */ 1143 1144 off = s->soffset; 1145 dsc = s->sclass; 1146 1147 if (dsc & FIELD) { 1148 TWORD ftyp = s->stype; 1149 int fal = talign(ftyp, ap); 1150 off = (off/fal)*fal; 1151 p = offplus(p, off, t, q, d, ap); 1152 p = block(FLD, p, NIL, ftyp, 0, ap); 1153 p->n_qual = q; 1154 p->n_rval = PKFIELD(dsc&FLDSIZ, s->soffset%fal); 1155 } else { 1156 p = offplus(p, off, t, q, d, ap); 1157#ifndef CAN_UNALIGN 1158 /* if target cannot handle unaligned addresses, fix here */ 1159#endif 1160 } 1161 1162 p = clocal(p); 1163 return p; 1164} 1165 1166int 1167notlval(p) register NODE *p; { 1168 1169 /* return 0 if p an lvalue, 1 otherwise */ 1170 1171 again: 1172 1173 switch( p->n_op ){ 1174 1175 case FLD: 1176 p = p->n_left; 1177 goto again; 1178 1179 case NAME: 1180 case OREG: 1181 case UMUL: 1182 if( ISARY(p->n_type) || ISFTN(p->n_type) ) return(1); 1183 case TEMP: 1184 case REG: 1185 return(0); 1186 1187 default: 1188 return(1); 1189 1190 } 1191 1192 } 1193/* make a constant node with value i */ 1194NODE * 1195bcon(int i) 1196{ 1197 return xbcon(i, NULL, INT); 1198} 1199 1200NODE * 1201xbcon(CONSZ val, struct symtab *sp, TWORD type) 1202{ 1203 NODE *p; 1204 1205 p = block(ICON, NIL, NIL, type, 0, 0); 1206 p->n_lval = val; 1207 p->n_sp = sp; 1208 return clocal(p); 1209} 1210 1211NODE * 1212bpsize(NODE *p) 1213{ 1214 int isdyn(struct symtab *sp); 1215 struct symtab s; 1216 NODE *q, *r; 1217 TWORD t; 1218 int sz; 1219 1220 s.stype = DECREF(p->n_type); 1221 s.sdf = p->n_df; 1222 if (isdyn(&s)) { 1223 q = bcon(1); 1224 for (t = s.stype; t > BTMASK; t = DECREF(t)) { 1225 if (ISPTR(t)) 1226 return buildtree(MUL, q, bcon(SZPOINT(t))); 1227 if (ISARY(t)) { 1228 if (s.sdf->ddim < 0) 1229 r = tempnode(-s.sdf->ddim, INT, 0, 0); 1230 else 1231 r = bcon(s.sdf->ddim/SZCHAR); 1232 q = buildtree(MUL, q, r); 1233 s.sdf++; 1234 } 1235 } 1236 sz = (int)tsize(p->n_type, p->n_df, p->n_ap); 1237 p = buildtree(MUL, q, bcon(sz/SZCHAR)); 1238 } else 1239 p = (offcon(psize(p), p->n_type, p->n_df, p->n_ap)); 1240 return p; 1241} 1242 1243/* 1244 * p is a node of type pointer; psize returns the 1245 * size of the thing pointed to 1246 */ 1247OFFSZ 1248psize(NODE *p) 1249{ 1250 1251 if (!ISPTR(p->n_type)) { 1252 uerror("pointer required"); 1253 return(SZINT); 1254 } 1255 /* note: no pointers to fields */ 1256 return(tsize(DECREF(p->n_type), p->n_df, p->n_ap)); 1257} 1258 1259/* 1260 * convert an operand of p 1261 * f is either CVTL or CVTR 1262 * operand has type int, and is converted by the size of the other side 1263 * convert is called when an integer is to be added to a pointer, for 1264 * example in arrays or structures. 1265 */ 1266NODE * 1267convert(NODE *p, int f) 1268{ 1269 union dimfun *df; 1270 TWORD ty, ty2; 1271 NODE *q, *r, *s, *rv; 1272 1273 if (f == CVTL) { 1274 q = p->n_left; 1275 s = p->n_right; 1276 } else { 1277 q = p->n_right; 1278 s = p->n_left; 1279 } 1280 ty2 = ty = DECREF(s->n_type); 1281 while (ISARY(ty)) 1282 ty = DECREF(ty); 1283 1284 r = offcon(tsize(ty, s->n_df, s->n_ap), s->n_type, s->n_df, s->n_ap); 1285 ty = ty2; 1286 rv = bcon(1); 1287 df = s->n_df; 1288 while (ISARY(ty)) { 1289 rv = buildtree(MUL, rv, df->ddim >= 0 ? bcon(df->ddim) : 1290 tempnode(-df->ddim, INT, 0, 0)); 1291 df++; 1292 ty = DECREF(ty); 1293 } 1294 rv = clocal(MBLOCK(rv, r, INT, 0, 0)); 1295 rv = optim(rv); 1296 1297 r = MBLOCK(q, rv, INT, 0, 0); 1298 r = clocal(r); 1299 /* 1300 * Indexing is only allowed with integer arguments, so insert 1301 * SCONV here if arg is not an integer. 1302 * XXX - complain? 1303 */ 1304 if (r->n_type != INTPTR) 1305 r = clocal(makety(r, INTPTR, 0, 0, 0)); 1306 if (f == CVTL) 1307 p->n_left = r; 1308 else 1309 p->n_right = r; 1310 return(p); 1311} 1312 1313NODE * 1314pconvert( p ) register NODE *p; { 1315 1316 /* if p should be changed into a pointer, do so */ 1317 1318 if( ISARY( p->n_type) ){ 1319 p->n_type = DECREF( p->n_type ); 1320 ++p->n_df; 1321 return( buildtree( ADDROF, p, NIL ) ); 1322 } 1323 if( ISFTN( p->n_type) ) 1324 return( buildtree( ADDROF, p, NIL ) ); 1325 1326 return( p ); 1327 } 1328 1329NODE * 1330oconvert(p) register NODE *p; { 1331 /* convert the result itself: used for pointer and unsigned */ 1332 1333 switch(p->n_op) { 1334 1335 case LE: 1336 case LT: 1337 case GE: 1338 case GT: 1339 if(ISUNSIGNED(p->n_left->n_type) || 1340 ISUNSIGNED(p->n_right->n_type) || 1341 ISPTR(p->n_left->n_type) || 1342 ISPTR(p->n_right->n_type)) 1343 p->n_op += (ULE-LE); 1344 /* FALLTHROUGH */ 1345 case EQ: 1346 case NE: 1347 return( p ); 1348 1349 case MINUS: 1350 p->n_type = INTPTR; 1351 p->n_ap = NULL; 1352 return(clocal(VBLOCK(p, bpsize(p->n_left), INT, 0, 0))); 1353 } 1354 1355 cerror( "illegal oconvert: %d", p->n_op ); 1356 1357 return(p); 1358 } 1359 1360/* 1361 * makes the operands of p agree; they are 1362 * either pointers or integers, by this time 1363 * with MINUS, the sizes must be the same 1364 * with COLON, the types must be the same 1365 */ 1366NODE * 1367ptmatch(NODE *p) 1368{ 1369 struct attr *ap, *ap2; 1370 union dimfun *d, *d2; 1371 TWORD t1, t2, t, q1, q2, q; 1372 int o; 1373 1374 o = p->n_op; 1375 t = t1 = p->n_left->n_type; 1376 q = q1 = p->n_left->n_qual; 1377 t2 = p->n_right->n_type; 1378 q2 = p->n_right->n_qual; 1379 d = p->n_left->n_df; 1380 d2 = p->n_right->n_df; 1381 ap = p->n_left->n_ap; 1382 ap2 = p->n_right->n_ap; 1383 1384 switch( o ){ 1385 1386 case ASSIGN: 1387 case RETURN: 1388 { break; } 1389 1390 case CAST: 1391 if (t == VOID) { 1392 /* just paint over */ 1393 p->n_right = block(SCONV, p->n_right, NIL, VOID, 0, 0); 1394 return p; 1395 } 1396 break; 1397 1398 case MINUS: { 1399 int isdyn(struct symtab *sp); 1400 struct symtab s1, s2; 1401 1402 s1.stype = DECREF(t); 1403 s1.sdf = d; 1404 s2.stype = DECREF(t2); 1405 s2.sdf = d2; 1406 if (isdyn(&s1) || isdyn(&s2)) 1407 ; /* We don't know */ 1408 else if (psize(p->n_left) != psize(p->n_right)) 1409 uerror("illegal pointer subtraction"); 1410 break; 1411 } 1412 1413 case COLON: 1414 if (t1 != t2) { 1415 /* 1416 * Check for void pointer types. They are allowed 1417 * to cast to/from any pointers. 1418 */ 1419 if (ISPTR(t1) && ISPTR(t2) && 1420 (BTYPE(t1) == VOID || BTYPE(t2) == VOID)) 1421 break; 1422 uerror("illegal types in :"); 1423 } 1424 break; 1425 1426 default: /* must work harder: relationals or comparisons */ 1427 1428 if( !ISPTR(t1) ){ 1429 t = t2; 1430 q = q2; 1431 d = d2; 1432 ap = ap2; 1433 break; 1434 } 1435 if( !ISPTR(t2) ){ 1436 break; 1437 } 1438 1439 /* both are pointers */ 1440 if( talign(t2,ap2) < talign(t,ap) ){ 1441 t = t2; 1442 q = q2; 1443 ap = ap2; 1444 } 1445 break; 1446 } 1447 1448 p->n_left = makety( p->n_left, t, q, d, ap ); 1449 p->n_right = makety( p->n_right, t, q, d, ap ); 1450 if( o!=MINUS && !clogop(o) ){ 1451 1452 p->n_type = t; 1453 p->n_qual = q; 1454 p->n_df = d; 1455 p->n_ap = ap; 1456 } 1457 1458 return(clocal(p)); 1459 } 1460 1461/* 1462 * Satisfy the types of various arithmetic binary ops. 1463 * 1464 * rules are: 1465 * if assignment, type of LHS 1466 * if any doubles, make double 1467 * else if any float make float 1468 * else if any longlongs, make long long 1469 * else if any longs, make long 1470 * else etcetc. 1471 * 1472 * If the op with the highest rank is unsigned, this is the resulting type. 1473 * See: 6.3.1.1 rank order equal of signed and unsigned types 1474 * 6.3.1.8 Usual arithmetic conversions 1475 */ 1476static NODE * 1477tymatch(NODE *p) 1478{ 1479 TWORD tl, tr, t; 1480 NODE *l, *r; 1481 int o; 1482 1483 o = p->n_op; 1484 r = p->n_right; 1485 l = p->n_left; 1486 1487 tl = l->n_type; 1488 tr = r->n_type; 1489 1490 if (tl == BOOL) tl = BOOL_TYPE; 1491 if (tr == BOOL) tr = BOOL_TYPE; 1492 1493 if (casgop(o)) { 1494 if (r->n_op != ICON && tl < FLOAT && tr < FLOAT && 1495 DEUNSIGN(tl) < DEUNSIGN(tr) && o != CAST) 1496 warner(Wtruncate, tnames[tr], tnames[tl]); 1497 p->n_right = makety(p->n_right, l->n_type, 0, 0, 0); 1498 t = p->n_type = l->n_type; 1499 p->n_ap = l->n_ap; 1500 } else { 1501 t = tl > tr ? tl : tr; /* MAX */ 1502 /* This depends on ctype() called early */ 1503 if (o != COLON && t < INT) 1504 t = INT; 1505 if (tl != t) p->n_left = makety(p->n_left, t, 0, 0, 0); 1506 if (tr != t) p->n_right = makety(p->n_right, t, 0, 0, 0); 1507 if (o == COLON && l->n_type == BOOL && r->n_type == BOOL) 1508 t = p->n_type = BOOL; 1509 else if (!clogop(o)) 1510 p->n_type = t; 1511 } 1512#ifdef PCC_DEBUG 1513 if (tdebug) { 1514 printf("tymatch(%p): ", p); 1515 tprint(stdout, tl, 0); 1516 printf(" %s ", copst(o)); 1517 tprint(stdout, tr, 0); 1518 printf(" => "); 1519 tprint(stdout, t, 0); 1520 printf("\n"); 1521 fwalk(p, eprint, 0); 1522 } 1523#endif 1524 return p; 1525} 1526 1527/* 1528 * make p into type t by inserting a conversion 1529 */ 1530NODE * 1531makety(NODE *p, TWORD t, TWORD q, union dimfun *d, struct attr *ap) 1532{ 1533 1534 if (t == p->n_type) { 1535 p->n_df = d; 1536 p->n_ap = ap; 1537 p->n_qual = q; 1538 return(p); 1539 } 1540 1541 if (ISITY(t) || ISCTY(t) || ISITY(p->n_type) || ISCTY(p->n_type)) 1542 cerror("makety"); 1543 1544 if (concast(p, t)) 1545 return clocal(p); 1546 1547 p = block(t & TMASK ? PCONV : SCONV, p, NIL, t, d, ap); 1548 p->n_qual = q; 1549 return clocal(p); 1550 1551} 1552 1553NODE * 1554block(int o, NODE *l, NODE *r, TWORD t, union dimfun *d, struct attr *ap) 1555{ 1556 register NODE *p; 1557 1558 p = talloc(); 1559 p->n_rval = 0; 1560 p->n_op = o; 1561 p->n_lval = 0; /* Protect against large lval */ 1562 p->n_left = l; 1563 p->n_right = r; 1564 p->n_type = t; 1565 p->n_qual = 0; 1566 p->n_df = d; 1567 p->n_ap = ap; 1568#if !defined(MULTIPASS) 1569 /* p->n_reg = */p->n_su = 0; 1570 p->n_regw = 0; 1571#endif 1572 return(p); 1573 } 1574 1575/* 1576 * Return the constant value from an ICON. 1577 */ 1578CONSZ 1579icons(NODE *p) 1580{ 1581 /* if p is an integer constant, return its value */ 1582 CONSZ val; 1583 1584 if (p->n_op != ICON || p->n_sp != NULL) { 1585 uerror( "constant expected"); 1586 val = 1; 1587 } else 1588 val = p->n_lval; 1589 tfree(p); 1590 return(val); 1591} 1592 1593/* 1594 * the intent of this table is to examine the 1595 * operators, and to check them for 1596 * correctness. 1597 * 1598 * The table is searched for the op and the 1599 * modified type (where this is one of the 1600 * types INT (includes char and short), LONG, 1601 * DOUBLE (includes FLOAT), and POINTER 1602 * 1603 * The default action is to make the node type integer 1604 * 1605 * The actions taken include: 1606 * PUN check for puns 1607 * CVTL convert the left operand 1608 * CVTR convert the right operand 1609 * TYPL the type is determined by the left operand 1610 * TYPR the type is determined by the right operand 1611 * TYMATCH force type of left and right to match,by inserting conversions 1612 * PTMATCH like TYMATCH, but for pointers 1613 * LVAL left operand must be lval 1614 * CVTO convert the op 1615 * NCVT do not convert the operands 1616 * OTHER handled by code 1617 * NCVTR convert the left operand, not the right... 1618 * 1619 */ 1620 1621# define MINT 01 /* integer */ 1622# define MDBI 02 /* integer or double */ 1623# define MSTR 04 /* structure */ 1624# define MPTR 010 /* pointer */ 1625# define MPTI 020 /* pointer or integer */ 1626 1627int 1628opact(NODE *p) 1629{ 1630 int mt12, mt1, mt2, o; 1631 1632 mt1 = mt2 = mt12 = 0; 1633 1634 switch (coptype(o = p->n_op)) { 1635 case BITYPE: 1636 mt12=mt2 = moditype(p->n_right->n_type); 1637 case UTYPE: 1638 mt12 &= (mt1 = moditype(p->n_left->n_type)); 1639 break; 1640 } 1641 1642 switch( o ){ 1643 1644 case NAME : 1645 case ICON : 1646 case FCON : 1647 case CALL : 1648 case UCALL: 1649 case UMUL: 1650 { return( OTHER ); } 1651 case UMINUS: 1652 if( mt1 & MDBI ) return( TYPL+PROML ); 1653 break; 1654 1655 case COMPL: 1656 if( mt1 & MINT ) return( TYPL+PROML ); 1657 break; 1658 1659 case ADDROF: 1660 return( NCVT+OTHER ); 1661 case NOT: 1662 return( PROML ); 1663 1664/* case INIT: */ 1665 case CM: 1666 case CBRANCH: 1667 case ANDAND: 1668 case OROR: 1669 return( 0 ); 1670 1671 case MUL: 1672 case DIV: 1673 if( mt12 & MDBI ) return( TYMATCH ); 1674 break; 1675 1676 case MOD: 1677 case AND: 1678 case OR: 1679 case ER: 1680 if( mt12 & MINT ) return( TYMATCH ); 1681 break; 1682 1683 case LS: 1684 case RS: 1685 if( mt12 & MINT ) return( TYPL+OTHER ); 1686 break; 1687 1688 case EQ: 1689 case NE: 1690 case LT: 1691 case LE: 1692 case GT: 1693 case GE: 1694 if( mt12 & MDBI ) return( TYMATCH+CVTO ); 1695 else if( mt12 & MPTR ) return( PTMATCH+PUN+CVTO ); 1696 else if( mt12 & MPTI ) return( PTMATCH+PUN ); 1697 else break; 1698 1699 case QUEST: 1700 return( TYPR+OTHER ); 1701 case COMOP: 1702 return( TYPR ); 1703 1704 case STREF: 1705 return( NCVTR+OTHER ); 1706 1707 case FORCE: 1708 return( TYPL ); 1709 1710 case COLON: 1711 if( mt12 & MDBI ) return( TYMATCH ); 1712 else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN ); 1713 else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN ); 1714 else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN ); 1715 else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER ); 1716 break; 1717 1718 case ASSIGN: 1719 case RETURN: 1720 if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER ); 1721 case CAST: 1722 if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH ); 1723 else if( mt1 & MPTR) return( LVAL+PTMATCH+PUN ); 1724 else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN ); 1725 break; 1726 1727 case LSEQ: 1728 case RSEQ: 1729 if( mt12 & MINT ) return( TYPL+LVAL+OTHER ); 1730 break; 1731 1732 case MULEQ: 1733 case DIVEQ: 1734 if( mt12 & MDBI ) return( LVAL+TYMATCH ); 1735 break; 1736 1737 case MODEQ: 1738 case ANDEQ: 1739 case OREQ: 1740 case EREQ: 1741 if (mt12 & MINT) 1742 return(LVAL+TYMATCH); 1743 break; 1744 1745 case PLUSEQ: 1746 case MINUSEQ: 1747 case INCR: 1748 case DECR: 1749 if (mt12 & MDBI) 1750 return(TYMATCH+LVAL); 1751 else if ((mt1&MPTR) && (mt2&MINT)) 1752 return(TYPL+LVAL+CVTR); 1753 break; 1754 1755 case MINUS: 1756 if (mt12 & MPTR) 1757 return(CVTO+PTMATCH+PUN); 1758 if (mt2 & MPTR) 1759 break; 1760 /* FALLTHROUGH */ 1761 case PLUS: 1762 if (mt12 & MDBI) 1763 return(TYMATCH); 1764 else if ((mt1&MPTR) && (mt2&MINT)) 1765 return(TYPL+CVTR); 1766 else if ((mt1&MINT) && (mt2&MPTR)) 1767 return(TYPR+CVTL); 1768 1769 } 1770 uerror("operands of %s have incompatible types", copst(o)); 1771 return(NCVT); 1772} 1773 1774int 1775moditype(TWORD ty) 1776{ 1777 switch (ty) { 1778 1779 case STRTY: 1780 case UNIONTY: 1781 return( MSTR ); 1782 1783 case BOOL: 1784 case CHAR: 1785 case SHORT: 1786 case UCHAR: 1787 case USHORT: 1788 case UNSIGNED: 1789 case ULONG: 1790 case ULONGLONG: 1791 case INT: 1792 case LONG: 1793 case LONGLONG: 1794 return( MINT|MDBI|MPTI ); 1795 case FLOAT: 1796 case DOUBLE: 1797 case LDOUBLE: 1798#ifndef NO_COMPLEX 1799 case FCOMPLEX: 1800 case COMPLEX: 1801 case LCOMPLEX: 1802 case FIMAG: 1803 case IMAG: 1804 case LIMAG: 1805#endif 1806 return( MDBI ); 1807 default: 1808 return( MPTR|MPTI ); 1809 1810 } 1811} 1812 1813int tvaloff = MAXREGS+NPERMREG > 100 ? MAXREGS+NPERMREG + 100 : 100; 1814 1815/* 1816 * Returns a TEMP node with temp number nr. 1817 * If nr == 0, return a node with a new number. 1818 */ 1819NODE * 1820tempnode(int nr, TWORD type, union dimfun *df, struct attr *ap) 1821{ 1822 NODE *r; 1823 1824 if (tvaloff == -NOOFFSET) 1825 tvaloff++; /* Skip this for array indexing */ 1826 r = block(TEMP, NIL, NIL, type, df, ap); 1827 regno(r) = nr ? nr : tvaloff; 1828 tvaloff += szty(type); 1829 return r; 1830} 1831 1832/* 1833 * Do sizeof on p. 1834 */ 1835NODE * 1836doszof(NODE *p) 1837{ 1838 extern NODE *arrstk[10]; 1839 extern int arrstkp; 1840 union dimfun *df; 1841 TWORD ty; 1842 NODE *rv, *q; 1843 int astkp; 1844 1845 if (p->n_op == FLD) 1846 uerror("can't apply sizeof to bit-field"); 1847 1848 /* 1849 * Arrays may be dynamic, may need to make computations. 1850 */ 1851 1852 rv = bcon(1); 1853 df = p->n_df; 1854 ty = p->n_type; 1855 astkp = 0; 1856 while (ISARY(ty)) { 1857 if (df->ddim == NOOFFSET) 1858 uerror("sizeof of incomplete type"); 1859 if (df->ddim < 0) { 1860 if (arrstkp) 1861 q = arrstk[astkp++]; 1862 else 1863 q = tempnode(-df->ddim, INT, 0, 0); 1864 } else 1865 q = bcon(df->ddim); 1866 rv = buildtree(MUL, rv, q); 1867 df++; 1868 ty = DECREF(ty); 1869 } 1870 rv = buildtree(MUL, rv, 1871 xbcon(tsize(ty, p->n_df, p->n_ap)/SZCHAR, NULL, INTPTR)); 1872 tfree(p); 1873 arrstkp = 0; /* XXX - may this fail? */ 1874 return rv; 1875} 1876 1877#ifdef PCC_DEBUG 1878void 1879eprint(NODE *p, int down, int *a, int *b) 1880{ 1881 int ty; 1882 1883 *a = *b = down+1; 1884 while( down > 1 ){ 1885 printf( "\t" ); 1886 down -= 2; 1887 } 1888 if( down ) printf( " " ); 1889 1890 ty = coptype( p->n_op ); 1891 1892 printf("%p) %s, ", p, copst(p->n_op)); 1893 if (p->n_op == XARG || p->n_op == XASM) 1894 printf("id '%s', ", p->n_name); 1895 if (ty == LTYPE) { 1896 printf(CONFMT, p->n_lval); 1897 if (p->n_op == NAME || p->n_op == ICON) 1898 printf(", %p, ", p->n_sp); 1899 else 1900 printf(", %d, ", p->n_rval); 1901 } 1902 tprint(stdout, p->n_type, p->n_qual); 1903 printf( ", %p, ", p->n_df); 1904 dump_attr(p->n_ap); 1905} 1906# endif 1907 1908/* 1909 * Emit everything that should be emitted on the left side 1910 * of a comma operator, and remove the operator. 1911 * Do not traverse through QUEST, ANDAND and OROR. 1912 * Enable this for all targets when stable enough. 1913 */ 1914static void 1915comops(NODE *p) 1916{ 1917 int o; 1918 NODE *q; 1919 1920 while (p->n_op == COMOP) { 1921 /* XXX hack for GCC ({ }) ops */ 1922 if (p->n_left->n_op == GOTO) { 1923 int v = (int)p->n_left->n_left->n_lval; 1924 ecomp(p->n_left); 1925 plabel(v+1); 1926 } else 1927 ecomp(p->n_left); /* will recurse if more COMOPs */ 1928 q = p->n_right; 1929 *p = *q; 1930 nfree(q); 1931 } 1932 o = coptype(p->n_op); 1933 if (p->n_op == QUEST || p->n_op == ANDAND || p->n_op == OROR) 1934 o = UTYPE; 1935 if (o != LTYPE) 1936 comops(p->n_left); 1937 if (o == BITYPE) 1938 comops(p->n_right); 1939} 1940 1941/* 1942 * Walk up through the tree from the leaves, 1943 * removing constant operators. 1944 */ 1945static void 1946logwalk(NODE *p) 1947{ 1948 int o = coptype(p->n_op); 1949 NODE *l, *r; 1950 1951 l = p->n_left; 1952 r = p->n_right; 1953 switch (o) { 1954 case LTYPE: 1955 return; 1956 case BITYPE: 1957 logwalk(r); 1958 case UTYPE: 1959 logwalk(l); 1960 } 1961 if (!clogop(p->n_op)) 1962 return; 1963 if (p->n_op == NOT && l->n_op == ICON) { 1964 p->n_lval = l->n_lval == 0; 1965 nfree(l); 1966 p->n_op = ICON; 1967 } 1968 if (l->n_op == ICON && r->n_op == ICON) { 1969 if (conval(l, p->n_op, r) == 0) { 1970 /* 1971 * people sometimes tend to do really odd compares, 1972 * like "if ("abc" == "def")" etc. 1973 * do it runtime instead. 1974 */ 1975 } else { 1976 p->n_lval = l->n_lval; 1977 p->n_op = ICON; 1978 nfree(l); 1979 nfree(r); 1980 } 1981 } 1982} 1983 1984/* 1985 * Removes redundant logical operators for branch conditions. 1986 */ 1987static void 1988fixbranch(NODE *p, int label) 1989{ 1990 1991 logwalk(p); 1992 1993 if (p->n_op == ICON) { 1994 if (p->n_lval != 0) 1995 branch(label); 1996 nfree(p); 1997 } else { 1998 if (!clogop(p->n_op)) /* Always conditional */ 1999 p = buildtree(NE, p, bcon(0)); 2000 ecode(buildtree(CBRANCH, p, bcon(label))); 2001 } 2002} 2003 2004/* 2005 * Write out logical expressions as branches. 2006 */ 2007static void 2008andorbr(NODE *p, int true, int false) 2009{ 2010 NODE *q; 2011 int o, lab; 2012 2013 lab = -1; 2014 switch (o = p->n_op) { 2015 case EQ: 2016 case NE: 2017 /* 2018 * Remove redundant EQ/NE nodes. 2019 */ 2020 while (((o = p->n_left->n_op) == EQ || o == NE) && 2021 p->n_right->n_op == ICON) { 2022 o = p->n_op; 2023 q = p->n_left; 2024 if (p->n_right->n_lval == 0) { 2025 nfree(p->n_right); 2026 *p = *q; 2027 nfree(q); 2028 if (o == EQ) 2029 p->n_op = negrel[p->n_op - EQ]; 2030#if 0 2031 p->n_op = NE; /* toggla */ 2032#endif 2033 } else if (p->n_right->n_lval == 1) { 2034 nfree(p->n_right); 2035 *p = *q; 2036 nfree(q); 2037 if (o == NE) 2038 p->n_op = negrel[p->n_op - EQ]; 2039#if 0 2040 p->n_op = EQ; /* toggla */ 2041#endif 2042 } else 2043 break; /* XXX - should always be false */ 2044 2045 } 2046 /* FALLTHROUGH */ 2047 case LE: 2048 case LT: 2049 case GE: 2050 case GT: 2051calc: if (true < 0) { 2052 p->n_op = negrel[p->n_op - EQ]; 2053 true = false; 2054 false = -1; 2055 } 2056 2057 rmcops(p->n_left); 2058 rmcops(p->n_right); 2059 fixbranch(p, true); 2060 if (false >= 0) 2061 branch(false); 2062 break; 2063 2064 case ULE: 2065 case UGT: 2066 /* Convert to friendlier ops */ 2067 if (nncon(p->n_right) && p->n_right->n_lval == 0) 2068 p->n_op = o == ULE ? EQ : NE; 2069 goto calc; 2070 2071 case UGE: 2072 case ULT: 2073 /* Already true/false by definition */ 2074 if (nncon(p->n_right) && p->n_right->n_lval == 0) { 2075 if (true < 0) { 2076 o = o == ULT ? UGE : ULT; 2077 true = false; 2078 } 2079 rmcops(p->n_left); 2080 ecode(p->n_left); 2081 rmcops(p->n_right); 2082 ecode(p->n_right); 2083 nfree(p); 2084 if (o == UGE) /* true */ 2085 branch(true); 2086 break; 2087 } 2088 goto calc; 2089 2090 case ANDAND: 2091 lab = false<0 ? getlab() : false ; 2092 andorbr(p->n_left, -1, lab); 2093 comops(p->n_right); 2094 andorbr(p->n_right, true, false); 2095 if (false < 0) 2096 plabel( lab); 2097 nfree(p); 2098 break; 2099 2100 case OROR: 2101 lab = true<0 ? getlab() : true; 2102 andorbr(p->n_left, lab, -1); 2103 comops(p->n_right); 2104 andorbr(p->n_right, true, false); 2105 if (true < 0) 2106 plabel( lab); 2107 nfree(p); 2108 break; 2109 2110 case NOT: 2111 andorbr(p->n_left, false, true); 2112 nfree(p); 2113 break; 2114 2115 default: 2116 rmcops(p); 2117 if (true >= 0) 2118 fixbranch(p, true); 2119 if (false >= 0) { 2120 if (true >= 0) 2121 branch(false); 2122 else 2123 fixbranch(buildtree(EQ, p, bcon(0)), false); 2124 } 2125 } 2126} 2127 2128/* 2129 * Create a node for either TEMP or on-stack storage. 2130 */ 2131NODE * 2132cstknode(TWORD t, union dimfun *df, struct attr *ap) 2133{ 2134 struct symtab *sp; 2135 2136 /* create a symtab entry suitable for this type */ 2137 sp = getsymtab("0hej", STEMP); 2138 sp->stype = t; 2139 sp->sdf = df; 2140 sp->sap = ap; 2141 sp->sclass = AUTO; 2142 sp->soffset = NOOFFSET; 2143 oalloc(sp, &autooff); 2144 return nametree(sp); 2145 2146} 2147 2148/* 2149 * Massage the output trees to remove C-specific nodes: 2150 * COMOPs are split into separate statements. 2151 * QUEST/COLON are rewritten to branches. 2152 * ANDAND/OROR/NOT are rewritten to branches for lazy-evaluation. 2153 * CBRANCH conditions are rewritten for lazy-evaluation. 2154 */ 2155static void 2156rmcops(NODE *p) 2157{ 2158 TWORD type; 2159 NODE *q, *r, *tval; 2160 int o, ty, lbl, lbl2; 2161 2162 tval = NIL; 2163 o = p->n_op; 2164 ty = coptype(o); 2165 if (BTYPE(p->n_type) == ENUMTY) { /* fixup enum */ 2166 struct symtab *sp = strmemb(p->n_ap); 2167 MODTYPE(p->n_type, sp->stype); 2168 /* 2169 * XXX may fail if these are true: 2170 * - variable-sized enums 2171 * - non-byte-addressed targets. 2172 */ 2173 if (BTYPE(p->n_type) == ENUMTY && ISPTR(p->n_type)) 2174 MODTYPE(p->n_type, INT); /* INT ok? */ 2175 } 2176 switch (o) { 2177 case QUEST: 2178 2179 /* 2180 * Create a branch node from ?: 2181 * || and && must be taken special care of. 2182 */ 2183 type = p->n_type; 2184 andorbr(p->n_left, -1, lbl = getlab()); 2185 2186 /* Make ASSIGN node */ 2187 /* Only if type is not void */ 2188 q = p->n_right->n_left; 2189 comops(q); 2190 if (type != VOID) { 2191 tval = cstknode(q->n_type, q->n_df, q->n_ap); 2192 q = buildtree(ASSIGN, ccopy(tval), q); 2193 } 2194 rmcops(q); 2195 ecode(q); /* Done with assign */ 2196 branch(lbl2 = getlab()); 2197 plabel( lbl); 2198 2199 q = p->n_right->n_right; 2200 comops(q); 2201 if (type != VOID) { 2202 q = buildtree(ASSIGN, ccopy(tval), q); 2203 } 2204 rmcops(q); 2205 ecode(q); /* Done with assign */ 2206 2207 plabel( lbl2); 2208 2209 nfree(p->n_right); 2210 if (p->n_type != VOID) { 2211 *p = *tval; 2212 nfree(tval); 2213 } else { 2214 p->n_op = ICON; 2215 p->n_lval = 0; 2216 p->n_sp = NULL; 2217 } 2218 break; 2219 2220 case ULE: 2221 case ULT: 2222 case UGE: 2223 case UGT: 2224 case EQ: 2225 case NE: 2226 case LE: 2227 case LT: 2228 case GE: 2229 case GT: 2230 case ANDAND: 2231 case OROR: 2232 case NOT: 2233#ifdef SPECIAL_CCODES 2234#error fix for private CCODES handling 2235#else 2236 r = talloc(); 2237 *r = *p; 2238 andorbr(r, -1, lbl = getlab()); 2239 2240 tval = cstknode(p->n_type, p->n_df, p->n_ap); 2241 2242 ecode(buildtree(ASSIGN, ccopy(tval), bcon(1))); 2243 branch(lbl2 = getlab()); 2244 plabel( lbl); 2245 ecode(buildtree(ASSIGN, ccopy(tval), bcon(0))); 2246 plabel( lbl2); 2247 2248 *p = *tval; 2249 nfree(tval); 2250 2251#endif 2252 break; 2253 case CBRANCH: 2254 andorbr(p->n_left, p->n_right->n_lval, -1); 2255 nfree(p->n_right); 2256 p->n_op = ICON; p->n_type = VOID; 2257 break; 2258 case COMOP: 2259 cerror("COMOP error"); 2260 2261 default: 2262 if (ty == LTYPE) 2263 return; 2264 rmcops(p->n_left); 2265 if (ty == BITYPE) 2266 rmcops(p->n_right); 2267 } 2268} 2269 2270/* 2271 * Return 1 if an assignment is found. 2272 */ 2273static int 2274has_se(NODE *p) 2275{ 2276 if (cdope(p->n_op) & ASGFLG) 2277 return 1; 2278 if (coptype(p->n_op) == LTYPE) 2279 return 0; 2280 if (has_se(p->n_left)) 2281 return 1; 2282 if (coptype(p->n_op) == BITYPE) 2283 return has_se(p->n_right); 2284 return 0; 2285} 2286 2287/* 2288 * Find and convert asgop's to separate statements. 2289 * Be careful about side effects. 2290 * assign tells whether ASSIGN should be considered giving 2291 * side effects or not. 2292 */ 2293static NODE * 2294delasgop(NODE *p) 2295{ 2296 NODE *q, *r; 2297 int tval; 2298 2299 if (p->n_op == INCR || p->n_op == DECR) { 2300 /* 2301 * Rewrite x++ to (x += 1) -1; and deal with it further down. 2302 * Pass2 will remove -1 if unnecessary. 2303 */ 2304 q = ccopy(p); 2305 tfree(p->n_left); 2306 q->n_op = (p->n_op==INCR)?PLUSEQ:MINUSEQ; 2307 p->n_op = (p->n_op==INCR)?MINUS:PLUS; 2308 p->n_left = delasgop(q); 2309 2310 } else if ((cdope(p->n_op)&ASGOPFLG) && 2311 p->n_op != RETURN && p->n_op != CAST) { 2312 NODE *l = p->n_left; 2313 NODE *ll = l->n_left; 2314 2315 if (has_se(l)) { 2316 q = tempnode(0, ll->n_type, ll->n_df, ll->n_ap); 2317 tval = regno(q); 2318 r = tempnode(tval, ll->n_type, ll->n_df,ll->n_ap); 2319 l->n_left = q; 2320 /* Now the left side of node p has no side effects. */ 2321 /* side effects on the right side must be obeyed */ 2322 p = delasgop(p); 2323 2324 r = buildtree(ASSIGN, r, ll); 2325 r = delasgop(r); 2326 ecode(r); 2327 } else { 2328#if 0 /* Cannot call buildtree() here, it would invoke double add shifts */ 2329 p->n_right = buildtree(UNASG p->n_op, ccopy(l), 2330 p->n_right); 2331#else 2332 p->n_right = block(UNASG p->n_op, ccopy(l), 2333 p->n_right, p->n_type, p->n_df, p->n_ap); 2334#endif 2335 p->n_op = ASSIGN; 2336 p->n_right = delasgop(p->n_right); 2337 p->n_right = clocal(p->n_right); 2338 } 2339 2340 } else { 2341 if (coptype(p->n_op) == LTYPE) 2342 return p; 2343 p->n_left = delasgop(p->n_left); 2344 if (coptype(p->n_op) == BITYPE) 2345 p->n_right = delasgop(p->n_right); 2346 } 2347 return p; 2348} 2349 2350#ifndef FIELDOPS 2351 2352/* avoid promotion to int */ 2353#define TYPMOD(o, p, n, t) clocal(block(o, p, n, t, 0, 0)) 2354#define TYPLS(p, n, t) TYPMOD(LS, p, n, t) 2355#define TYPRS(p, n, t) TYPMOD(RS, p, n, t) 2356#define TYPOR(p, q, t) TYPMOD(OR, p, q, t) 2357#define TYPAND(p, q, t) TYPMOD(AND, p, q, t) 2358 2359/* 2360 * Read an unaligned bitfield from position pointed to by p starting at 2361 * off and size fsz and return a tree of type t with resulting data. 2362 */ 2363static NODE * 2364rdualfld(NODE *p, TWORD t, TWORD ct, int off, int fsz) 2365{ 2366 int t2f, inbits, tsz, ctsz; 2367 NODE *q, *r; 2368 2369 ct = ENUNSIGN(ct); 2370 ctsz = (int)tsize(ct, 0, 0); 2371 2372 /* traverse until first data byte */ 2373 for (t2f = 0; off > ctsz; t2f++, off -= ctsz) 2374 ; 2375#ifdef UNALIGNED_ACCESS 2376 /* try to squeeze it into an int */ 2377 if (off + fsz > ctsz && off + fsz <= SZINT) { 2378 ct = UNSIGNED; 2379 ctsz = SZINT; 2380 } 2381#endif 2382 p = makety(p, PTR|ct, 0, 0, 0); 2383 if (off + fsz <= ctsz) { 2384 /* only one operation needed */ 2385 q = buildtree(UMUL, buildtree(PLUS, p, bcon(t2f)), 0); 2386 if (!ISUNSIGNED(t)) { 2387 ct = DEUNSIGN(ct); 2388 q = makety(q, ct, 0, 0, 0); 2389 } 2390 q = TYPLS(q, bcon(ctsz-fsz-off), ct); 2391 q = TYPRS(q, bcon(ctsz-fsz), ct); 2392 q = makety(q, t, 0, 0, 0); 2393 } else { 2394 q = buildtree(UMUL, buildtree(PLUS, ccopy(p), bcon(t2f)), 0); 2395 q = makety(TYPRS(q, bcon(off), ct), t, 0, 0, 0); 2396 inbits = ctsz - off; 2397 t2f++; 2398 2399 while (fsz > inbits) { 2400 r = buildtree(UMUL, 2401 buildtree(PLUS, ccopy(p), bcon(t2f)), 0); 2402 r = makety(r, t, 0, 0, 0); 2403 r = TYPLS(r, bcon(inbits), t); 2404 q = TYPOR(q, r, t); 2405 inbits += ctsz; 2406 t2f++; 2407 } 2408 /* sign/zero extend XXX - RS must sign extend */ 2409 tsz = (int)tsize(t, 0, 0); 2410 if (!ISUNSIGNED(t)) { 2411 t = DEUNSIGN(t); 2412 q = makety(q, t, 0, 0, 0); 2413 } 2414 q = TYPLS(q, bcon(tsz-fsz), t); 2415 q = TYPRS(q, bcon(tsz-fsz), t); 2416 tfree(p); 2417 } 2418 2419 return q; 2420} 2421 2422/* 2423 * Write val to a (unaligned) bitfield with length fsz positioned off bits 2424 * from d. Bitfield type is t, and type to use when writing is ct. 2425 * neither f nor d should have any side effects if copied. 2426 * Multiples of ct are supposed to be written without problems. 2427 * Both val and d are free'd after use. 2428 */ 2429static NODE * 2430wrualfld(NODE *val, NODE *d, TWORD t, TWORD ct, int off, int fsz) 2431{ 2432 NODE *p, *q, *r, *rn, *s; 2433 int tsz, ctsz, t2f, inbits; 2434 2435 tsz = (int)tsize(t, 0, 0); 2436 ctsz = (int)tsize(ct, 0, 0); 2437 2438 ct = ENUNSIGN(ct); 2439 d = makety(d, PTR|ct, 0, 0, 0); 2440 2441 for (t2f = 0; off > ctsz; t2f++, off -= ctsz) 2442 ; 2443 2444 if (off + fsz <= ctsz) { 2445 r = tempnode(0, ct, 0, 0); 2446 2447 /* only one operation needed */ 2448 d = buildtree(UMUL, buildtree(PLUS, d, bcon(t2f)), 0); 2449 p = ccopy(d); 2450 p = TYPAND(p, xbcon(~(SZMASK(fsz) << off), 0, ct), ct); 2451 2452 val = makety(val, ct, 0, 0, 0); 2453 q = TYPAND(val, xbcon(SZMASK(fsz), 0, ct), ct); 2454 q = buildtree(ASSIGN, ccopy(r), q); 2455 2456 q = TYPLS(q, bcon(off), ct); 2457 p = TYPOR(p, q, ct); 2458 p = makety(p, t, 0, 0, 0); 2459 rn = buildtree(ASSIGN, d, p); 2460 rn = buildtree(COMOP, rn, makety(r, t, 0, 0, 0)); 2461 } else { 2462 s = makety(ccopy(val), t, 0, 0, 0); 2463 s = TYPAND(s, xbcon(SZMASK(fsz), 0, t), t); 2464 2465 r = buildtree(UMUL, buildtree(PLUS, ccopy(d), bcon(t2f)), 0); 2466 p = ccopy(r); 2467 p = TYPAND(p, xbcon(SZMASK(off), 0, ct), ct); 2468 q = ccopy(val); 2469 q = TYPLS(q, bcon(off), t); 2470 q = makety(q, ct, 0, 0, 0); 2471 p = TYPOR(p, q, ct); 2472 rn = buildtree(ASSIGN, r, p); 2473 inbits = ctsz - off; 2474 t2f++; 2475 2476 while (fsz > inbits+ctsz) { 2477 r = buildtree(UMUL, 2478 buildtree(PLUS, ccopy(d), bcon(t2f)), 0); 2479 q = ccopy(val); 2480 q = TYPRS(q, bcon(inbits), t); 2481 q = makety(q, ct, 0, 0, 0); 2482 rn = buildtree(COMOP, rn, buildtree(ASSIGN, r, q)); 2483 t2f++; 2484 inbits += ctsz; 2485 } 2486 2487 r = buildtree(UMUL, buildtree(PLUS, d, bcon(t2f)), 0); 2488 p = ccopy(r); 2489 p = TYPAND(p, makety(xbcon(~SZMASK(fsz-inbits), 0, ct), 2490 ct, 0, 0, 0), ct); 2491 q = TYPRS(val, bcon(inbits), t); 2492 q = TYPAND(q, xbcon(SZMASK(fsz-inbits), 0, t), t); 2493 q = makety(q, ct, 0, 0, 0); 2494 p = TYPOR(p, q, ct); 2495 rn = buildtree(COMOP, rn, buildtree(ASSIGN, r, p)); 2496 rn = buildtree(COMOP, rn, s); 2497 } 2498 return rn; 2499} 2500 2501/* 2502 * Rewrite bitfield operations to shifts. 2503 */ 2504static NODE * 2505rmfldops(NODE *p) 2506{ 2507 CONSZ msk; 2508 TWORD t, ct; 2509 NODE *q, *r, *t1, *t2, *bt, *t3, *t4; 2510 int fsz, foff, tsz; 2511 2512 if (p->n_op == FLD) { 2513 /* Rewrite a field read operation */ 2514 fsz = UPKFSZ(p->n_rval); 2515 foff = UPKFOFF(p->n_rval); 2516 tsz = (int)tsize(p->n_left->n_type, 0, 0); 2517 q = buildtree(ADDROF, p->n_left, NIL); 2518 2519 ct = t = p->n_type; 2520 if (attr_find(p->n_ap, GCC_ATYP_PACKED) && 2521 coptype(q->n_op) != LTYPE) { 2522 t1 = tempnode(0, q->n_type, 0, 0); 2523 bt = buildtree(ASSIGN, ccopy(t1), q); 2524 q = t1; 2525#ifndef UNALIGNED_ACCESS 2526 ct = UCHAR; 2527#endif 2528 } else 2529 bt = bcon(0); 2530 q = rdualfld(q, t, ct, foff, fsz); 2531 p->n_left = bt; 2532 p->n_right = q; 2533 p->n_op = COMOP; 2534 } else if (((cdope(p->n_op)&ASGOPFLG) || p->n_op == ASSIGN || 2535 p->n_op == INCR || p->n_op == DECR) && p->n_left->n_op == FLD) { 2536 /* 2537 * Rewrite a field write operation 2538 * More difficult than a read op since we must care 2539 * about side effects. 2540 */ 2541 q = p->n_left; 2542 fsz = UPKFSZ(q->n_rval); 2543 foff = UPKFOFF(q->n_rval); 2544 t = q->n_left->n_type; 2545 tsz = (int)tsize(t, 0, 0); 2546#if TARGET_ENDIAN == TARGET_BE 2547 foff = tsz - fsz - foff; 2548#endif 2549 msk = (((1LL << (fsz-1))-1) << 1) | 1; 2550 bt = NULL; 2551 if (p->n_right->n_op != ICON && p->n_right->n_op != NAME) { 2552 t2 = tempnode(0, p->n_right->n_type, 0, 0); 2553 bt = buildtree(ASSIGN, ccopy(t2), p->n_right); 2554 } else 2555 t2 = p->n_right; 2556 2557 ct = t; 2558#ifndef UNALIGNED_ACCESS 2559 if (attr_find(q->n_ap, GCC_ATYP_PACKED)) 2560 ct = UCHAR; 2561#endif 2562 /* t2 is what we have to write (RHS of ASSIGN) */ 2563 /* bt is (eventually) something that must be written */ 2564 2565 2566 if (q->n_left->n_op == UMUL) { 2567 /* LHS of assignment may have side effects */ 2568 q = q->n_left; 2569 t1 = tempnode(0, q->n_left->n_type, 0, 0); 2570 r = buildtree(ASSIGN, ccopy(t1), q->n_left); 2571 2572 bt = bt ? block(COMOP, bt, r, INT, 0, 0) : r; 2573 q->n_left = t1; 2574 } 2575 t1 = buildtree(ADDROF, p->n_left->n_left, 0); 2576 2577 /* t1 is lval where to write (and read) */ 2578 2579 if (p->n_op == ASSIGN) { 2580 q = wrualfld(t2, t1, t, ct, foff, fsz); 2581 if (bt) 2582 q = block(COMOP, bt, q, t, 0, 0); 2583 nfree(p->n_left); 2584 p->n_left = bcon(0); 2585 p->n_right = q; 2586 p->n_op = COMOP; 2587 } else if ((cdope(p->n_op)&ASGOPFLG)) { 2588 /* And here is the asgop-specific code */ 2589 t3 = tempnode(0, t, 0, 0); 2590 q = rdualfld(ccopy(t1), t, ct, foff, fsz); 2591 q = buildtree(UNASG p->n_op, q, t2); 2592 q = buildtree(ASSIGN, ccopy(t3), q); 2593 r = wrualfld(ccopy(t3), t1, t, ct, foff, fsz); 2594 q = buildtree(COMOP, q, r); 2595 q = buildtree(COMOP, q, t3); 2596 2597 nfree(p->n_left); 2598 p->n_left = bt ? bt : bcon(0); 2599 p->n_right = q; 2600 p->n_op = COMOP; 2601 } else { 2602 t3 = tempnode(0, t, 0, 0); 2603 t4 = tempnode(0, t, 0, 0); 2604 2605 q = rdualfld(ccopy(t1), t, ct, foff, fsz); 2606 q = buildtree(ASSIGN, ccopy(t3), q); 2607 r = buildtree(p->n_op==INCR?PLUS:MINUS, ccopy(t3), t2); 2608 r = buildtree(ASSIGN, ccopy(t4), r); 2609 q = buildtree(COMOP, q, r); 2610 r = wrualfld(t4, t1, t, ct, foff, fsz); 2611 q = buildtree(COMOP, q, r); 2612 2613 if (bt) 2614 q = block(COMOP, bt, q, t, 0, 0); 2615 nfree(p->n_left); 2616 p->n_left = q; 2617 p->n_right = t3; 2618 p->n_op = COMOP; 2619 } 2620 } 2621 if (coptype(p->n_op) != LTYPE) 2622 p->n_left = rmfldops(p->n_left); 2623 if (coptype(p->n_op) == BITYPE) 2624 p->n_right = rmfldops(p->n_right); 2625 return p; 2626} 2627#endif 2628 2629void 2630ecomp(NODE *p) 2631{ 2632 2633#ifdef PCC_DEBUG 2634 if (edebug) 2635 fwalk(p, eprint, 0); 2636#endif 2637 if (!reached) { 2638 warner(Wunreachable_code, NULL); 2639 reached = 1; 2640 } 2641 p = optim(p); 2642#ifndef FIELDOPS 2643 p = rmfldops(p); 2644#endif 2645 comops(p); 2646 rmcops(p); 2647 p = delasgop(p); 2648 if (p->n_op == ICON && p->n_type == VOID) 2649 tfree(p); 2650 else 2651 ecode(p); 2652} 2653 2654 2655#if defined(MULTIPASS) 2656void 2657p2tree(NODE *p) 2658{ 2659 struct symtab *q; 2660 int ty; 2661 2662 myp2tree(p); /* local action can be taken here */ 2663 2664 ty = coptype(p->n_op); 2665 2666 printf("%d\t", p->n_op); 2667 2668 if (ty == LTYPE) { 2669 printf(CONFMT, p->n_lval); 2670 printf("\t"); 2671 } 2672 if (ty != BITYPE) { 2673 if (p->n_op == NAME || p->n_op == ICON) 2674 printf("0\t"); 2675 else 2676 printf("%d\t", p->n_rval); 2677 } 2678 2679 printf("%o\t", p->n_type); 2680 2681 /* handle special cases */ 2682 2683 switch (p->n_op) { 2684 2685 case NAME: 2686 case ICON: 2687 /* print external name */ 2688 if ((q = p->n_sp) != NULL) { 2689 if ((q->sclass == STATIC && q->slevel > 0)) { 2690 printf(LABFMT, q->soffset); 2691 } else 2692 printf("%s\n", 2693 q->soname ? q->soname : exname(q->sname)); 2694 } else 2695 printf("\n"); 2696 break; 2697 2698 case STARG: 2699 case STASG: 2700 case STCALL: 2701 case USTCALL: 2702 /* print out size */ 2703 /* use lhs size, in order to avoid hassles 2704 * with the structure `.' operator 2705 */ 2706 2707 /* note: p->left not a field... */ 2708 printf(CONFMT, (CONSZ)tsize(STRTY, p->n_left->n_df, 2709 p->n_left->n_ap)); 2710 printf("\t%d\t\n", talign(STRTY, p->n_left->n_ap)); 2711 break; 2712 2713 case XARG: 2714 case XASM: 2715 break; 2716 2717 default: 2718 printf( "\n" ); 2719 } 2720 2721 if (ty != LTYPE) 2722 p2tree(p->n_left); 2723 if (ty == BITYPE) 2724 p2tree(p->n_right); 2725} 2726#else 2727static char * 2728sptostr(struct symtab *sp) 2729{ 2730 char *cp = inlalloc(32); 2731 int n = sp->soffset; 2732 if (n < 0) 2733 n = -n; 2734 snprintf(cp, 32, LABFMT, n); 2735 return cp; 2736} 2737 2738void 2739p2tree(NODE *p) 2740{ 2741 struct symtab *q; 2742 int ty; 2743 2744 myp2tree(p); /* local action can be taken here */ 2745 2746 /* Fix left imaginary types */ 2747 if (ISITY(BTYPE(p->n_type))) 2748 MODTYPE(p->n_type, p->n_type - (FIMAG-FLOAT)); 2749 2750 ty = coptype(p->n_op); 2751 2752 switch( p->n_op ){ 2753 2754 case NAME: 2755 case ICON: 2756 if ((q = p->n_sp) != NULL) { 2757 if ((q->sclass == STATIC && q->slevel > 0) 2758#ifdef GCC_COMPAT 2759 || q->sflags == SLBLNAME 2760#endif 2761 ) { 2762 p->n_name = sptostr(q); 2763 } else { 2764 if ((p->n_name = q->soname) == NULL) 2765 p->n_name = addname(exname(q->sname)); 2766 } 2767 } else 2768 p->n_name = ""; 2769 break; 2770 2771 case STASG: 2772 /* STASG used for stack array init */ 2773 if (ISARY(p->n_type)) { 2774 int size1 = (int)tsize(p->n_type, p->n_left->n_df, 2775 p->n_left->n_ap)/SZCHAR; 2776 p->n_stsize = (int)tsize(p->n_type, p->n_right->n_df, 2777 p->n_right->n_ap)/SZCHAR; 2778 if (size1 < p->n_stsize) 2779 p->n_stsize = size1; 2780 p->n_stalign = talign(p->n_type, 2781 p->n_left->n_ap)/SZCHAR; 2782 break; 2783 } 2784 /* FALLTHROUGH */ 2785 case STARG: 2786 case STCALL: 2787 case USTCALL: 2788 /* set up size parameters */ 2789 p->n_stsize = (int)((tsize(STRTY, p->n_left->n_df, 2790 p->n_left->n_ap)+SZCHAR-1)/SZCHAR); 2791 p->n_stalign = talign(STRTY,p->n_left->n_ap)/SZCHAR; 2792 if (p->n_stalign == 0) 2793 p->n_stalign = 1; /* At least char for packed structs */ 2794 break; 2795 2796 case XARG: 2797 case XASM: 2798 break; 2799 2800 default: 2801 p->n_name = ""; 2802 } 2803 2804 if( ty != LTYPE ) p2tree( p->n_left ); 2805 if( ty == BITYPE ) p2tree( p->n_right ); 2806 } 2807 2808#endif 2809 2810/* 2811 * Change void data types into char. 2812 */ 2813static void 2814delvoid(NODE *p, void *arg) 2815{ 2816 /* Convert "PTR undef" (void *) to "PTR uchar" */ 2817 if (BTYPE(p->n_type) == VOID) 2818 p->n_type = (p->n_type & ~BTMASK) | UCHAR; 2819 if (BTYPE(p->n_type) == BOOL) { 2820 if (p->n_op == SCONV && p->n_type == BOOL) { 2821 /* create a jump and a set */ 2822 NODE *r; 2823 int l, l2; 2824 2825 r = tempnode(0, BOOL_TYPE, NULL, 0); 2826 cbranch(buildtree(EQ, p->n_left, bcon(0)), 2827 bcon(l = getlab())); 2828 *p = *r; 2829 ecode(buildtree(ASSIGN, tcopy(r), bcon(1))); 2830 branch(l2 = getlab()); 2831 plabel(l); 2832 ecode(buildtree(ASSIGN, r, bcon(0))); 2833 plabel(l2); 2834 } else 2835 p->n_type = (p->n_type & ~BTMASK) | BOOL_TYPE; 2836 } 2837 2838} 2839 2840/* 2841 * Change calls inside calls to separate statement. 2842 */ 2843static NODE * 2844deldcall(NODE *p, int split) 2845{ 2846 NODE *q, *r; 2847 int o = p->n_op; 2848 2849 if (cdope(o) & CALLFLG) { 2850 if (split) { 2851 q = cstknode(p->n_type, p->n_df, p->n_ap); 2852 r = ccopy(q); 2853 q = block(ASSIGN, q, p, p->n_type, p->n_df, p->n_ap); 2854 ecode(q); 2855 return r; 2856 } 2857 split++; 2858 } 2859 if (coptype(o) == BITYPE) 2860 p->n_right = deldcall(p->n_right, split); 2861 if (coptype(o) != LTYPE) 2862 p->n_left = deldcall(p->n_left, split); 2863 return p; 2864} 2865 2866#ifndef WORD_ADDRESSED 2867 2868static NODE * 2869pprop(NODE *p, TWORD t, struct attr *ap) 2870{ 2871 int o = p->n_op; 2872 TWORD t2; 2873 2874#ifdef PCC_DEBUG 2875 if (p->n_op == TEMP && p->n_type != t && 2876 !(ISPTR(p->n_type) && ISPTR(t))) { 2877 cerror("TEMP type change: %x -> %x", p->n_type, t); 2878 } 2879#endif 2880 2881 p->n_type = t; 2882 p->n_ap = ap; 2883 switch (o) { 2884 case UMUL: 2885 t = INCREF(t); 2886 break; 2887 case ADDROF: 2888 t2 = p->n_left->n_type; 2889 if (p->n_left->n_op == TEMP) { 2890 /* Will be converted to memory in pass2 */ 2891 if (!ISPTR(t2) && DECREF(t) != t2) 2892 ; /* XXX cannot convert this */ 2893 else 2894 p->n_left->n_type = DECREF(t); 2895 return p; 2896 } 2897 if (ISPTR(t2) && !ISPTR(DECREF(t))) 2898 break; /* not quite correct */ 2899 t = DECREF(t); 2900 break; 2901 case PCONV: 2902 return p; 2903 2904 case PLUSEQ: 2905 case PLUS: 2906 case INCR: 2907 case DECR: 2908 if (!ISPTR(p->n_left->n_type)) { 2909 if (!ISPTR(p->n_right->n_type)) 2910 cerror("no * in PLUS"); 2911 p->n_right = pprop(p->n_right, t, ap); 2912 } else 2913 p->n_left = pprop(p->n_left, t, ap); 2914 return p; 2915 2916 case MINUSEQ: 2917 case MINUS: 2918 if (ISPTR(p->n_left->n_type)) { 2919 if (ISPTR(p->n_right->n_type)) 2920 break; /* change both */ 2921 p->n_left = pprop(p->n_left, t, ap); 2922 } else 2923 p->n_right = pprop(p->n_right, t, ap); 2924 return p; 2925 2926 case CALL: 2927 case UCALL: 2928 case STCALL: /* may end up here if struct passed in regs */ 2929 case USTCALL: 2930 return p; 2931 2932 case STASG: /* if struct is cast to pointer */ 2933 return p; 2934 2935 case ASSIGN: 2936 break; 2937 2938 default: 2939 if (coptype(o) == LTYPE) 2940 break; 2941 2942fwalk(p, eprint, 0); 2943 cerror("pprop op error %d\n", o); 2944 } 2945 if (coptype(o) == BITYPE) 2946 p->n_right = pprop(p->n_right, t, ap); 2947 if (coptype(o) != LTYPE) 2948 p->n_left = pprop(p->n_left, t, ap); 2949 return p; 2950} 2951 2952/* 2953 * Search for PCONV's that can be removed while still keeping 2954 * the type correctness. 2955 */ 2956NODE * 2957rmpconv(NODE *p) 2958{ 2959 struct symtab *sp; 2960 int o = p->n_op; 2961 int ot = coptype(o); 2962 NODE *q, *l; 2963 2964 if (ot != LTYPE) 2965 p->n_left = rmpconv(p->n_left); 2966 if (ot == BITYPE) 2967 p->n_right = rmpconv(p->n_right); 2968 if (o != PCONV) 2969 return p; 2970 l = p->n_left; 2971 if (nncon(l) || (cdope(l->n_op) & CALLFLG)) 2972 ; /* Let any nonamed constant be cast to pointer directly */ 2973 else if (l->n_type >= INTPTR && l->n_op == ICON) { 2974 /* named constants only if >= pointer size */ 2975 /* create INTPTR type */ 2976 sp = l->n_sp; 2977 l->n_sp = NULL; 2978 concast(l, INTPTR); 2979 l->n_sp = sp; 2980 } else if (!ISPTR(l->n_type)) 2981 return p; 2982 q = pprop(p->n_left, p->n_type, p->n_ap); 2983 nfree(p); 2984 return q; 2985} 2986#endif 2987 2988void 2989ecode(NODE *p) 2990{ 2991 /* walk the tree and write out the nodes.. */ 2992 2993 if (nerrors) 2994 return; 2995 2996#ifdef GCC_COMPAT 2997 { 2998 NODE *q = p; 2999 3000 if (q->n_op == UMUL) 3001 q = p->n_left; 3002 if (cdope(q->n_op)&CALLFLG && 3003 attr_find(q->n_ap, GCC_ATYP_WARN_UNUSED_RESULT)) 3004 werror("return value ignored"); 3005 } 3006#endif 3007#ifndef WORD_ADDRESSED 3008 p = rmpconv(p); 3009#endif 3010 p = optim(p); 3011 p = delasgop(p); 3012 p = deldcall(p, 0); 3013 walkf(p, delvoid, 0); 3014#ifdef PCC_DEBUG 3015 if (xdebug) { 3016 printf("Fulltree:\n"); 3017 fwalk(p, eprint, 0); 3018 } 3019#endif 3020 p2tree(p); 3021#if !defined(MULTIPASS) 3022 send_passt(IP_NODE, p); 3023#endif 3024} 3025 3026/* 3027 * Send something further on to the next pass. 3028 */ 3029void 3030send_passt(int type, ...) 3031{ 3032 struct interpass *ip; 3033 struct interpass_prolog *ipp; 3034 extern int crslab; 3035 va_list ap; 3036 int sz; 3037 3038 va_start(ap, type); 3039 if (cftnsp == NULL && type != IP_ASM) { 3040#ifdef notyet 3041 cerror("no function"); 3042#endif 3043 if (type == IP_NODE) 3044 tfree(va_arg(ap, NODE *)); 3045 return; 3046 } 3047 if (type == IP_PROLOG || type == IP_EPILOG) 3048 sz = sizeof(struct interpass_prolog); 3049 else 3050 sz = sizeof(struct interpass); 3051 3052 ip = inlalloc(sz); 3053 ip->type = type; 3054 ip->lineno = lineno; 3055 switch (type) { 3056 case IP_NODE: 3057 ip->ip_node = va_arg(ap, NODE *); 3058 if (ip->ip_node->n_op == LABEL) { 3059 NODE *p = ip->ip_node; 3060 ip->ip_lbl = p->n_left->n_lval; 3061 ip->type = IP_DEFLAB; 3062 nfree(nfree(p)); 3063 } 3064 break; 3065 case IP_EPILOG: 3066 if (!isinlining) { 3067 locctr(PROG, cftnsp); 3068 defloc(cftnsp); 3069 } 3070 /* FALLTHROUGH */ 3071 case IP_PROLOG: 3072 inftn = type == IP_PROLOG ? 1 : 0; 3073 ipp = (struct interpass_prolog *)ip; 3074 memset(ipp->ipp_regs, (type == IP_PROLOG)? -1 : 0, 3075 sizeof(ipp->ipp_regs)); 3076 ipp->ipp_autos = va_arg(ap, int); 3077 ipp->ipp_name = va_arg(ap, char *); 3078 ipp->ipp_type = va_arg(ap, TWORD); 3079 ipp->ipp_vis = va_arg(ap, int); 3080 ip->ip_lbl = va_arg(ap, int); 3081 ipp->ip_tmpnum = va_arg(ap, int); 3082 ipp->ip_lblnum = crslab; 3083 if (type == IP_PROLOG) 3084 ipp->ip_lblnum--; 3085 break; 3086 case IP_DEFLAB: 3087 ip->ip_lbl = va_arg(ap, int); 3088 break; 3089 case IP_ASM: 3090 if (blevel == 0) { /* outside function */ 3091 printf("\t"); 3092 printf("%s", va_arg(ap, char *)); 3093 printf("\n"); 3094 va_end(ap); 3095 locctr(NOSEG, NULL); 3096 return; 3097 } 3098 ip->ip_asm = va_arg(ap, char *); 3099 break; 3100 default: 3101 cerror("bad send_passt type %d", type); 3102 } 3103 va_end(ap); 3104 pass1_lastchance(ip); /* target-specific info */ 3105 if (isinlining) 3106 inline_addarg(ip); 3107 else 3108 pass2_compile(ip); 3109} 3110 3111char * 3112copst(int op) 3113{ 3114 if (op <= MAXOP) 3115 return opst[op]; 3116#define SNAM(x,y) case x: return #y; 3117 switch (op) { 3118 SNAM(QUALIFIER,QUALIFIER) 3119 SNAM(CLASS,CLASS) 3120 SNAM(RB,]) 3121 SNAM(DOT,.) 3122 SNAM(ELLIPSIS,...) 3123 SNAM(LB,[) 3124 SNAM(TYPE,TYPE) 3125 SNAM(COMOP,COMOP) 3126 SNAM(QUEST,?) 3127 SNAM(COLON,:) 3128 SNAM(ANDAND,&&) 3129 SNAM(OROR,||) 3130 SNAM(NOT,!) 3131 SNAM(CAST,CAST) 3132 SNAM(PLUSEQ,+=) 3133 SNAM(MINUSEQ,-=) 3134 SNAM(MULEQ,*=) 3135 SNAM(DIVEQ,/=) 3136 SNAM(MODEQ,%=) 3137 SNAM(ANDEQ,&=) 3138 SNAM(OREQ,|=) 3139 SNAM(EREQ,^=) 3140 SNAM(LSEQ,<<=) 3141 SNAM(RSEQ,>>=) 3142 SNAM(INCR,++) 3143 SNAM(DECR,--) 3144 SNAM(STRING,STRING) 3145 SNAM(SZOF,SIZEOF) 3146 SNAM(ATTRIB,ATTRIBUTE) 3147 SNAM(TYMERGE,TYMERGE) 3148 SNAM(LABEL,LABEL) 3149#ifdef GCC_COMPAT 3150 SNAM(XREAL,__real__) 3151 SNAM(XIMAG,__imag__) 3152#endif 3153 default: 3154 cerror("bad copst %d", op); 3155 } 3156 return 0; /* XXX gcc */ 3157} 3158 3159int 3160cdope(int op) 3161{ 3162 if (op <= MAXOP) 3163 return dope[op]; 3164 switch (op) { 3165 case CLOP: 3166 case STRING: 3167 case QUALIFIER: 3168 case CLASS: 3169 case RB: 3170 case ELLIPSIS: 3171 case TYPE: 3172 return LTYPE; 3173 case DOT: 3174 case SZOF: 3175 case COMOP: 3176 case QUEST: 3177 case COLON: 3178 case LB: 3179 case TYMERGE: 3180 return BITYPE; 3181 case XIMAG: 3182 case XREAL: 3183 case ATTRIB: 3184 case LABEL: 3185 return UTYPE; 3186 case ANDAND: 3187 case OROR: 3188 return BITYPE|LOGFLG; 3189 case NOT: 3190 return UTYPE|LOGFLG; 3191 case CAST: 3192 return BITYPE|ASGFLG|ASGOPFLG; 3193 case PLUSEQ: 3194 return BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG; 3195 case MINUSEQ: 3196 return BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG; 3197 case MULEQ: 3198 return BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG; 3199 case OREQ: 3200 case EREQ: 3201 case ANDEQ: 3202 return BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG; 3203 case DIVEQ: 3204 return BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG; 3205 case MODEQ: 3206 return BITYPE|DIVFLG|ASGFLG|ASGOPFLG; 3207 case LSEQ: 3208 case RSEQ: 3209 return BITYPE|SHFFLG|ASGFLG|ASGOPFLG; 3210 case INCR: 3211 case DECR: 3212 return BITYPE|ASGFLG; 3213 } 3214 cerror("cdope missing op %d", op); 3215 return 0; /* XXX gcc */ 3216} 3217 3218/* 3219 * make a fresh copy of p 3220 */ 3221NODE * 3222ccopy(NODE *p) 3223{ 3224 NODE *q; 3225 3226 q = talloc(); 3227 *q = *p; 3228 3229 switch (coptype(q->n_op)) { 3230 case BITYPE: 3231 q->n_right = ccopy(p->n_right); 3232 case UTYPE: 3233 q->n_left = ccopy(p->n_left); 3234 } 3235 3236 return(q); 3237} 3238 3239NODE * 3240nlabel(int label) 3241{ 3242 return block(LABEL, bcon(label), NIL, 0, 0, 0); 3243} 3244 3245/* 3246 * set PROG-seg label. 3247 */ 3248void 3249plabel(int label) 3250{ 3251 reached = 1; /* Will this always be correct? */ 3252 send_passt(IP_NODE, nlabel(label)); 3253} 3254 3255/* 3256 * Perform integer promotion on node n. 3257 */ 3258NODE * 3259intprom(NODE *n) 3260{ 3261 if ((n->n_type >= CHAR && n->n_type < INT) || n->n_type == BOOL) { 3262 if ((n->n_type == UCHAR && MAX_UCHAR > MAX_INT) || 3263 (n->n_type == USHORT && MAX_USHORT > MAX_INT)) 3264 return makety(n, UNSIGNED, 0, 0, 0); 3265 return makety(n, INT, 0, 0, 0); 3266 } 3267 return n; 3268} 3269 3270/* 3271 * Return CON/VOL/0, whichever are active for the current type. 3272 */ 3273int 3274cqual(TWORD t, TWORD q) 3275{ 3276 while (ISARY(t)) 3277 t = DECREF(t), q = DECQAL(q); 3278 if (t <= BTMASK) 3279 q <<= TSHIFT; 3280 return q & (CON|VOL); 3281} 3282 3283int crslab = 10; 3284/* 3285 * Return a number for internal labels. 3286 */ 3287int 3288getlab(void) 3289{ 3290 return crslab++; 3291} 3292