1: // Copyright (C) 1985-1998 by Symantec
   2: // Copyright (C) 2000-2009 by Digital Mars
   3: // All Rights Reserved
   4: // http://www.digitalmars.com
   5: // Written by Walter Bright
   6: /*
   7:  * This source file is made available for personal use
   8:  * only. The license is in /dmd/src/dmd/backendlicense.txt
   9:  * or /dm/src/dmd/backendlicense.txt
  10:  * For any other uses, please contact Digital Mars.
  11:  */
  12: 
  13: /* Routines to handle elems.                    */
  14: 
  15: #if !SPP
  16: 
  17: #include        <stdio.h>
  18: #include        <string.h>
  19: #include        <time.h>
  20: #include        <stdarg.h>
  21: 
  22: #include        "cc.h"
  23: #include        "type.h"
  24: #include        "el.h"
  25: #include        "list.h"
  26: #include        "mem.h"
  27: #include        "oper.h"
  28: #include        "type.h"
  29: 
  30: #include        "code.h"
  31: 
  32: #include        "global.h"
  33: #include        "go.h"
  34: 
  35: #if SCPP
  36: #include        "parser.h"
  37: #endif
  38: 
  39: static char __file__[] = __FILE__;      /* for tassert.h                */
  40: #include        "tassert.h"
  41: 
  42: #ifdef STATS
  43: static int elfreed = 0;                 /* number of freed elems        */
  44: static int eprm_cnt;                    /* max # of allocs at any point */
  45: #endif
  46: 
  47: #if TARGET_OSX
  48: extern void slist_add(Symbol *s);
  49: #endif
  50: 
  51: /*******************************
  52:  * Do our own storage allocation of elems.
  53:  */
  54: 
  55: static elem *nextfree = NULL;           /* pointer to next free elem    */
  56: 
  57: static int elcount = 0;                 /* number of allocated elems    */
  58: static int elem_size = sizeof(elem);
  59: 
  60: #ifdef DEBUG
  61: static int elmax;                       /* max # of allocs at any point */
  62: #endif
  63: 
  64: /////////////////////////////
  65: // Table to gather redundant strings in.
  66: 
  67: static struct STAB
  68: {   symbol *sym;        // symbol that refers to the string
  69:     char *p;            // pointer to the string
  70:     int len;            // length of string p
  71: } stable[16];
  72: static int stable_si;
  73: 
  74: /************************
  75:  * Initialize el package.
  76:  */
  77: 
  78: void el_init()
  79: {
  80:     if (!configv.addlinenumbers)
  81:         elem_size = sizeof(elem) - sizeof(Srcpos);
  82: }
  83: 
  84: /*******************************
  85:  * Initialize for another run through.
  86:  */
  87: 
  88: void el_reset()
  89: {
  90:     stable_si = 0;
  91:     for (int i = 0; i < arraysize(stable); i++)
  92:         mem_free(stable[i].p);
  93:     memset(stable,0,sizeof(stable));
  94: }
  95: 
  96: #if TX86
  97: /************************
  98:  * Terminate el package.
  99:  */
 100: 
 101: void el_term()
 102: {
 103: #if TERMCODE
 104:         int i;
 105: 
 106:         for (i = 0; i < arraysize(stable); i++)
 107:             mem_free(stable[i].p);
 108: 
 109: #ifdef DEBUG
 110:         dbg_printf("Max # of elems = %d\n",elmax);
 111: #endif
 112:         if (elcount != 0)
 113:             dbg_printf("unfreed elems = %d\n",elcount);
 114:         while (nextfree)
 115:         {   elem *e;
 116: 
 117:             e = nextfree->E1;
 118:             mem_ffree(nextfree);
 119:             nextfree = e;
 120:         }
 121: #else
 122:         assert(elcount == 0);
 123: #endif
 124: }
 125: #endif
 126: 
 127: /***********************
 128:  * Allocate an element.
 129:  */
 130: 
 131: #if SCPP && __SC__ && __INTSIZE == 4 && TX86 && !_DEBUG_TRACE && !MEM_DEBUG && _WIN32 && !defined(DEBUG)
 132: 
 133: __declspec(naked) elem *el_calloc()
 134: {
 135:     __asm
 136:     {
 137:         mov     EAX,elcount
 138:         push    EDI
 139: 
 140:         inc     EAX
 141:         mov     EDI,nextfree
 142: 
 143:         test    EDI,EDI
 144:         je      L27
 145: 
 146:         mov     EDX,E1[EDI]
 147:         mov     elcount,EAX
 148: 
 149:         xor     EAX,EAX
 150:         mov     nextfree,EDX
 151:         jmp     L30
 152: 
 153: L27:    push    sizeof(elem)
 154:         mov     elcount,EAX
 155:         call    mem_fmalloc
 156:         mov     EDI,EAX
 157:         xor     EAX,EAX
 158: 
 159: L30:    mov     EDX,EDI
 160:         mov     ECX,(sizeof(elem) + 3) / 4
 161:     #if DOS386
 162:         push    DS
 163:         pop     ES
 164:     #endif
 165:         rep     stosd
 166:         mov     EAX,EDX
 167:         pop     EDI
 168:         ret
 169:     }
 170: }
 171: 
 172: #else
 173: 
 174: elem *el_calloc()
 175: {
 176:     elem *e;
 177:     static elem ezero;
 178: 
 179:     elcount++;
 180:     if (nextfree)
 181:     {   e = nextfree;
 182:         nextfree = e->E1;
 183:     }
 184:     else
 185:         e = (elem *) mem_fmalloc(sizeof(elem));
 186: #ifdef STATS
 187:     eprm_cnt++;
 188: #endif
 189:     *e = ezero;                         /* clear it             */
 190: 
 191: #ifdef DEBUG
 192:     e->id = IDelem;
 193:     if (elcount > elmax)
 194:         elmax = elcount;
 195: #endif
 196:     /*dbg_printf("el_calloc() = %p\n",e);*/
 197:     return e;
 198: }
 199: 
 200: #endif
 201: 
 202: /***************
 203:  * Free element
 204:  */
 205: 
 206: void el_free(elem *e)
 207: {
 208:     int op;
 209:     tym_t ty;
 210: 
 211: L1:
 212:     if (!e) return;
 213:     elem_debug(e);
 214:     //dbg_printf("el_free(%p)\n",e);
 215:     //elem_print(e);
 216:     if (SCPP && PARSER)
 217:     {
 218:         ty = e->ET ? e->ET->Tty : 0;
 219:         type_free(e->ET);
 220:     }
 221:     else if (e->Ecount--)
 222:         return;                         // usage count
 223:     elcount--;
 224:     op = e->Eoper;
 225:     switch (op)
 226:     {
 227:         case OPconst:
 228: #if FLOATS_IN_CODE
 229:             if (!PARSER && FLT_CODESEG_CELEM(e))
 230:                 flt_free_elem(e);
 231: #endif
 232:             break;
 233: 
 234:         case OPvar:
 235:             break;
 236:         case OPrelconst:
 237: #if SCPP
 238:             if (0 && PARSER && tybasic(ty) == TYmemptr)
 239:                 el_free(e->EV.sm.ethis);
 240: #endif
 241:             break;
 242:         case OPstring:
 243:         case OPasm:
 244:             mem_free(e->EV.ss.Vstring);
 245:             break;
 246:         default:
 247:             debug_assert(op < OPMAX);
 248:             if (!OTleaf(op))
warning C6385: Invalid data: accessing 'unsigned char const * const optab1', the readable size is '183' bytes, but '1143' bytes might be read: Lines: 208, 209, 211, 212, 216, 221, 223, 224, 225, 246, 248
249: { elem *en; 250: 251: if (OTbinary(op)) 252: el_free(e->E2); 253: en = e->E1; 254: #ifdef DEBUG 255: memset(e,0xFF,elem_size); 256: #endif 257: e->E1 = nextfree; 258: nextfree = e; 259: 260: #ifdef STATS 261: elfreed++; 262: #endif 263: e = en; 264: goto L1; 265: } 266: break; 267: } 268: #ifdef DEBUG 269: memset(e,0xFF,elem_size); 270: #endif 271: e->E1 = nextfree; 272: nextfree = e; 273: 274: #ifdef STATS 275: elfreed++; 276: #endif 277: } 278: 279: #ifdef STATS 280: /* count number of elems available on free list */ 281: void el_count_free() 282: { 283: elem *e; 284: int count; 285: 286: for(e=nextfree;e;e=e->E1) 287: count++; 288: dbg_printf("Requests for elems %d\n",elcount); 289: dbg_printf("Requests to free elems %d\n",elfreed); 290: dbg_printf("Number of elems %d\n",eprm_cnt); 291: dbg_printf("Number of elems currently on free list %d\n",count); 292: } 293: #endif 294: 295: /********************* 296: * Combine e1 and e2 with a comma-expression. 297: * Be careful about either or both being NULL. 298: */ 299: 300: elem * el_combine(elem *e1,elem *e2) 301: { 302: if (e1) 303: { if (e2) 304: e1 = (SCPP && PARSER) ? el_bint(OPcomma,e2->ET,e1,e2) 305: : el_bin(OPcomma,e2->Ety,e1,e2); 306: } 307: else 308: e1 = e2; 309: return e1; 310: } 311: 312: /********************* 313: * Combine e1 and e2 as parameters to a function. 314: * Be careful about either or both being NULL. 315: */ 316: 317: elem * el_param(elem *e1,elem *e2) 318: { 319: //printf("el_param(%p, %p)\n", e1, e2); 320: #if 0 321: if (e2 && e2->Eoper != OPstrpar && tybasic(e2->Ety) == TYstruct) 322: *(char*)0=0; 323: #endif 324: if (e1) 325: { if (e2) 326: e1 = (SCPP && PARSER) ? el_bint(OPparam,tsvoid,e1,e2) 327: : el_bin(OPparam,TYvoid,e1,e2); 328: } 329: else 330: e1 = e2; 331: return e1; 332: } 333: 334: /********************************* 335: * Create parameter list, terminated by a NULL. 336: */ 337: 338: elem *el_params(elem *e1, ...) 339: { 340: elem *e; 341: va_list ap; 342: 343: e = NULL; 344: for (va_start(ap, e1); e1; e1 = va_arg(ap, elem *)) 345: { 346: e = el_param(e, e1); 347: } 348: va_end(ap); 349: return e; 350: } 351: 352: /***************************************** 353: * Do an array of parameters as a balanced 354: * binary tree. 355: */ 356: 357: elem *el_params(void **args, int length) 358: { 359: if (length == 0) 360: return NULL; 361: if (length == 1) 362: return (elem *)args[0]; 363: int mid = length >> 1; 364: return el_param(el_params(args, mid), 365: el_params(args + mid, length - mid)); 366: } 367: 368: /***************************************** 369: * Do an array of parameters as a balanced 370: * binary tree. 371: */ 372: 373: elem *el_combines(void **args, int length) 374: { 375: if (length == 0) 376: return NULL; 377: if (length == 1) 378: return (elem *)args[0]; 379: int mid = length >> 1; 380: return el_combine(el_combines(args, mid), 381: el_combines(args + mid, length - mid)); 382: } 383: 384: /*************************************** 385: * Return a list of the parameters. 386: */ 387: 388: int el_nparams(elem *e) 389: { 390: if (e->Eoper == OPparam) 391: { 392: return el_nparams(e->E1) + el_nparams(e->E2); 393: } 394: else 395: return 1; 396: } 397: 398: /************************************* 399: * Create a quad word out of two dwords. 400: */ 401: 402: elem *el_pair(tym_t tym, elem *lo, elem *hi) 403: { 404: #if 0 405: lo = el_una(OPu32_64, TYullong, lo); 406: hi = el_una(OPu32_64, TYullong, hi); 407: hi = el_bin(OPshl, TYullong, hi, el_long(TYint, 32)); 408: return el_bin(OPor, tym, lo, hi); 409: #else 410: return el_bin(OPpair, tym, lo, hi); 411: #endif 412: } 413: 414: 415: /************************* 416: * Copy an element (not the tree!). 417: */ 418: 419: void el_copy(elem *to,elem *from) 420: { 421: assert(to && from); 422: elem_debug(from); 423: elem_debug(to); 424: memcpy(to,from,elem_size); 425: elem_debug(to); 426: } 427: 428: /*********************************** 429: * Allocate a temporary, and return temporary elem. 430: */ 431: 432: elem * el_alloctmp(tym_t ty) 433: { 434: symbol *s; 435: 436: assert(MARS || !PARSER); 437: s = symbol_generate(SCtmp,type_fake(ty)); 438: symbol_add(s); 439: s->Sfl = FLtmp; 440: s->Sflags = SFLfree | SFLunambig | GTregcand; 441: return el_var(s); 442: } 443: 444: /******************************** 445: * Select the e1 child of e. 446: */ 447: 448: elem * el_selecte1(elem *e) 449: { elem *e1; 450: 451: assert(!PARSER); 452: elem_debug(e); 453: assert(EOP(e)); 454: e1 = e->E1; 455: elem_debug(e1); 456: if (e->E2) elem_debug(e->E2); 457: e->E1 = NULL; // so e1 won't be freed
warning C4390: ';' : empty controlled statement found; is this the intent?
458: if (configv.addlinenumbers) 459: { 460: if (e->Esrcpos.Slinnum) 461: e1->Esrcpos = e->Esrcpos; 462: } 463: e1->Ety = e->Ety; 464: // if (tyaggregate(e1->Ety)) 465: // e1->Enumbytes = e->Enumbytes; 466: #if MARS 467: if (!e1->Ejty) 468: e1->Ejty = e->Ejty; 469: #endif 470: el_free(e); 471: return e1; 472: } 473: 474: /******************************** 475: * Select the e2 child of e. 476: */ 477: 478: elem * el_selecte2(elem *e) 479: { elem *e2; 480: 481: //dbg_printf("el_selecte2(%p)\n",e); 482: elem_debug(e); 483: assert(EBIN(e)); 484: if (e->E1) 485: elem_debug(e->E1); 486: e2 = e->E2;
warning C4390: ';' : empty controlled statement found; is this the intent?
487: elem_debug(e2); 488: e->E2 = NULL; // so e2 won't be freed 489: if (configv.addlinenumbers) 490: { 491: if (e->Esrcpos.Slinnum) 492: e2->Esrcpos = e->Esrcpos; 493: } 494: if (PARSER) 495: el_settype(e2,e->ET); 496: else 497: { e2->Ety = e->Ety; 498: // if (tyaggregate(e->Ety)) 499: // e2->Enumbytes = e->Enumbytes; 500: } 501: el_free(e); 502: return e2; 503: } 504: 505: /************************* 506: * Create and return a duplicate of e, including its leaves. 507: * No CSEs. 508: */ 509: 510: elem * el_copytree(elem *e) 511: { elem *d; 512: 513: if (!e) 514: return e; 515: elem_debug(e); 516: d = el_calloc(); 517: el_copy(d,e); 518: assert(!e->Ecount); 519: if (SCPP && PARSER) 520: { 521: type_debug(d->ET); 522: d->ET->Tcount++; 523: } 524: if (EOP(e)) 525: { d->E1 = el_copytree(e->E1); 526: if (EBIN(e)) 527: d->E2 = el_copytree(e->E2); 528: } 529: else 530: { 531: switch (e->Eoper) 532: { case OPstring: 533: #if 0 534: if (OPTIMIZER) 535: { 536: /* Convert the string to a static symbol and 537: then just refer to it, because two OPstrings can't 538: refer to the same string. 539: */ 540: 541: el_convstring(e); // convert string to symbol 542: d->Eoper = OPrelconst; 543: d->EV.sp.Vsym = e->EV.sp.Vsym; 544: break; 545: } 546: #endif 547: #if 0 548: case OPrelconst: 549: e->EV.sm.ethis = NULL; 550: break; 551: #endif 552: case OPasm: 553: d->EV.ss.Vstring = (char *) mem_malloc(d->EV.ss.Vstrlen); 554: memcpy(d->EV.ss.Vstring,e->EV.ss.Vstring,e->EV.ss.Vstrlen); 555: break; 556: } 557: } 558: return d; 559: } 560: 561: /************************* 562: * Similar to el_copytree(e). But if e has any side effects, it's replaced 563: * with (tmp = e) and tmp is returned. 564: */ 565: 566: elem * el_same(elem **pe) 567: { elem *e = *pe; 568: 569: if (e && el_sideeffect(e)) 570: { 571: *pe = exp2_copytotemp(e); /* convert to ((tmp=e),tmp) */ 572: e = (*pe)->E2; /* point at tmp */ 573: } 574: return el_copytree(e); 575: } 576: 577: /************************** 578: * Replace symbol s1 with s2 in tree. 579: */ 580: 581: #if SCPP 582: 583: void el_replace_sym(elem *e,symbol *s1,symbol *s2) 584: { 585: symbol_debug(s1); 586: symbol_debug(s2); 587: while (1) 588: { elem_debug(e); 589: if (EOP(e)) 590: { if (EBIN(e)) 591: el_replace_sym(e->E2,s1,s2); 592: e = e->E1; 593: } 594: else 595: { 596: switch (e->Eoper) 597: { 598: case OPvar: 599: case OPrelconst: 600: if (e->EV.sp.Vsym == s1) 601: e->EV.sp.Vsym = s2; 602: break; 603: } 604: break; 605: } 606: } 607: } 608: 609: #endif 610: 611: /************************************* 612: * Does symbol s appear in tree e? 613: * Returns: 614: * 1 yes 615: * 0 no 616: */ 617: 618: #if MARS 619: 620: int el_appears(elem *e,Symbol *s) 621: { 622: symbol_debug(s); 623: while (1) 624: { elem_debug(e); 625: if (EOP(e)) 626: { if (EBIN(e) && el_appears(e->E2,s)) 627: return 1; 628: e = e->E1; 629: } 630: else 631: { 632: switch (e->Eoper) 633: { 634: case OPvar: 635: case OPrelconst: 636: if (e->EV.sp.Vsym == s) 637: return 1; 638: break; 639: } 640: break; 641: } 642: } 643: return 0; 644: } 645: 646: /***************************************** 647: * Look for symbol that is a base of addressing mode e. 648: * Returns: 649: * s symbol used as base 650: * NULL couldn't find a base symbol 651: */ 652: 653: #if 0 654: Symbol *el_basesym(elem *e) 655: { Symbol *s; 656: 657: s = NULL; 658: while (1) 659: { elem_debug(e); 660: switch (e->Eoper) 661: { 662: case OPvar: 663: s = e->EV.sp.Vsym; 664: break; 665: case OPcomma: 666: e = e->E2; 667: continue; 668: case OPind: 669: s = el_basesym(e->E1); 670: break; 671: case OPadd: 672: s = el_basesym(e->E1); 673: if (!s) 674: s = el_basesym(e->E2); 675: break; 676: } 677: break; 678: } 679: return s; 680: } 681: #endif 682: 683: /**************************************** 684: * Does any definition of lvalue ed appear in e? 685: * Returns: 686: * 1 yes 687: * 0 no 688: */ 689: 690: int el_anydef(elem *ed, elem *e) 691: { int op; 692: int edop; 693: Symbol *s; 694: elem *e1; 695: 696: edop = ed->Eoper; 697: s = (edop == OPvar) ? ed->EV.sp.Vsym : NULL; 698: while (1) 699: { 700: op = e->Eoper; 701: if (!OTleaf(op)) 702: { 703: e1 = e->E1; 704: if (OTdef(op)) 705: { 706: if (e1->Eoper == OPvar && e1->EV.sp.Vsym == s) 707: return 1; 708: 709: // This doesn't cover all the cases 710: if (e1->Eoper == edop && el_match(e1,ed)) 711: return 1; 712: } 713: if (OTbinary(op) && el_anydef(ed,e->E2)) 714: return 1; 715: e = e1; 716: } 717: else 718: break; 719: } 720: return 0; 721: } 722: 723: #endif 724: 725: /************************ 726: * Make a binary operator node. 727: */ 728: 729: elem * el_bint(unsigned op,type *t,elem *e1,elem *e2) 730: { elem *e; 731: 732: /* e2 is NULL when OPpostinc is built */ 733: assert(op < OPMAX && OTbinary(op) && e1); 734: assert(PARSER); 735: e = el_calloc(); 736: if (t) 737: { e->ET = t; 738: type_debug(t); 739: e->ET->Tcount++; 740: } 741: e->Eoper = op; 742: elem_debug(e1); 743: if (e2) 744: elem_debug(e2); 745: e->E1 = e1;
warning C4390: ';' : empty controlled statement found; is this the intent?
746: e->E2 = e2; 747: return e; 748: } 749: 750: elem * el_bin(unsigned op,tym_t ty,elem *e1,elem *e2) 751: { elem *e; 752: 753: #if 0 754: if (!(op < OPMAX && OTbinary(op) && e1 && e2)) 755: *(char *)0=0; 756: #endif 757: assert(op < OPMAX && OTbinary(op) && e1 && e2); 758: assert(MARS || !PARSER); 759: elem_debug(e1); 760: elem_debug(e2); 761: e = el_calloc(); 762: e->Ety = ty; 763: e->Eoper = op; 764: e->E1 = e1; 765: e->E2 = e2; 766: if (op == OPcomma && tyaggregate(ty)) 767: e->ET = e2->ET; 768: return e; 769: } 770: 771: /************************ 772: * Make a unary operator node. 773: */ 774: 775: elem * el_unat(unsigned op,type *t,elem *e1) 776: { elem *e; 777: 778: #ifdef DEBUG 779: if (!(op < OPMAX && OTunary(op) && e1)) 780: dbg_printf("op = x%x, e1 = %p\n",op,e1); 781: #endif 782: assert(op < OPMAX && OTunary(op) && e1); 783: assert(PARSER); 784: elem_debug(e1); 785: e = el_calloc(); 786: e->Eoper = op; 787: e->E1 = e1; 788: if (t) 789: { 790: type_debug(t); 791: t->Tcount++; 792: e->ET = t; 793: } 794: return e; 795: } 796: 797: elem * el_una(unsigned op,tym_t ty,elem *e1) 798: { elem *e; 799: 800: #ifdef DEBUG 801: if (!(op < OPMAX && OTunary(op) && e1)) 802: dbg_printf("op = x%x, e1 = %p\n",op,e1); 803: #endif 804: assert(op < OPMAX && OTunary(op) && e1); 805: assert(MARS || !PARSER); 806: elem_debug(e1); 807: e = el_calloc(); 808: e->Ety = ty; 809: e->Eoper = op; 810: e->E1 = e1; 811: return e; 812: } 813: 814: /******************* 815: * Make a constant node out of integral type. 816: */ 817: 818: elem * el_longt(type *t,targ_llong val) 819: { elem *e; 820: 821: assert(PARSER); 822: e = el_calloc(); 823: e->Eoper = OPconst; 824: e->ET = t; 825: if (e->ET) 826: { type_debug(t); 827: e->ET->Tcount++; 828: } 829: e->EV.Vllong = val; 830: return e; 831: } 832: 833: elem * el_long(tym_t t,targ_llong val) 834: { elem *e; 835: 836: assert(MARS || !PARSER); 837: e = el_calloc(); 838: e->Eoper = OPconst; 839: e->Ety = t; 840: switch (tybasic(t)) 841: { 842: case TYfloat: 843: case TYifloat: 844: e->EV.Vfloat = val;
warning C4244: '=' : conversion from 'targ_llong' to 'targ_float', possible loss of data
845: break; 846: case TYdouble: 847: case TYidouble: 848: e->EV.Vdouble = val;
warning C4244: '=' : conversion from 'targ_llong' to 'targ_double', possible loss of data
849: break; 850: case TYldouble: 851: case TYildouble: 852: e->EV.Vldouble = val;
warning C4244: '=' : conversion from 'targ_llong' to 'targ_ldouble', possible loss of data
853: break; 854: case TYcfloat: 855: case TYcdouble: 856: case TYcldouble: 857: assert(0); 858: break; 859: default: 860: e->EV.Vllong = val; 861: break; 862: } 863: return e; 864: } 865: 866: /******************************* 867: * If elem is a const that can be converted to an OPconst, 868: * do the conversion. 869: */ 870: 871: #if SCPP 872: void el_toconst(elem *e) 873: { 874: elem_debug(e); 875: assert(PARSER); 876: #if TX86 877: if (e->Eoper == OPvar && e->EV.sp.Vsym->Sflags & SFLvalue) 878: #else 879: if (e->Eoper == OPvar && e->EV.sp.Vsym->Sflags & SFLvalue && 880: tybasic(e->ET->Tty) != TYstruct) 881: #endif 882: { elem *es = e->EV.sp.Vsym->Svalue; 883: 884: type_debug(e->ET); 885: symbol_debug(e->EV.sp.Vsym); 886: elem_debug(es); 887: e->Eoper = es->Eoper; 888: assert(e->Eoper == OPconst); 889: e->EV = es->EV; 890: } 891: } 892: #endif 893: 894: /******************************* 895: * Set new type for elem. 896: */ 897: 898: elem * el_settype(elem *e,type *t) 899: { 900: #if MARS 901: assert(0); 902: #else 903: assert(PARSER); 904: elem_debug(e); 905: type_debug(t); 906: type_settype(&e->ET,t); 907: #endif 908: return e; 909: } 910: 911: /******************************* 912: * Walk tree, replacing symbol s1 with s2. 913: */ 914: 915: #if SCPP 916: 917: void el_replacesym(elem *e,symbol *s1,symbol *s2) 918: { 919: _chkstack(); 920: 921: assert(PARSER); 922: while (e) 923: { elem_debug(e); 924: if (EOP(e)) 925: { el_replacesym(e->E2,s1,s2); 926: e = e->E1; 927: } 928: else 929: { 930: if ((e->Eoper == OPvar || e->Eoper == OPrelconst) && 931: e->EV.sp.Vsym == s1) 932: e->EV.sp.Vsym = s2; 933: break; 934: } 935: } 936: } 937: 938: #endif 939: 940: /******************************* 941: * Create elem that is the size of a type. 942: */ 943: 944: elem * el_typesize(type *t) 945: { 946: #if MARS 947: assert(0); 948: return NULL; 949: #else 950: assert(PARSER); 951: type_debug(t); 952: if (CPP && tybasic(t->Tty) == TYstruct && t->Tflags & TFsizeunknown) 953: { elem *e; 954: 955: symbol_debug(t->Ttag); 956: e = el_calloc(); 957: e->Eoper = OPsizeof; 958: e->EV.sp.Vsym = t->Ttag; 959: e->ET = tssize; 960: e->ET->Tcount++; 961: type_debug(tssize); 962: elem_debug(e); 963: return e; 964: } 965: else if (tybasic(t->Tty) == TYarray && type_isvla(t)) 966: { 967: type *troot = type_arrayroot(t); 968: elem *en; 969: 970: en = el_nelems(t); 971: return el_bint(OPmul, en->ET, en, el_typesize(troot)); 972: } 973: else 974: return el_longt(tssize,type_size(t)); 975: #endif 976: } 977: 978: /***************************** 979: * Return an elem that evaluates to the number of elems in a type 980: * (if it is an array). Returns NULL if t is not an array. 981: */ 982: 983: #if SCPP 984: elem * el_nelems(type *t) 985: { elem *enelems; 986: 987: assert(PARSER); 988: type_debug(t); 989: if (tybasic(t->Tty) == TYarray) 990: { type *ts = tssize; 991: 992: enelems = el_longt(ts, 1); 993: do 994: { 995: if (t->Tflags & TFsizeunknown || 996: (t->Tflags & TFvla && !t->Tel)) 997: { synerr(EM_unknown_size,"array"); // size of array is unknown 998: t->Tflags &= ~TFsizeunknown; 999: } 1000: else if (t->Tflags & TFvla) 1001: { 1002: enelems = el_bint(OPmul, ts, enelems, el_copytree(t->Tel)); 1003: } 1004: else if (enelems->Eoper == OPconst) 1005: { enelems->EV.Vllong *= t->Tdim; 1006: type_chksize(enelems->EV.Vllong); 1007: } 1008: else 1009: enelems = el_bint(OPmul, enelems->ET, enelems, el_longt(ts, t->Tdim)); 1010: t = t->Tnext; 1011: } while (tybasic(t->Tty) == TYarray); 1012: } 1013: else 1014: enelems = NULL; 1015: return enelems; 1016: } 1017: #endif 1018: 1019: /************************************ 1020: * Return != 0 if function has any side effects. 1021: */ 1022: 1023: #if MARS 1024: 1025: int el_funcsideeff(elem *e) 1026: { Symbol *s; 1027: 1028: if (e->Eoper == OPvar && 1029: tyfunc((s = e->EV.sp.Vsym)->Stype->Tty) && 1030: ((s->Sfunc && s->Sfunc->Fflags3 & Fnosideeff) || s == funcsym_p) 1031: ) 1032: return 0; 1033: return 1; // assume it does have side effects 1034: } 1035: 1036: #endif 1037: 1038: /**************************** 1039: * Return != 0 if elem has any side effects. 1040: */ 1041: 1042: int el_sideeffect(elem *e) 1043: { int op; 1044: 1045: assert(e); 1046: op = e->Eoper; 1047: assert(op < OPMAX); 1048: elem_debug(e); 1049: return typemask(e) & mTYvolatile || 1050: OTsideff(op) || 1051: (OTunary(op) && el_sideeffect(e->E1)) || 1052: (OTbinary(op) && (el_sideeffect(e->E1) || 1053: el_sideeffect(e->E2))); 1054: } 1055: 1056: #if TX86 1057: /****************************** 1058: * Input: 1059: * ea lvalue (might be an OPbit) 1060: * Returns: 1061: * 0 eb has no dependency on ea 1062: * 1 eb might have a dependency on ea 1063: * 2 eb definitely depends on ea 1064: */ 1065: 1066: int el_depends(elem *ea,elem *eb) 1067: { 1068: L1: 1069: elem_debug(ea); 1070: elem_debug(eb); 1071: switch (ea->Eoper) 1072: { 1073: case OPbit: 1074: ea = ea->E1; 1075: goto L1; 1076: case OPvar: 1077: case OPind: 1078: break; 1079: default: 1080: assert(0); 1081: } 1082: switch (eb->Eoper) 1083: { 1084: case OPconst: 1085: case OPrelconst: 1086: case OPstring: 1087: #if SCPP 1088: case OPsizeof: 1089: #endif 1090: goto Lnodep; 1091: case OPvar: 1092: if (ea->Eoper == OPvar && ea->EV.sp.Vsym != eb->EV.sp.Vsym) 1093: goto Lnodep; 1094: break; 1095: default: 1096: break; // this could use improvement 1097: } 1098: return 1; 1099: 1100: Lnodep: 1101: return 0; 1102: } 1103: #endif 1104: 1105: /************************** 1106: * Make an elem out of a symbol, PIC style. 1107: */ 1108: 1109: #if TARGET_OSX 1110: 1111: elem *el_picvar(symbol *s) 1112: { elem *e; 1113: int x; 1114: 1115: //printf("el_picvar(s = '%s')\n", s->Sident); 1116: //printf(" Sclass = "); WRclass((enum SC) s->Sclass); printf("\n"); 1117: //symbol_print(s); 1118: symbol_debug(s); 1119: type_debug(s->Stype); 1120: e = el_calloc(); 1121: e->Eoper = OPvar; 1122: e->EV.sp.Vsym = s; 1123: e->Ety = s->ty(); 1124: 1125: switch (s->Sclass) 1126: { 1127: case SCstatic: 1128: case SClocstat: 1129: x = 0; 1130: goto case_got; 1131: 1132: case SCcomdat: 1133: case SCcomdef: 1134: case SCglobal: 1135: case SCextern: 1136: #if 0 1137: if (s->Stype->Tty & mTYthread) 1138: x = 0; 1139: else 1140: #endif 1141: x = 1; 1142: case_got: 1143: { if (!localgot) 1144: { 1145: //localgot = symbol_generate(SCtmp,type_fake(TYnptr)); 1146: char name[15]; 1147: static int tmpnum; 1148: sprintf(name, "_LOCALGOT%d", tmpnum++); 1149: localgot = symbol_name(name, SCtmp, type_fake(TYnptr)); 1150: symbol_add(localgot); 1151: localgot->Sfl = FLtmp; 1152: localgot->Sflags = SFLfree | SFLunambig | GTregcand; 1153: } 1154: int op = e->Eoper; 1155: tym_t tym = e->Ety; 1156: e->Eoper = OPrelconst; 1157: e->Ety = TYnptr; 1158: e = el_bin(OPadd, TYnptr, e, el_var(localgot)); 1159: #if 1 1160: if (s->Stype->Tty & mTYthread) 1161: { 1162: if (!tls_get_addr_sym) 1163: { 1164: /* void *___tls_get_addr(void *ptr); 1165: * Parameter ptr is passed in EAX, matching TYjfunc calling convention. 1166: */ 1167: tls_get_addr_sym = symbol_name("___tls_get_addr",SCglobal,type_fake(TYjfunc)); 1168: symbol_keep(tls_get_addr_sym); 1169: slist_add(tls_get_addr_sym); 1170: } 1171: if (x == 1) 1172: e = el_una(OPind, TYnptr, e); 1173: e = el_bin(OPcallns, TYnptr, el_var(tls_get_addr_sym), e); 1174: if (op == OPvar) 1175: e = el_una(OPind, TYnptr, e); 1176: } 1177: else 1178: #endif 1179: { 1180: switch (op * 2 + x) 1181: { 1182: case OPvar * 2 + 1: 1183: e = el_una(OPind, TYnptr, e); 1184: e = el_una(OPind, TYnptr, e); 1185: break; 1186: case OPvar * 2 + 0: 1187: case OPrelconst * 2 + 1: 1188: e = el_una(OPind, TYnptr, e); 1189: break; 1190: case OPrelconst * 2 + 0: 1191: break; 1192: default: 1193: assert(0); 1194: break; 1195: } 1196: } 1197: e->Ety = tym; 1198: break; 1199: } 1200: default: 1201: break; 1202: } 1203: return e; 1204: } 1205: #endif 1206: #if TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS 1207: 1208: elem *el_picvar(symbol *s) 1209: { elem *e; 1210: int x; 1211: 1212: //printf("el_picvar(s = '%s')\n", s->Sident); 1213: symbol_debug(s); 1214: type_debug(s->Stype); 1215: e = el_calloc(); 1216: e->Eoper = OPvar; 1217: e->EV.sp.Vsym = s; 1218: e->Ety = s->ty(); 1219: 1220: /* For 32 bit: 1221: * CALL __i686.get_pc_thunk.bx@PC32 1222: * ADD EBX,offset _GLOBAL_OFFSET_TABLE_@GOTPC[2] 1223: * Generate for var locals: 1224: * MOV reg,s@GOTOFF[014h][EBX] 1225: * For var globals: 1226: * MOV EAX,s@GOT32[EBX] 1227: * MOV reg,[EAX] 1228: * For TLS var locals and globals: 1229: * MOV EAX,s@TLS_GD[EBX] 1230: * CALL ___tls_get_addr@PLT32 1231: * MOV reg,[EAX] 1232: ***************************************** 1233: * Generate for var locals: 1234: * MOV reg,s@PC32[RIP] 1235: * For var globals: 1236: * MOV RAX,s@GOTPCREL[RIP] 1237: * MOV reg,[RAX] 1238: * For TLS var locals and globals: 1239: * 0x66 1240: * LEA DI,s@TLSGD[RIP] 1241: * 0x66 1242: * 0x66 1243: * 0x48 (REX | REX_W) 1244: * CALL __tls_get_addr@PLT32 1245: * MOV reg,[RAX] 1246: */ 1247: 1248: if (I64) 1249: { 1250: elfobj_refGOTsym(); 1251: switch (s->Sclass) 1252: { 1253: case SCstatic: 1254: case SClocstat: 1255: x = 0; 1256: goto case_got64; 1257: 1258: case SCcomdat: 1259: case SCcomdef: 1260: case SCglobal: 1261: case SCextern: 1262: x = 1; 1263: case_got64: 1264: { 1265: int op = e->Eoper; 1266: tym_t tym = e->Ety; 1267: e->Ety = TYnptr; 1268: 1269: if (s->Stype->Tty & mTYthread) 1270: { 1271: /* Add "volatile" to prevent e from being common subexpressioned. 1272: * This is so we can preserve the magic sequence of instructions 1273: * that the gnu linker patches: 1274: * lea EDI,x@tlsgd[RIP], call __tls_get_addr@plt 1275: * => 1276: * mov EAX,gs[0], sub EAX,x@tpoff 1277: */ 1278: e->Eoper = OPrelconst; 1279: e->Ety |= mTYvolatile; 1280: if (!tls_get_addr_sym) 1281: { 1282: /* void *__tls_get_addr(void *ptr); 1283: * Parameter ptr is passed in RDI, matching TYnfunc calling convention. 1284: */ 1285: tls_get_addr_sym = symbol_name("__tls_get_addr",SCglobal,type_fake(TYnfunc)); 1286: symbol_keep(tls_get_addr_sym); 1287: } 1288: e = el_bin(OPcall, TYnptr, el_var(tls_get_addr_sym), e); 1289: } 1290: 1291: switch (op * 2 + x) 1292: { 1293: case OPvar * 2 + 1: 1294: e = el_una(OPind, TYnptr, e); 1295: break; 1296: case OPvar * 2 + 0: 1297: case OPrelconst * 2 + 1: 1298: break; 1299: case OPrelconst * 2 + 0: 1300: e = el_una(OPaddr, TYnptr, e); 1301: break; 1302: default: 1303: assert(0); 1304: break; 1305: } 1306: e->Ety = tym; 1307: break; 1308: } 1309: default: 1310: break; 1311: } 1312: } 1313: else 1314: switch (s->Sclass) 1315: { 1316: /* local (and thread) symbols get only one level of indirection; 1317: * all globally known symbols get two. 1318: */ 1319: case SCstatic: 1320: case SClocstat: 1321: x = 0; 1322: goto case_got; 1323: 1324: case SCcomdat: 1325: case SCcomdef: 1326: case SCglobal: 1327: case SCextern: 1328: if (s->Stype->Tty & mTYthread) 1329: x = 0; 1330: else 1331: x = 1; 1332: case_got: 1333: { if (!localgot) 1334: { 1335: //localgot = symbol_generate(SCtmp,type_fake(TYnptr)); 1336: char name[15]; 1337: static int tmpnum; 1338: sprintf(name, "_LOCALGOT%d", tmpnum++); 1339: localgot = symbol_name(name, SCtmp, type_fake(TYnptr)); 1340: symbol_add(localgot); 1341: localgot->Sfl = FLtmp; 1342: localgot->Sflags = SFLfree | SFLunambig | GTregcand; 1343: } 1344: int op = e->Eoper; 1345: tym_t tym = e->Ety; 1346: e->Eoper = OPrelconst; 1347: e->Ety = TYnptr; 1348: e = el_bin(OPadd, TYnptr, e, el_var(localgot)); 1349: 1350: if (s->Stype->Tty & mTYthread) 1351: { 1352: /* Add "volatile" to prevent e from being common subexpressioned. 1353: * This is so we can preserve the magic sequence of instructions 1354: * that the gnu linker patches: 1355: * lea EAX,x@tlsgd[EBX], call __tls_get_addr@plt 1356: * => 1357: * mov EAX,gs[0], sub EAX,x@tpoff 1358: * elf32-i386.c 1359: */ 1360: e->Ety |= mTYvolatile; 1361: if (!tls_get_addr_sym) 1362: { 1363: /* void *___tls_get_addr(void *ptr); 1364: * Parameter ptr is passed in EAX, matching TYjfunc calling convention. 1365: */ 1366: tls_get_addr_sym = symbol_name("___tls_get_addr",SCglobal,type_fake(TYjfunc)); 1367: symbol_keep(tls_get_addr_sym); 1368: } 1369: e = el_bin(OPcall, TYnptr, el_var(tls_get_addr_sym), e); 1370: } 1371: 1372: switch (op * 2 + x) 1373: { 1374: case OPvar * 2 + 1: 1375: e = el_una(OPind, TYnptr, e); 1376: e = el_una(OPind, TYnptr, e); 1377: break; 1378: case OPvar * 2 + 0: 1379: case OPrelconst * 2 + 1: 1380: e = el_una(OPind, TYnptr, e); 1381: break; 1382: case OPrelconst * 2 + 0: 1383: break; 1384: default: 1385: assert(0); 1386: break; 1387: } 1388: e->Ety = tym; 1389: break; 1390: } 1391: default: 1392: break; 1393: } 1394: return e; 1395: } 1396: #endif 1397: 1398: /************************** 1399: * Make an elem out of a symbol. 1400: */ 1401: 1402: #if MARS 1403: elem * el_var(symbol *s) 1404: { elem *e; 1405: 1406: //printf("el_var(s = '%s')\n", s->Sident); 1407: //printf("%x\n", s->Stype->Tty); 1408: #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS 1409: // OSX is currently always pic 1410: if (config.flags3 & CFG3pic && 1411: #if TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS 1412: (!(s->Stype->Tty & mTYthread) || I64) && 1413: #endif 1414: !tyfunc(s->ty())) 1415: // Position Independent Code 1416: return el_picvar(s); 1417: #endif 1418: symbol_debug(s); 1419: type_debug(s->Stype); 1420: e = el_calloc(); 1421: e->Eoper = OPvar; 1422: e->EV.sp.Vsym = s; 1423: type_debug(s->Stype); 1424: e->Ety = s->ty(); 1425: if (s->Stype->Tty & mTYthread) 1426: { 1427: //printf("thread local %s\n", s->Sident); 1428: #if TARGET_OSX 1429: ; 1430: #elif TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS 1431: /* For 32 bit: 1432: * Generate for var locals: 1433: * MOV reg,GS:[00000000] // add GS: override in back end 1434: * ADD reg, offset s@TLS_LE 1435: * e => *(&s + *(GS:0)) 1436: * For var globals: 1437: * MOV reg,GS:[00000000] 1438: * ADD reg, s@TLS_IE 1439: * e => *(s + *(GS:0)) 1440: * note different fixup 1441: ***************************************** 1442: * For 64 bit: 1443: * Generate for var locals: 1444: * MOV reg,FS:s@TPOFF32 1445: * For var globals: 1446: * MOV RAX,s@GOTTPOFF[RIP] 1447: * MOV reg,FS:[RAX] 1448: * 1449: * For address of locals: 1450: * MOV RAX,FS:[00] 1451: * LEA reg,s@TPOFF32[RAX] 1452: * e => &s + *(FS:0) 1453: * For address of globals: 1454: * MOV reg,FS:[00] 1455: * MOV RAX,s@GOTTPOFF[RIP] 1456: * ADD reg,RAX 1457: * e => s + *(FS:0) 1458: * This leaves us with a problem, as the 'var' version cannot simply have 1459: * its address taken, as what is the address of FS:s ? The (not so efficient) 1460: * solution is to just use the second address form, and * it. 1461: * Turns out that is identical to the 32 bit version, except GS => FS and the 1462: * fixups are different. 1463: * In the future, we should figure out a way to optimize to the 'var' version. 1464: */ 1465: if (I64) 1466: elfobj_refGOTsym(); 1467: elem *e1 = el_calloc(); 1468: e1->EV.sp.Vsym = s; 1469: if (s->Sclass == SCstatic || s->Sclass == SClocstat) 1470: { e1->Eoper = OPrelconst; 1471: e1->Ety = TYnptr; 1472: } 1473: else 1474: { 1475: e1->Eoper = OPvar; 1476: e1->Ety = TYnptr; 1477: } 1478: 1479: /* Fake GS:[0000] as a load of _tls_array, and then in the back end recognize 1480: * the fake and rewrite it as GS:[0000] (or FS:[0000] for I64), because there is 1481: * no way to represent segment overrides in the elem nodes. 1482: */ 1483: elem *e2 = el_calloc(); 1484: e2->Eoper = OPvar; 1485: e2->EV.sp.Vsym = rtlsym[RTLSYM_TLS_ARRAY]; 1486: e2->Ety = e2->EV.sp.Vsym->ty(); 1487: 1488: e->Eoper = OPind; 1489: e->E1 = el_bin(OPadd,e1->Ety,e2,e1); 1490: e->E2 = NULL; 1491: #else 1492: /* 1493: mov EAX,FS:__tls_array 1494: mov ECX,__tls_index 1495: mov EAX,[ECX*4][EAX] 1496: inc dword ptr _t[EAX] 1497: 1498: e => *(&s + *(FS:_tls_array + _tls_index * 4)) 1499: 1500: If this is an executable app, not a dll, _tls_index 1501: can be assumed to be 0. 1502: */ 1503: elem *e1,*e2,*ea; 1504: 1505: e1 = el_calloc(); 1506: e1->Eoper = OPrelconst; 1507: e1->EV.sp.Vsym = s; 1508: e1->Ety = TYnptr; 1509: 1510: if (config.wflags & WFexe) 1511: { 1512: // e => *(&s + *(FS:_tls_array)) 1513: e2 = el_var(rtlsym[RTLSYM_TLS_ARRAY]); 1514: } 1515: else 1516: { 1517: e2 = el_bin(OPmul,TYint,el_var(rtlsym[RTLSYM_TLS_INDEX]),el_long(TYint,4)); 1518: ea = el_var(rtlsym[RTLSYM_TLS_ARRAY]); 1519: e2 = el_bin(OPadd,ea->Ety,ea,e2); 1520: } 1521: e2 = el_una(OPind,TYint,e2); 1522: 1523: e->Eoper = OPind; 1524: e->E1 = el_bin(OPadd,e1->Ety,e1,e2); 1525: e->E2 = NULL; 1526: #endif 1527: } 1528: return e; 1529: } 1530: #elif SCPP 1531: elem * el_var(symbol *s) 1532: { elem *e; 1533: 1534: //printf("el_var(s = '%s')\n", s->Sident); 1535: #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS 1536: if (config.flags3 & CFG3pic && !tyfunc(s->ty())) 1537: return el_picvar(s); 1538: #endif 1539: symbol_debug(s); 1540: type_debug(s->Stype); 1541: e = el_calloc(); 1542: e->Eoper = OPvar; 1543: e->EV.sp.Vsym = s; 1544: if (SCPP && PARSER) 1545: #if TX86 && TARGET_WINDOS 1546: { type *t = s->Stype; 1547: 1548: type_debug(t); 1549: e->ET = t; 1550: t->Tcount++; 1551: switch (t->Tty & (mTYimport | mTYthread)) 1552: { case mTYimport: 1553: obj_import(e); 1554: break; 1555: case mTYthread: 1556: /* 1557: mov EAX,FS:__tls_array 1558: mov ECX,__tls_index 1559: mov EAX,[ECX*4][EAX] 1560: inc dword ptr _t[EAX] 1561: 1562: e => *(&s + *(FS:_tls_array + _tls_index * 4)) 1563: */ 1564: #if MARS 1565: assert(0); 1566: #else 1567: { elem *e1,*e2,*ea; 1568: 1569: e1 = el_calloc(); 1570: e1->Eoper = OPrelconst; 1571: e1->EV.sp.Vsym = s; 1572: e1->ET = newpointer(s->Stype); 1573: e1->ET->Tcount++; 1574: 1575: e2 = el_bint(OPmul,tsint,el_var(rtlsym[RTLSYM_TLS_INDEX]),el_longt(tsint,4)); 1576: ea = el_var(rtlsym[RTLSYM_TLS_ARRAY]); 1577: e2 = el_bint(OPadd,ea->ET,ea,e2); 1578: e2 = el_unat(OPind,tsint,e2); 1579: 1580: e->Eoper = OPind; 1581: e->E1 = el_bint(OPadd,e1->ET,e1,e2); 1582: e->E2 = NULL; 1583: } 1584: #endif 1585: break; 1586: case mTYthread | mTYimport: 1587: assert(SCPP); 1588: #if SCPP 1589: tx86err(EM_thread_and_dllimport,s->Sident); // can't be both thread and import 1590: #endif 1591: break; 1592: } 1593: } 1594: #else 1595: { type_debug(s->Stype); 1596: e->ET = s->Stype; 1597: e->ET->Tcount++; 1598: } 1599: #endif 1600: else 1601: e->Ety = s->ty(); 1602: return e; 1603: } 1604: #endif 1605: 1606: /************************** 1607: * Make a pointer to an elem out of a symbol. 1608: */ 1609: 1610: elem * el_ptr(symbol *s) 1611: { 1612: elem *e; 1613: 1614: //printf("el_ptr(s = '%s')\n", s->Sident); 1615: //printf("el_ptr\n"); 1616: symbol_debug(s); 1617: type_debug(s->Stype); 1618: #if TARGET_OSX 1619: if (config.flags3 & CFG3pic && tyfunc(s->ty())) 1620: { 1621: /* Cannot access address of code from code. 1622: * Instead, create a data variable, put the address of the 1623: * code in that data variable, and return the elem for 1624: * that data variable. 1625: */ 1626: symbol *sd = symboldata(Doffset, TYnptr); 1627: Doffset += reftoident(DATA, Doffset, s, 0, CFoff); 1628: e = el_picvar(sd); 1629: return e; 1630: } 1631: #endif 1632: #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS 1633: if (config.flags3 & CFG3pic && tyfunc(s->ty())) 1634: e = el_picvar(s); 1635: else 1636: #endif 1637: e = el_var(s); 1638: #if SCPP 1639: if (PARSER) 1640: { type_debug(e->ET); 1641: e = el_unat(OPaddr,type_ptr(e,e->ET),e); 1642: } 1643: else 1644: #endif 1645: if (e->Eoper == OPvar) 1646: { 1647: e->Ety = TYnptr; 1648: e->Eoper = OPrelconst; 1649: } 1650: else 1651: { e = el_una(OPaddr, TYnptr, e); 1652: e = doptelem(e, GOALvalue | GOALflags); 1653: } 1654: return e; 1655: } 1656: 1657: /************************** 1658: * Make a pointer to an elem out of a symbol at offset. 1659: */ 1660: 1661: #if SCPP 1662: 1663: elem * el_ptr_offset(symbol *s,targ_size_t offset) 1664: { elem *e; 1665: elem *e1; 1666: 1667: e = el_ptr(s); /* e is an elem which is a pointer to s */ 1668: e1 = e->E1; 1669: if (e1->Eoper == OPvar) 1670: ; 1671: // The following case happens if symbol s is in thread local storage 1672: else if (e1->Eoper == OPind && 1673: e1->E1->Eoper == OPadd && 1674: e1->E1->E1->Eoper == OPrelconst) 1675: e1 = e1->E1->E1; 1676: else 1677: assert(0); 1678: assert(e1->EV.sp.Vsym == s); 1679: e1->EV.sp.Voffset = offset; 1680: return e; 1681: } 1682: 1683: #endif 1684: 1685: /************************* 1686: * Returns: 1687: * !=0 elem evaluates right-to-left 1688: * 0 elem evaluates left-to-right 1689: */ 1690: 1691: HINT ERTOL(elem *e) 1692: { 1693: elem_debug(e); 1694: assert(!PARSER); 1695: #if TX86 1696: return OTrtol(e->Eoper) && 1697: (!OTopeq(e->Eoper) || config.inline8087 || !tyfloating(e->Ety)); 1698: #else 1699: return OTrtol(e->Eoper); 1700: #endif 1701: } 1702: 1703: /******************************** 1704: * Return !=0 if expression never returns. 1705: * Does not detect all cases, errs on the side of saying it returns. 1706: */ 1707: 1708: int el_noreturn(elem *e) 1709: { int result = 0; 1710: 1711: while (1) 1712: { elem_debug(e); 1713: switch (e->Eoper) 1714: { case OPcomma: 1715: if (result |= el_noreturn(e->E1)) 1716: break; 1717: e = e->E2; 1718: continue; 1719: 1720: case OPcall: 1721: case OPucall: 1722: e = e->E1; 1723: if (e->Eoper == OPvar && e->EV.sp.Vsym->Sflags & SFLexit) 1724: result = 1; 1725: break; 1726: 1727: case OPhalt: 1728: result = 1; 1729: break; 1730: 1731: default: 1732: break; 1733: } 1734: break; 1735: } 1736: return result; 1737: } 1738: 1739: /******************************** 1740: * Scan down commas and return the controlling elem. 1741: */ 1742: 1743: elem *el_scancommas(elem *e) 1744: { 1745: while (e->Eoper == OPcomma) 1746: e = e->E2; 1747: return e; 1748: } 1749: 1750: /*************************** 1751: * Count number of commas in the expression. 1752: */ 1753: 1754: int el_countCommas(elem *e) 1755: { int ncommas = 0; 1756: while (1) 1757: { 1758: if (EBIN(e)) 1759: { 1760: ncommas += (e->Eoper == OPcomma) + el_countCommas(e->E2); 1761: } 1762: else if (EUNA(e)) 1763: { 1764: } 1765: else 1766: break; 1767: e = e->E1; 1768: } 1769: return ncommas; 1770: } 1771: 1772: /************************************ 1773: * Convert floating point constant to a read-only symbol. 1774: * Needed iff floating point code can't load immediate constants. 1775: */ 1776: 1777: elem *el_convfloat(elem *e) 1778: { 1779: unsigned char buffer[32]; 1780: 1781: #if TX86 1782: assert(config.inline8087); 1783: 1784: // Do not convert if the constants can be loaded with the special FPU instructions 1785: if (tycomplex(e->Ety)) 1786: { 1787: if (loadconst(e, 0) && loadconst(e, 1)) 1788: return e; 1789: } 1790: else if (loadconst(e, 0)) 1791: return e; 1792: 1793: changes++; 1794: tym_t ty = e->Ety; 1795: int sz = tysize(ty); 1796: assert(sz <= sizeof(buffer)); 1797: void *p; 1798: switch (tybasic(ty)) 1799: { 1800: case TYfloat: 1801: case TYifloat: 1802: p = &e->EV.Vfloat; 1803: assert(sz == sizeof(e->EV.Vfloat)); 1804: break; 1805: 1806: case TYdouble: 1807: case TYidouble: 1808: case TYdouble_alias: 1809: p = &e->EV.Vdouble; 1810: assert(sz == sizeof(e->EV.Vdouble)); 1811: break; 1812: 1813: case TYldouble: 1814: case TYildouble: 1815: /* The size, alignment, and padding of long doubles may be different 1816: * from host to target 1817: */ 1818: p = buffer; 1819: memset(buffer, 0, sz); // ensure padding is 0 1820: memcpy(buffer, &e->EV.Vldouble, 10); 1821: break; 1822: 1823: case TYcfloat: 1824: p = &e->EV.Vcfloat; 1825: assert(sz == sizeof(e->EV.Vcfloat)); 1826: break; 1827: 1828: case TYcdouble: 1829: p = &e->EV.Vcdouble; 1830: assert(sz == sizeof(e->EV.Vcdouble)); 1831: break; 1832: 1833: case TYcldouble: 1834: p = buffer; 1835: memset(buffer, 0, sz); 1836: memcpy(buffer, &e->EV.Vcldouble.re, 10); 1837: memcpy(buffer + tysize(TYldouble), &e->EV.Vcldouble.im, 10); 1838: break; 1839: 1840: default: 1841: assert(0); 1842: } 1843: #if 0 1844: printf("%gL+%gLi\n", (double)e->EV.Vcldouble.re, (double)e->EV.Vcldouble.im); 1845: printf("el_convfloat() %g %g sz=%d\n", e->EV.Vcdouble.re, e->EV.Vcdouble.im, sz); 1846: printf("el_convfloat(): sz = %d\n", sz); 1847: unsigned short *p = (unsigned short *)&e->EV.Vcldouble; 1848: for (int i = 0; i < sz/2; i++) printf("%04x ", p[i]); 1849: printf("\n"); 1850: #endif 1851: symbol *s = out_readonly_sym(ty, p, sz); 1852: el_free(e); 1853: e = el_var(s); 1854: e->Ety = ty; 1855: if (e->Eoper == OPvar) 1856: e->Ety |= mTYconst; 1857: //printf("s: %s %d:x%x\n", s->Sident, s->Sseg, s->Soffset); 1858: #endif 1859: return e; 1860: } 1861: 1862: /******************************** 1863: * Convert reference to a string to reference to a symbol 1864: * stored in the static data segment. 1865: */ 1866: 1867: elem *el_convstring(elem *e) 1868: { 1869: //printf("el_convstring()\n"); 1870: int i; 1871: symbol *s; 1872: char *p; 1873: targ_size_t len; 1874: 1875: assert(!PARSER); 1876: elem_debug(e); 1877: assert(e->Eoper == OPstring); 1878: p = e->EV.ss.Vstring; 1879: e->EV.ss.Vstring = NULL; 1880: len = e->EV.ss.Vstrlen; 1881: 1882: #if TX86 1883: // Handle strings that go into the code segment 1884: if (tybasic(e->Ety) == TYcptr || 1885: (tyfv(e->Ety) && config.flags3 & CFG3strcod)) 1886: { 1887: assert(OMFOBJ); // option not done yet for others 1888: s = symbol_generate(SCstatic, type_fake(mTYcs | e->Ety)); 1889: s->Sfl = FLcsdata; 1890: s->Soffset = Coffset; 1891: s->Sseg = cseg; 1892: symbol_keep(s); 1893: if (!eecontext.EEcompile || eecontext.EEin) 1894: { obj_bytes(cseg,Coffset,len,p); 1895: Coffset += len; 1896: } 1897: mem_free(p); 1898: goto L1; 1899: } 1900: #endif 1901: 1902: if (eecontext.EEin) // if compiling debugger expression 1903: { 1904: s = out_readonly_sym(e->Ety, p, len); 1905: mem_free(p); 1906: goto L1; 1907: } 1908: 1909: // See if e is already in the string table 1910: for (i = 0; i < arraysize(stable); i++) 1911: { if (stable[i].len == len && 1912: memcmp(stable[i].p,p,len) == 0) 1913: { 1914: // Replace e with that symbol 1915: MEM_PH_FREE(p); 1916: s = stable[i].sym; 1917: goto L1; 1918: } 1919: } 1920: 1921: // Replace string with a symbol that refers to that string 1922: // in the DATA segment 1923: 1924: if (eecontext.EEcompile) 1925: s = symboldata(Doffset,e->Ety); 1926: else 1927: s = out_readonly_sym(e->Ety,p,len); 1928: 1929: // Remember the string for possible reuse later 1930: //dbg_printf("Adding %d, '%s'\n",stable_si,p); 1931: mem_free(stable[stable_si].p); 1932: stable[stable_si].p = p; 1933: stable[stable_si].len = len; 1934: stable[stable_si].sym = s; 1935: stable_si = (stable_si + 1) & (arraysize(stable) - 1); 1936: 1937: L1: 1938: // Refer e to the symbol generated 1939: elem *ex = el_ptr(s); 1940: ex->Ety = e->Ety; 1941: if (e->EV.ss.Voffset) 1942: { 1943: if (ex->Eoper == OPrelconst) 1944: ex->EV.sp.Voffset += e->EV.ss.Voffset; 1945: else 1946: ex = el_bin(OPadd, ex->Ety, ex, el_long(TYint, e->EV.ss.Voffset)); 1947: } 1948: el_free(e); 1949: return ex; 1950: } 1951: 1952: /******************************************** 1953: * If e is a long double constant, and it is perfectly representable as a 1954: * double constant, convert it to a double constant. 1955: * Note that this must NOT be done in contexts where there are no further 1956: * operations, since then it could change the type (eg, in the function call 1957: * printf("%La", 2.0L); the 2.0 must stay as a long double). 1958: */ 1959: #if 1 1960: void shrinkLongDoubleConstantIfPossible(elem *e) 1961: { 1962: if (e->Eoper == OPconst && e->Ety == TYldouble) 1963: { 1964: /* Check to see if it can be converted into a double (this happens 1965: * when the low bits are all zero, and the exponent is in the 1966: * double range). 1967: * Use 'volatile' to prevent optimizer from folding away the conversions, 1968: * and thereby missing the truncation in the conversion to double. 1969: */ 1970: volatile long double v = e->EV.Vldouble; 1971: volatile double vDouble; 1972: *(&vDouble) = v; 1973: if (v == vDouble) // This will fail if compiler does NaN incorrectly! 1974: { 1975: // Yes, we can do it! 1976: e->EV.Vdouble = vDouble; 1977: e->Ety = TYdouble; 1978: } 1979: } 1980: } 1981: #endif 1982: 1983: 1984: /************************* 1985: * Run through a tree converting it to CODGEN. 1986: */ 1987: 1988: elem *el_convert(elem *e) 1989: { int op; 1990: 1991: //printf("el_convert(%p)\n", e); 1992: elem_debug(e); 1993: op = e->Eoper; 1994: switch (op) 1995: { 1996: case OPvar: 1997: break; 1998: 1999: case OPconst: 2000: #if TX86 2001: if (tyfloating(e->Ety) && config.inline8087) 2002: e = el_convfloat(e); 2003: #endif 2004: break; 2005: 2006: case OPstring: 2007: changes++; 2008: e = el_convstring(e); 2009: break; 2010: 2011: case OPnullptr: 2012: e = el_long(e->Ety, 0); 2013: break; 2014: 2015: case OPmul: 2016: /* special floating-point case: allow x*2 to be x+x 2017: * in this case, we preserve the constant 2. 2018: */ 2019: if (tyreal(e->Ety) && // don't bother with imaginary or complex 2020: e->E2->Eoper == OPconst && el_toldouble(e->E2) == 2.0L) 2021: { 2022: e->E1 = el_convert(e->E1); 2023: /* Don't call el_convert(e->E2), we want it to stay as a constant 2024: * which will be detected by code gen. 2025: */ 2026: break; 2027: } 2028: #if 1 2029: case OPdiv: 2030: case OPadd: 2031: case OPmin: 2032: // For a*b,a+b,a-b,a/b, if a long double constant is involved, convert it to a double constant. 2033: if (tyreal(e->Ety)) 2034: shrinkLongDoubleConstantIfPossible(e->E1); 2035: if (tyreal(e->Ety)) 2036: shrinkLongDoubleConstantIfPossible(e->E2); 2037: // fall through... 2038: #endif 2039: default: 2040: if (OTbinary(op))
warning C6385: Invalid data: accessing 'unsigned char const * const optab1', the readable size is '183' bytes, but '1145' bytes might be read: Lines: 1989, 1993, 1994, 2039, 2040
2041: { 2042: e->E1 = el_convert(e->E1); 2043: e->E2 = el_convert(e->E2); 2044: } 2045: else if (OTunary(op)) 2046: { 2047: e->E1 = el_convert(e->E1); 2048: } 2049: break; 2050: } 2051: return e; 2052: } 2053: 2054: 2055: /************************ 2056: * Make a constant elem. 2057: * ty = type of elem 2058: * *pconst = union of constant data 2059: */ 2060: 2061: elem * el_const(tym_t ty,union eve *pconst) 2062: { elem *e; 2063: 2064: assert(MARS || !PARSER); 2065: e = el_calloc(); 2066: e->Eoper = OPconst; 2067: e->Ety = ty; 2068: memcpy(&e->EV,pconst,sizeof(e->EV)); 2069: return e; 2070: } 2071: 2072: 2073: /************************** 2074: * Insert constructor information into tree. 2075: * e code to construct the object 2076: * decl VarDeclaration of variable being constructed 2077: */ 2078: 2079: #if MARS 2080: elem *el_dctor(elem *e,void *decl) 2081: { 2082: elem *ector = el_calloc(); 2083: ector->Eoper = OPdctor; 2084: ector->Ety = TYvoid; 2085: ector->EV.ed.Edecl = decl; 2086: if (e) 2087: e = el_bin(OPinfo,e->Ety,ector,e); 2088: else 2089: /* Remember that a "constructor" may execute no code, hence 2090: * the need for OPinfo if there is code to execute. 2091: */ 2092: e = ector; 2093: return e; 2094: } 2095: #endif 2096: 2097: /************************** 2098: * Insert destructor information into tree. 2099: * e code to destruct the object 2100: * decl VarDeclaration of variable being destructed 2101: * (must match decl for corresponding OPctor) 2102: */ 2103: 2104: #if MARS 2105: elem *el_ddtor(elem *e,void *decl) 2106: { 2107: /* A destructor always executes code, or we wouldn't need 2108: * eh for it. 2109: * An OPddtor must match 1:1 with an OPdctor 2110: */ 2111: elem *edtor = el_calloc(); 2112: edtor->Eoper = OPddtor; 2113: edtor->Ety = TYvoid; 2114: edtor->EV.ed.Edecl = decl; 2115: edtor->EV.ed.Eleft = e; 2116: return edtor; 2117: } 2118: #endif 2119: 2120: /************************** 2121: * Insert constructor information into tree. 2122: * ector pointer to object being constructed 2123: * e code to construct the object 2124: * sdtor function to destruct the object 2125: */ 2126: 2127: #if SCPP 2128: elem *el_ctor(elem *ector,elem *e,symbol *sdtor) 2129: { 2130: //printf("el_ctor(ector = %p, e = %p, sdtor = %p)\n", ector, e, sdtor); 2131: //printf("stdor = '%s'\n", cpp_prettyident(sdtor)); 2132: //printf("e:\n"); elem_print(e); 2133: if (ector) 2134: { 2135: if (sdtor) 2136: { 2137: if (sdtor->Sfunc->Fbody) 2138: { 2139: n2_instantiate_memfunc(sdtor); 2140: } 2141: // Causes symbols to be written out prematurely when 2142: // writing precompiled headers. 2143: // Moved to outelem(). 2144: //nwc_mustwrite(sdtor); 2145: } 2146: if (!sdtor || ector->Eoper == OPcall || 2147: (ector->Eoper == OPrelconst && !(sytab[ector->EV.sp.Vsym->Sclass] & SCSS)) 2148: #if TX86 2149: // Not ambient memory model 2150: || (tyfarfunc(sdtor->ty()) ? !LARGECODE : LARGECODE) 2151: #endif 2152: ) 2153: { 2154: el_free(ector); 2155: } 2156: else 2157: { 2158: ector = el_unat(OPctor,ector->ET,ector); 2159: ector->EV.eop.Edtor = sdtor; 2160: symbol_debug(sdtor); 2161: if (e) 2162: e = el_bint(OPinfo,e->ET,ector,e); 2163: else 2164: e = ector; 2165: } 2166: } 2167: return e; 2168: } 2169: #endif 2170: 2171: /************************** 2172: * Insert destructor information into tree. 2173: * edtor pointer to object being destructed 2174: * e code to do the destruction 2175: */ 2176: 2177: elem *el_dtor(elem *edtor,elem *e) 2178: { 2179: if (edtor) 2180: { 2181: edtor = el_unat(OPdtor,edtor->ET,edtor); 2182: if (e) 2183: e = el_bint(OPcomma,e->ET,edtor,e); 2184: else 2185: e = edtor; 2186: } 2187: return e; 2188: } 2189: 2190: /********************************** 2191: * Create an elem of the constant 0, of the type t. 2192: */ 2193: 2194: elem *el_zero(type *t) 2195: { 2196: elem *e; 2197: 2198: assert(PARSER); 2199: 2200: e = el_calloc(); 2201: e->Eoper = OPconst; 2202: e->ET = t; 2203: if (t) 2204: { 2205: type_debug(t); 2206: e->ET->Tcount++; 2207: } 2208: return(e); 2209: } 2210: 2211: /******************* 2212: * Find and return pointer to parent of e starting at *pe. 2213: * Return NULL if can't find it. 2214: */ 2215: 2216: elem ** el_parent(elem *e,elem **pe) 2217: { 2218: assert(e && pe && *pe); 2219: elem_debug(e); 2220: elem_debug(*pe); 2221: if (e == *pe) 2222: return pe; 2223: else if (OTunary((*pe)->Eoper)) 2224: return el_parent(e,&((*pe)->E1)); 2225: else if (OTbinary((*pe)->Eoper)) 2226: { elem **pe2; 2227: 2228: return ((pe2 = el_parent(e,&((*pe)->E1))) != 0) ? pe2 2229: : el_parent(e,&((*pe)->E2)); 2230: } 2231: else 2232: return NULL; 2233: } 2234: 2235: /******************************* 2236: * Return !=0 if trees match. 2237: */ 2238: 2239: static int gmatch2; // kludge for el_match2() 2240: 2241: int el_match(elem *n1,elem *n2) 2242: { unsigned op; 2243: tym_t tym,tym2; 2244: 2245: L1: 2246: if (n1 == n2) 2247: return TRUE; 2248: if (!n1 || !n2) 2249: goto nomatch; 2250: elem_debug(n1); 2251: elem_debug(n2); 2252: 2253: if ((op = n1->Eoper) != n2->Eoper) 2254: goto nomatch; 2255: 2256: if ((tym = typemask(n1)) != (tym2 = typemask(n2))) 2257: { 2258: #if TX86 2259: if ((tym & ~mTYbasic) != (tym2 & ~mTYbasic)) 2260: #else 2261: if ((tym & ~mTYbasic & ~mTYMAN) != (tym2 & ~mTYbasic & ~mTYMAN)) 2262: #endif 2263: { 2264: if (!(gmatch2 & 2)) 2265: goto nomatch; 2266: } 2267: tym = tybasic(tym); 2268: tym2 = tybasic(tym2); 2269: if (tyequiv[tym] != tyequiv[tym2] && 2270: !((gmatch2 & 8) && touns(tym) == touns(tym2)) 2271: ) 2272: goto nomatch; 2273: gmatch2 &= ~8; 2274: } 2275: 2276: if (OTunary(op)) 2277: { 2278: L2: 2279: if (PARSER) 2280: { 2281: n1 = n1->E1; 2282: n2 = n2->E1; 2283: assert(n1 && n2); 2284: goto L1; 2285: } 2286: else if (OPTIMIZER) 2287: { 2288: if (op == OPstrpar || op == OPstrctor) 2289: { if (/*n1->Enumbytes != n2->Enumbytes ||*/ n1->ET != n2->ET) 2290: goto nomatch; 2291: } 2292: n1 = n1->E1; 2293: n2 = n2->E1; 2294: assert(n1 && n2); 2295: goto L1; 2296: } 2297: else 2298: { 2299: if (n1->E1 == n2->E1) 2300: goto ismatch; 2301: n1 = n1->E1; 2302: n2 = n2->E1; 2303: assert(n1 && n2); 2304: goto L1; 2305: } 2306: } 2307: else if (OTbinary(op)) 2308: { 2309: if (!PARSER) 2310: { 2311: if (op == OPstreq) 2312: { if (/*n1->Enumbytes != n2->Enumbytes ||*/ n1->ET != n2->ET) 2313: goto nomatch; 2314: } 2315: } 2316: if (el_match(n1->E2,n2->E2)) 2317: { 2318: goto L2; // check left tree 2319: } 2320: goto nomatch; 2321: } 2322: else /* leaf elem */ 2323: { unsigned n; 2324: 2325: switch (op) 2326: { 2327: case OPconst: 2328: if (gmatch2 & 1) 2329: break; 2330: Lagain: 2331: switch (tybasic(tym)) 2332: { 2333: case TYshort: 2334: case TYwchar_t: 2335: case TYushort: 2336: case TYchar16: 2337: case_short: 2338: if (n1->EV.Vshort != n2->EV.Vshort) 2339: goto nomatch; 2340: break; 2341: case TYlong: 2342: case TYulong: 2343: case TYdchar: 2344: case_long: 2345: if (n1->EV.Vlong != n2->EV.Vlong) 2346: goto nomatch; 2347: break; 2348: case TYllong: 2349: case TYullong: 2350: case_llong: 2351: if (n1->EV.Vllong != n2->EV.Vllong) 2352: goto nomatch; 2353: break; 2354: case TYcent: 2355: case TYucent: 2356: if (n1->EV.Vcent.lsw != n2->EV.Vcent.lsw || 2357: n1->EV.Vcent.msw != n2->EV.Vcent.msw) 2358: goto nomatch; 2359: break; 2360: case TYenum: 2361: if (PARSER) 2362: { tym = n1->ET->Tnext->Tty; 2363: goto Lagain; 2364: } 2365: case TYint: 2366: case TYuint: 2367: if (intsize == SHORTSIZE) 2368: goto case_short; 2369: else 2370: goto case_long; 2371: 2372: #if TX86 2373: #if JHANDLE 2374: case TYjhandle: 2375: #endif 2376: case TYnullptr: 2377: case TYnptr: 2378: case TYsptr: 2379: case TYcptr: 2380: if (NPTRSIZE == SHORTSIZE) 2381: goto case_short; 2382: else if (NPTRSIZE == LONGSIZE) 2383: goto case_long; 2384: else 2385: { assert(NPTRSIZE == LLONGSIZE); 2386: goto case_llong; 2387: } 2388: #endif 2389: 2390: case TYbool: 2391: case TYchar: 2392: case TYuchar: 2393: case TYschar: 2394: if (n1->EV.Vschar != n2->EV.Vschar) 2395: goto nomatch; 2396: break; 2397: #if TX86 2398: case TYfptr: 2399: case TYhptr: 2400: case TYvptr: 2401: 2402: /* Far pointers on the 386 are longer than 2403: any integral type... 2404: */ 2405: if (memcmp(&n1->EV,&n2->EV,tysize[tybasic(tym)])) 2406: goto nomatch; 2407: break; 2408: #endif 2409: /* Compare bit patterns w/o worrying about 2410: exceptions, unordered comparisons, etc. 2411: */ 2412: case TYfloat: 2413: case TYifloat: 2414: if (memcmp(&n1->EV,&n2->EV,sizeof(n1->EV.Vfloat))) 2415: goto nomatch; 2416: break; 2417: 2418: case TYdouble: 2419: case TYdouble_alias: 2420: case TYidouble: 2421: if (memcmp(&n1->EV,&n2->EV,sizeof(n1->EV.Vdouble))) 2422: goto nomatch; 2423: break; 2424: 2425: case TYldouble: 2426: case TYildouble: 2427: #if LNGDBLSIZE > 10 2428: /* sizeof is 12, but actual size is 10 */ 2429: if (memcmp(&n1->EV,&n2->EV,10)) 2430: #else 2431: if (memcmp(&n1->EV,&n2->EV,sizeof(n1->EV.Vldouble))) 2432: #endif 2433: goto nomatch; 2434: break; 2435: 2436: case TYcfloat: 2437: if (memcmp(&n1->EV,&n2->EV,sizeof(n1->EV.Vcfloat))) 2438: goto nomatch; 2439: break; 2440: 2441: case TYcdouble: 2442: if (memcmp(&n1->EV,&n2->EV,sizeof(n1->EV.Vcdouble))) 2443: goto nomatch; 2444: break; 2445: 2446: case TYcldouble: 2447: #if LNGDBLSIZE > 10 2448: /* sizeof is 12, but actual size of each part is 10 */ 2449: if (memcmp(&n1->EV,&n2->EV,10) || 2450: memcmp(&n1->EV.Vldouble + 1, &n2->EV.Vldouble + 1, 10)) 2451: #else 2452: if (memcmp(&n1->EV,&n2->EV,sizeof(n1->EV.Vcldouble))) 2453: #endif 2454: goto nomatch; 2455: break; 2456: case TYvoid: 2457: break; // voids always match 2458: #if SCPP 2459: case TYident: 2460: assert(errcnt); 2461: goto nomatch; 2462: #endif 2463: default: 2464: #ifdef DEBUG 2465: elem_print(n1); 2466: #endif 2467: assert(0); 2468: } 2469: break; 2470: case OPrelconst: 2471: case OPvar: 2472: #if SCPP 2473: case OPsizeof: 2474: #endif 2475: symbol_debug(n1->EV.sp.Vsym); 2476: symbol_debug(n2->EV.sp.Vsym); 2477: if (n1->EV.sp.Voffset != n2->EV.sp.Voffset) 2478: goto nomatch; 2479: #if SCPP 2480: if (gmatch2 & 4) 2481: { 2482: #if 0 2483: printf("------- symbols ---------\n"); 2484: symbol_print(n1->EV.sp.Vsym); 2485: symbol_print(n2->EV.sp.Vsym); 2486: printf("\n"); 2487: #endif 2488: if (/*strcmp(n1->EV.sp.Vsym->Sident, n2->EV.sp.Vsym->Sident) &&*/ 2489: n1->EV.sp.Vsym != n2->EV.sp.Vsym && 2490: (!n1->EV.sp.Vsym->Ssequence || n1->EV.sp.Vsym->Ssequence != n2->EV.sp.Vsym->Ssequence)) 2491: goto nomatch; 2492: } 2493: else 2494: #endif 2495: { 2496: if (n1->EV.sp.Vsym != n2->EV.sp.Vsym) 2497: goto nomatch; 2498: } 2499: break; 2500: case OPasm: 2501: case OPstring: 2502: case OPhstring: 2503: if (n1->EV.ss.Vstrlen != (n = n2->EV.ss.Vstrlen) || 2504: n1->EV.ss.Voffset != n2->EV.ss.Voffset || 2505: memcmp(n1->EV.ss.Vstring,n2->EV.ss.Vstring,n)) 2506: goto nomatch; /* check bytes in the string */ 2507: break; 2508: case OPstrthis: 2509: case OPframeptr: 2510: case OPhalt: 2511: case OPgot: 2512: break; 2513: #if SCPP 2514: case OPmark: 2515: break; 2516: #endif 2517: default: 2518: #ifdef DEBUG 2519: WROP(op); 2520: #endif 2521: assert(0); 2522: } 2523: ismatch: 2524: return TRUE; 2525: } 2526: assert(0); 2527: /* NOTREACHED */ 2528: 2529: nomatch: 2530: return FALSE; 2531: } 2532: 2533: /********************************* 2534: * Kludge on el_match(). Same, but ignore differences in OPconst. 2535: */ 2536: 2537: int el_match2(elem *n1,elem *n2) 2538: { int result; 2539: 2540: gmatch2 = 1; 2541: result = el_match(n1,n2); 2542: gmatch2 = 0; 2543: return result; 2544: } 2545: 2546: /********************************* 2547: * Kludge on el_match(). Same, but ignore differences in type modifiers. 2548: */ 2549: 2550: int el_match3(elem *n1,elem *n2) 2551: { int result; 2552: 2553: gmatch2 = 2; 2554: result = el_match(n1,n2); 2555: gmatch2 = 0; 2556: return result; 2557: } 2558: 2559: /********************************* 2560: * Kludge on el_match(). Same, but ignore differences in spelling of var's. 2561: */ 2562: 2563: int el_match4(elem *n1,elem *n2) 2564: { int result; 2565: 2566: gmatch2 = 2|4; 2567: result = el_match(n1,n2); 2568: gmatch2 = 0; 2569: return result; 2570: } 2571: 2572: /********************************* 2573: * Kludge on el_match(). Same, but regard signed/unsigned as equivalent. 2574: */ 2575: 2576: int el_match5(elem *n1,elem *n2) 2577: { int result; 2578: 2579: gmatch2 = 8; 2580: result = el_match(n1,n2); 2581: gmatch2 = 0; 2582: return result; 2583: } 2584: 2585: /****************************** 2586: * Extract long value from constant parser elem. 2587: */ 2588: 2589: targ_llong el_tolongt(elem *e) 2590: { targ_llong result; 2591: char parsersave = PARSER; 2592: 2593: PARSER = 1; 2594: result = el_tolong(e); 2595: PARSER = parsersave; 2596: return result; 2597: } 2598: 2599: /****************************** 2600: * Extract long value from constant elem. 2601: */ 2602: 2603: targ_llong el_tolong(elem *e) 2604: { targ_llong result; 2605: tym_t ty; 2606: 2607: elem_debug(e); 2608: #if SCPP 2609: if (e->Eoper == OPsizeof) 2610: { 2611: e->Eoper = OPconst; 2612: e->EV.Vllong = type_size(e->EV.sp.Vsym->Stype); 2613: } 2614: #endif 2615: #ifdef DEBUG 2616: if (e->Eoper != OPconst) 2617: elem_print(e); 2618: #endif 2619: assert(e->Eoper == OPconst); 2620: ty = tybasic(typemask(e)); 2621: L1:
warning C4102: 'L1' : unreferenced label
2622: switch (ty) 2623: { 2624: case TYchar: 2625: if (config.flags & CFGuchar) 2626: goto Uchar; 2627: /* FALL-THROUGH */ 2628: case TYschar: 2629: result = e->EV.Vschar; 2630: break; 2631: case TYuchar: 2632: case TYbool: 2633: Uchar: 2634: result = e->EV.Vuchar; 2635: break; 2636: case TYshort: 2637: Ishort: 2638: result = e->EV.Vshort; 2639: break; 2640: case TYushort: 2641: case TYwchar_t: 2642: case TYchar16: 2643: Ushort: 2644: result = e->EV.Vushort; 2645: break; 2646: #if SCPP && TX86 2647: case TYenum: 2648: assert(PARSER); 2649: ty = e->ET->Tnext->Tty; 2650: goto L1; 2651: #endif 2652: 2653: #if TX86 2654: #if JHANDLE 2655: case TYjhandle: 2656: #endif 2657: case TYnullptr: 2658: case TYnptr: 2659: case TYsptr: 2660: case TYcptr: 2661: if (NPTRSIZE == SHORTSIZE) 2662: goto Ushort; 2663: if (NPTRSIZE == LONGSIZE) 2664: goto Ulong; 2665: if (NPTRSIZE == LLONGSIZE) 2666: goto Ullong; 2667: assert(0); 2668: #endif 2669: 2670: case TYuint: 2671: if (intsize == SHORTSIZE) 2672: goto Ushort; 2673: goto Ulong; 2674: 2675: case TYulong: 2676: case TYdchar: 2677: case TYfptr: 2678: #if TX86 2679: case TYhptr: 2680: #endif 2681: case TYvptr: 2682: case TYvoid: /* some odd cases */ 2683: Ulong: 2684: result = e->EV.Vulong; 2685: break; 2686: 2687: #if TX86 2688: case TYint: 2689: if (intsize == SHORTSIZE) 2690: goto Ishort; 2691: goto Ilong; 2692: 2693: case TYlong: 2694: Ilong: 2695: result = e->EV.Vlong; 2696: break; 2697: #endif 2698: case TYllong: 2699: case TYullong: 2700: Ullong: 2701: result = e->EV.Vullong; 2702: break; 2703: case TYdouble_alias: 2704: case TYldouble: 2705: case TYdouble: 2706: case TYfloat: 2707: case TYildouble: 2708: case TYidouble: 2709: case TYifloat: 2710: case TYcldouble: 2711: case TYcdouble: 2712: case TYcfloat: 2713: result = (targ_llong)el_toldouble(e); 2714: break; 2715: 2716: #if SCPP 2717: case TYmemptr: 2718: ty = tybasic(tym_conv(e->ET)); 2719: goto L1; 2720: #endif 2721: 2722: case TYcent: 2723: case TYucent: 2724: goto Ullong; // should do better than this when actually doing arithmetic on cents 2725: 2726: default: 2727: #if SCPP 2728: // Can happen as result of syntax errors 2729: assert(errcnt); 2730: #else 2731: #ifdef DEBUG 2732: elem_print(e); 2733: #endif 2734: assert(0); 2735: #endif 2736: } 2737: return result; 2738: } 2739: 2740: /*********************************** 2741: * Determine if constant e is all ones or all zeros. 2742: * Input: 2743: * bit 0: all zeros 2744: * 1: 1 2745: * -1: all ones 2746: */ 2747: 2748: int el_allbits(elem *e,int bit) 2749: { targ_llong value; 2750: 2751: elem_debug(e); 2752: assert(e->Eoper == OPconst); 2753: value = e->EV.Vullong; 2754: switch (tysize(e->Ety)) 2755: { 2756: case 1: value = (signed char) value; 2757: break; 2758: case 2: value = (short) value; 2759: break; 2760: case 4: value = (int) value; 2761: break; 2762: case 8: break; 2763: default: 2764: assert(0); 2765: } 2766: if (bit == -1) 2767: value++; 2768: else if (bit == 1) 2769: value--; 2770: return value == 0; 2771: } 2772: 2773: /******************************************** 2774: * Determine if constant e is a 32 bit or less value, or is a 32 bit value sign extended to 64 bits. 2775: */ 2776: 2777: int el_signx32(elem *e) 2778: { 2779: elem_debug(e); 2780: assert(e->Eoper == OPconst); 2781: if (tysize(e->Ety) == 8) 2782: { 2783: if (e->EV.Vullong != (int)e->EV.Vullong) 2784: return FALSE; 2785: } 2786: return TRUE; 2787: } 2788: 2789: /****************************** 2790: * Extract long double value from constant elem. 2791: * Silently ignore types which are not floating point values. 2792: */ 2793: 2794: targ_ldouble el_toldouble(elem *e) 2795: { targ_ldouble result; 2796: 2797: elem_debug(e); 2798: assert(cnst(e)); 2799: #if TX86 2800: switch (tybasic(typemask(e))) 2801: { 2802: case TYfloat: 2803: case TYifloat: 2804: result = e->EV.Vfloat; 2805: break; 2806: case TYdouble: 2807: case TYidouble: 2808: case TYdouble_alias: 2809: result = e->EV.Vdouble; 2810: break; 2811: case TYldouble: 2812: case TYildouble: 2813: result = e->EV.Vldouble; 2814: break; 2815: default: 2816: result = 0; 2817: break; 2818: } 2819: #else 2820: switch (tysize[tybasic(typemask(e))]) 2821: { 2822: case FLOATSIZE: // TYfloat 2823: result = e->EV.Vfloat; 2824: break; 2825: case DOUBLESIZE: // TYdouble 2826: result = e->EV.Vdouble; 2827: break; 2828: #if DOUBLESIZE != LNGDBLSIZE 2829: case LNGDBLSIZE: // TYldouble 2830: #ifdef LNGHDBLSIZE 2831: case LNGHDBLSIZE: 2832: #endif 2833: result = e->EV.Vldouble; 2834: break; 2835: #endif 2836: default: 2837: result = 0; 2838: break; 2839: } 2840: #endif 2841: return result; 2842: } 2843: 2844: /******************************** 2845: * Is elem type-dependent or value-dependent? 2846: * Return !=0 if so. 2847: */ 2848: 2849: int el_isdependent(elem *e) 2850: { 2851: if (type_isdependent(e->ET)) 2852: return 1; 2853: while (1) 2854: { 2855: if (e->PEFflags & PEFdependent) 2856: return 1; 2857: if (OTunary(e->Eoper)) 2858: e = e->E1; 2859: else if (OTbinary(e->Eoper)) 2860: { if (el_isdependent(e->E2)) 2861: return 1; 2862: e = e->E1; 2863: } 2864: else 2865: break; 2866: } 2867: return 0; 2868: } 2869: 2870: /**************************************** 2871: * Return alignment size of elem. 2872: */ 2873: 2874: unsigned el_alignsize(elem *e) 2875: { 2876: tym_t tym = tybasic(e->Ety); 2877: unsigned alignsize = tyalignsize(tym); 2878: if (alignsize == (unsigned)-1) 2879: { 2880: assert(e->ET); 2881: alignsize = type_alignsize(e->ET); 2882: } 2883: return alignsize; 2884: } 2885: 2886: /******************************* 2887: * Check for errors in a tree. 2888: */ 2889: 2890: #ifdef DEBUG 2891: 2892: void el_check(elem *e) 2893: { 2894: elem_debug(e); 2895: while (1) 2896: { 2897: if (OTunary(e->Eoper)) 2898: e = e->E1; 2899: else if (OTbinary(e->Eoper)) 2900: { el_check(e->E2); 2901: e = e->E1; 2902: } 2903: else 2904: break; 2905: } 2906: } 2907: 2908: #endif 2909: 2910: /******************************* 2911: * Write out expression elem. 2912: */ 2913: 2914: #ifdef DEBUG 2915: 2916: void elem_print(elem *e) 2917: { static int nestlevel = 0; 2918: int i; 2919: tym_t tym; 2920: 2921: nestlevel++; 2922: for (i = nestlevel; --i;) dbg_printf(" "); 2923: dbg_printf("el:%p ",e); 2924: if (!e) 2925: { dbg_printf("\n"); 2926: goto ret; 2927: } 2928: elem_debug(e); 2929: if (configv.addlinenumbers) 2930: { 2931: e->Esrcpos.print("elem_print"); 2932: } 2933: if (!PARSER) 2934: { dbg_printf("cnt=%d ",e->Ecount); 2935: if (!OPTIMIZER) 2936: dbg_printf("cs=%d ",e->Ecomsub); 2937: } 2938: WROP(e->Eoper); 2939: dbg_printf(" "); 2940: if (SCPP && PARSER) 2941: { 2942: if (e->ET) 2943: { type_debug(e->ET); 2944: if (tybasic(e->ET->Tty) == TYstruct 2945: #if !TX86 2946: && (e->PEFflags & PEFstrsize) 2947: #endif 2948: ) 2949: dbg_printf("%d ", (int)type_size(e->ET)); 2950: WRTYxx(e->ET->Tty); 2951: } 2952: } 2953: else 2954: { 2955: if ((e->Eoper == OPstrpar || e->Eoper == OPstrctor || e->Eoper == OPstreq) || 2956: e->Ety == TYstruct) 2957: if (e->ET) 2958: dbg_printf("%d ", (int)type_size(e->ET)); 2959: WRTYxx(e->Ety); 2960: } 2961: if (OTunary(e->Eoper)) 2962: { 2963: if (e->E2) 2964: dbg_printf("%p %p\n",e->E1,e->E2); 2965: else 2966: dbg_printf("%p\n",e->E1); 2967: elem_print(e->E1); 2968: } 2969: else if (OTbinary(e->Eoper)) 2970: { 2971: if (!PARSER && e->Eoper == OPstreq) 2972: dbg_printf("bytes=%d ", (int)type_size(e->ET)); 2973: dbg_printf("%p %p\n",e->E1,e->E2); 2974: elem_print(e->E1); 2975: elem_print(e->E2); 2976: } 2977: else 2978: { 2979: switch (e->Eoper) 2980: { 2981: case OPrelconst: 2982: dbg_printf(" %lld+&",(unsigned long long)e->Eoffset); 2983: dbg_printf(" %s",e->EV.sp.Vsym->Sident); 2984: break; 2985: case OPvar: 2986: if (e->Eoffset) 2987: dbg_printf(" %lld+",(unsigned long long)e->Eoffset); 2988: dbg_printf(" %s",e->EV.sp.Vsym->Sident); 2989: break; 2990: case OPasm: 2991: case OPstring: 2992: case OPhstring: 2993: dbg_printf(" '%s',%lld\n",e->EV.ss.Vstring,(unsigned long long)e->EV.ss.Voffset); 2994: break; 2995: case OPconst: 2996: tym = tybasic(typemask(e)); 2997: case_tym: 2998: switch (tym) 2999: { case TYbool: 3000: case TYchar: 3001: case TYschar: 3002: case TYuchar: 3003: dbg_printf("%d ",e->EV.Vuchar); 3004: break; 3005: #if TX86 3006: case TYsptr: 3007: #if JHANDLE 3008: case TYjhandle: 3009: #endif 3010: case TYnullptr: 3011: case TYnptr: 3012: case TYcptr: 3013: #endif 3014: if (NPTRSIZE == LONGSIZE) 3015: goto L1; 3016: if (NPTRSIZE == SHORTSIZE) 3017: goto L3; 3018: if (NPTRSIZE == LLONGSIZE) 3019: goto L2; 3020: assert(0); 3021: break; 3022: case TYenum: 3023: if (PARSER) 3024: { tym = e->ET->Tnext->Tty; 3025: goto case_tym; 3026: } 3027: case TYint: 3028: case TYuint: 3029: case TYvoid: /* in case (void)(1) */ 3030: #if TX86 3031: if (tysize[TYint] == LONGSIZE) 3032: goto L1; 3033: #endif 3034: case TYshort: 3035: case TYwchar_t: 3036: case TYushort: 3037: case TYchar16: 3038: L3: 3039: #if TX86 3040: dbg_printf("%d ",e->EV.Vint); 3041: break; 3042: #endif 3043: case TYlong: 3044: case TYulong: 3045: case TYdchar: 3046: case TYfptr: 3047: #if TX86 3048: case TYvptr: 3049: case TYhptr: 3050: #endif 3051: L1: 3052: dbg_printf("%dL ",e->EV.Vlong); 3053: break; 3054: 3055: case TYllong: 3056: L2: 3057: dbg_printf("%lldLL ",e->EV.Vllong); 3058: break; 3059: 3060: case TYullong: 3061: dbg_printf("%lluLL ",e->EV.Vullong); 3062: break; 3063: 3064: case TYcent: 3065: case TYucent: 3066: dbg_printf("%lluLL+%lluLL ", e->EV.Vcent.msw, e->EV.Vcent.lsw); 3067: break; 3068: 3069: case TYfloat: 3070: dbg_printf("%gf ",(double)e->EV.Vfloat); 3071: break; 3072: case TYdouble: 3073: case TYdouble_alias: 3074: dbg_printf("%g ",(double)e->EV.Vdouble); 3075: break; 3076: case TYldouble: 3077: dbg_printf("%Lg ", e->EV.Vldouble); 3078: break; 3079: 3080: case TYifloat: 3081: dbg_printf("%gfi ", (double)e->EV.Vfloat); 3082: break; 3083: 3084: case TYidouble: 3085: dbg_printf("%gi ", (double)e->EV.Vdouble); 3086: break; 3087: 3088: case TYildouble: 3089: dbg_printf("%gLi ", (double)e->EV.Vldouble); 3090: break; 3091: 3092: case TYcfloat: 3093: dbg_printf("%gf+%gfi ", (double)e->EV.Vcfloat.re, (double)e->EV.Vcfloat.im); 3094: break; 3095: 3096: case TYcdouble: 3097: dbg_printf("%g+%gi ", (double)e->EV.Vcdouble.re, (double)e->EV.Vcdouble.im); 3098: break; 3099: 3100: case TYcldouble: 3101: dbg_printf("%gL+%gLi ", (double)e->EV.Vcldouble.re, (double)e->EV.Vcldouble.im); 3102: break; 3103: 3104: case TYident: 3105: dbg_printf("'%s' ", e->ET->Tident); 3106: break; 3107: 3108: default: 3109: dbg_printf("Invalid type "); 3110: WRTYxx(typemask(e)); 3111: /*assert(0);*/ 3112: } 3113: break; 3114: default: 3115: break; 3116: } 3117: dbg_printf("\n"); 3118: } 3119: ret: 3120: nestlevel--; 3121: } 3122: 3123: #endif 3124: 3125: /********************************** 3126: * Hydrate an elem. 3127: */ 3128: 3129: #if HYDRATE 3130: void el_hydrate(elem **pe) 3131: { 3132: elem *e; 3133: 3134: if (!isdehydrated(*pe)) 3135: return; 3136: 3137: assert(PARSER); 3138: e = (elem *) ph_hydrate(pe); 3139: elem_debug(e); 3140: #ifdef DEBUG 3141: if (!(e->Eoper < OPMAX)) 3142: dbg_printf("e = x%lx, e->Eoper = %d\n",e,e->Eoper); 3143: #endif 3144: debug_assert(e->Eoper < OPMAX); 3145: type_hydrate(&e->ET); 3146: if (configv.addlinenumbers) 3147: { filename_translate(&e->Esrcpos); 3148: srcpos_hydrate(&e->Esrcpos); 3149: } 3150: if (EOP(e)) 3151: { el_hydrate(&e->E1); 3152: if (EBIN(e)) 3153: el_hydrate(&e->E2); 3154: #if SCPP 3155: else if (e->Eoper == OPctor) 3156: { symbol_hydrate(&e->EV.eop.Edtor); 3157: symbol_debug(e->EV.eop.Edtor); 3158: } 3159: #endif 3160: } 3161: else 3162: { 3163: switch (e->Eoper) 3164: { case OPstring: 3165: case OPasm: 3166: ph_hydrate(&e->EV.ss.Vstring); 3167: break; 3168: 3169: case OPrelconst: 3170: //if (tybasic(e->ET->Tty) == TYmemptr) 3171: //el_hydrate(&e->EV.sm.ethis); 3172: case OPvar: 3173: #if TX86 3174: symbol_hydrate(&e->EV.sp.Vsym); 3175: #else 3176: ph_hydrate(&e->EV.sp.Vsym); 3177: #endif 3178: symbol_debug(e->EV.sp.Vsym); 3179: break; 3180: } 3181: } 3182: } 3183: #endif 3184: 3185: /********************************** 3186: * Dehydrate an elem. 3187: */ 3188: 3189: #if DEHYDRATE 3190: void el_dehydrate(elem **pe) 3191: { elem *e; 3192: 3193: if ((e = *pe) == NULL || isdehydrated(e)) 3194: return; 3195: 3196: assert(PARSER); 3197: elem_debug(e); 3198: #ifdef DEBUG 3199: if (!(e->Eoper < OPMAX)) 3200: dbg_printf("e = x%lx, e->Eoper = %d\n",e,e->Eoper); 3201: #endif 3202: debug_assert(e->Eoper < OPMAX); 3203: ph_dehydrate(pe); 3204: #if DEBUG_XSYMGEN 3205: if (xsym_gen && ph_in_head(e)) 3206: return; 3207: #endif 3208: type_dehydrate(&e->ET); 3209: #if TX86 3210: if (configv.addlinenumbers) 3211: srcpos_dehydrate(&e->Esrcpos); 3212: #endif 3213: if (EOP(e)) 3214: { el_dehydrate(&e->E1); 3215: if (EBIN(e)) 3216: el_dehydrate(&e->E2); 3217: #if SCPP 3218: else if (e->Eoper == OPctor) 3219: symbol_dehydrate(&e->EV.eop.Edtor); 3220: #endif 3221: } 3222: else 3223: { 3224: switch (e->Eoper) 3225: { case OPstring: 3226: case OPasm: 3227: ph_dehydrate(&e->EV.ss.Vstring); 3228: break; 3229: case OPrelconst: 3230: //if (tybasic(e->ET->Tty) == TYmemptr) 3231: //el_dehydrate(&e->EV.sm.ethis); 3232: case OPvar: 3233: #if TX86 3234: symbol_dehydrate(&e->EV.sp.Vsym); 3235: #else 3236: ph_dehydrate(&e->EV.sp.Vsym); 3237: #endif 3238: break; 3239: } 3240: } 3241: } 3242: #endif 3243: 3244: #endif /* !SPP */ 3245: