1: // Copyright (C) 1984-1998 by Symantec
  2: // Copyright (C) 2000-2010 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: #if !SPP
 14: 
 15: #include        <stdio.h>
 16: #include        <string.h>
 17: #include        <stdlib.h>
 18: #include        <time.h>
 19: #include        "cc.h"
 20: #include        "oper.h"
 21: #include        "global.h"
 22: #include        "el.h"
 23: #include        "type.h"
 24: #include        "dt.h"
 25: 
 26: static char __file__[] = __FILE__;      /* for tassert.h                */
 27: #include        "tassert.h"
 28: 
 29: static dt_t *dt_freelist;
 30: 
 31: /**********************************************
 32:  * Allocate a data definition struct.
 33:  */
 34: 
 35: dt_t *dt_calloc(char dtx)
 36: {
 37:     dt_t *dt;
 38:     static dt_t dtzero;
 39: 
 40:     if (dt_freelist)
 41:     {
 42:         dt = dt_freelist;
 43:         dt_freelist = dt->DTnext;
 44:         *dt = dtzero;
 45:     }
 46:     else
 47:         dt = (dt_t *) mem_fcalloc(sizeof(dt_t));
 48:     dt->dt = dtx;
 49:     return dt;
 50: }
 51: 
 52: /**********************************************
 53:  * Free a data definition struct.
 54:  */
 55: 
 56: void dt_free(dt_t *dt)
 57: {   dt_t *dtn;
 58: 
 59:     for (; dt; dt = dtn)
 60:     {
 61:         switch (dt->dt)
 62:         {
 63:             case DT_abytes:
 64:             case DT_nbytes:
 65:                 mem_free(dt->DTpbytes);
 66:                 break;
 67:         }
 68:         dtn = dt->DTnext;
 69:         dt->DTnext = dt_freelist;
 70:         dt_freelist = dt;
 71:     }
 72: }
 73: 
 74: /*********************************
 75:  * Free free list.
 76:  */
 77: 
 78: void dt_term()
 79: {
 80: #if TERMCODE
 81:     dt_t *dtn;
 82: 
 83:     while (dt_freelist)
 84:     {   dtn = dt_freelist->DTnext;
 85:         mem_ffree(dt_freelist);
 86:         dt_freelist = dtn;
 87:     }
 88: #endif
 89: }
 90: 
 91: 
 92: /**********************
 93:  * Construct a DT_azeros record, and return it.
 94:  * Increment dsout.
 95:  */
 96: 
 97: dt_t **dtnzeros(dt_t **pdtend,targ_size_t size)
 98: {   dt_t *dt;
 99: 
100:     //printf("dtnzeros(x%x)\n",size);
101:     assert((long) size >= 0);
102:     while (*pdtend)
103:         pdtend = &((*pdtend)->DTnext);
104:     if (size)
105:     {   dt = dt_calloc(DT_azeros);
106:         dt->DTazeros = size;
107:         *pdtend = dt;
108:         pdtend = &dt->DTnext;
109: #if SCPP
110:         dsout += size;
111: #endif
112:     }
113:     return pdtend;
114: }
115: 
116: /**********************
117:  * Construct a DTsymsize record.
118:  */
119: 
120: void dtsymsize(symbol *s)
121: {
122:     symbol_debug(s);
123:     s->Sdt = dt_calloc(DT_symsize);
124: }
125: 
126: /**********************
127:  * Construct a DTnbytes record, and return it.
128:  */
129: 
130: dt_t ** dtnbytes(dt_t **pdtend,targ_size_t size,const char *ptr)
131: {   dt_t *dt;
132: 
133:     while (*pdtend)
134:         pdtend = &((*pdtend)->DTnext);
135:     if (size)
136:     {   if (size == 1)
137:         {   dt = dt_calloc(DT_1byte);
138:             dt->DTonebyte = *ptr;
139:         }
140:         else if (size <= 7)
141:         {   dt = dt_calloc(DT_ibytes);
142:             dt->DTn = size;
143:             memcpy(dt->DTdata,ptr,size);
144:         }
145:         else
146:         {
147:             dt = dt_calloc(DT_nbytes);
148:             dt->DTnbytes = size;
149:             dt->DTpbytes = (char *) MEM_PH_MALLOC(size);
150:             memcpy(dt->DTpbytes,ptr,size);
151:         }
152:         *pdtend = dt;
153:         pdtend = &dt->DTnext;
154:     }
155:     return pdtend;
156: }
157: 
158: /**********************
159:  * Construct a DTabytes record, and return it.
160:  */
161: 
162: dt_t **dtabytes(dt_t **pdtend,tym_t ty, targ_size_t offset, targ_size_t size, const char *ptr)
163: {   dt_t *dt;
164: 
165:     while (*pdtend)
166:         pdtend = &((*pdtend)->DTnext);
167: 
168:     dt = dt_calloc(DT_abytes);
169:     dt->DTnbytes = size;
170:     dt->DTpbytes = (char *) MEM_PH_MALLOC(size);
171:     dt->Dty = ty;
172:     dt->DTabytes = offset;
173:     memcpy(dt->DTpbytes,ptr,size);
174: 
175:     *pdtend = dt;
176:     pdtend = &dt->DTnext;
177:     return pdtend;
178: }
179: 
180: /**********************
181:  * Construct a DTibytes record, and return it.
182:  */
183: 
184: dt_t ** dtdword(dt_t **pdtend, int value)
185: {   dt_t *dt;
186: 
187:     while (*pdtend)
188:         pdtend = &((*pdtend)->DTnext);
189:     dt = dt_calloc(DT_ibytes);
190:     dt->DTn = 4;
191: 
192:     union { char* cp; int* lp; } u;
193:     u.cp = dt->DTdata;
194:     *u.lp = value;
195: 
196:     *pdtend = dt;
197:     pdtend = &dt->DTnext;
198:     return pdtend;
199: }
200: 
201: dt_t ** dtsize_t(dt_t **pdtend, targ_size_t value)
202: {   dt_t *dt;
203: 
204:     while (*pdtend)
205:         pdtend = &((*pdtend)->DTnext);
206:     dt = dt_calloc(DT_ibytes);
207:     dt->DTn = NPTRSIZE;
208: 
209:     union { char* cp; int* lp; } u;
210:     u.cp = dt->DTdata;
211:     *u.lp = value;
212:     if (NPTRSIZE == 8)
213:         u.lp[1] = value >> 32;
warning C4293: '>>' : shift count negative or too big, undefined behavior
214: 215: *pdtend = dt; 216: pdtend = &dt->DTnext; 217: return pdtend; 218: } 219: 220: /********************** 221: * Concatenate two dt_t's. 222: */ 223: 224: dt_t ** dtcat(dt_t **pdtend,dt_t *dt) 225: { 226: while (*pdtend) 227: pdtend = &((*pdtend)->DTnext); 228: *pdtend = dt; 229: pdtend = &dt->DTnext; 230: return pdtend; 231: } 232: 233: /********************** 234: * Construct a DTcoff record, and return it. 235: */ 236: 237: dt_t ** dtcoff(dt_t **pdtend,targ_size_t offset) 238: { dt_t *dt; 239: 240: while (*pdtend) 241: pdtend = &((*pdtend)->DTnext); 242: dt = dt_calloc(DT_coff); 243: dt->Dty = TYcptr; 244: dt->DToffset = offset; 245: *pdtend = dt; 246: pdtend = &dt->DTnext; 247: return pdtend; 248: } 249: 250: /********************** 251: * Construct a DTxoff record, and return it. 252: */ 253: 254: dt_t ** dtxoff(dt_t **pdtend,symbol *s,targ_size_t offset,tym_t ty) 255: { dt_t *dt; 256: 257: symbol_debug(s); 258: while (*pdtend) 259: pdtend = &((*pdtend)->DTnext); 260: dt = dt_calloc(DT_xoff); 261: dt->DTsym = s; 262: dt->DToffset = offset; 263: dt->Dty = ty; 264: *pdtend = dt; 265: pdtend = &dt->DTnext; 266: return pdtend; 267: } 268: 269: /************************** 270: * 'Optimize' a list of dt_t's. 271: * (Try to collapse it into one DT_azeros object.) 272: */ 273: 274: void dt_optimize(dt_t *dt) 275: { dt_t *dtn; 276: 277: if (dt) 278: { for (; 1; dt = dtn) 279: { 280: dtn = dt->DTnext; 281: if (!dtn) 282: break; 283: switch (dt->dt) 284: { 285: case DT_azeros: 286: if (dtn->dt == DT_1byte && dtn->DTonebyte == 0) 287: { 288: dt->DTazeros += 1; 289: goto L1; 290: } 291: else if (dtn->dt == DT_azeros) 292: { 293: dt->DTazeros += dtn->DTazeros; 294: goto L1; 295: } 296: break; 297: 298: case DT_1byte: 299: if (dt->DTonebyte == 0) 300: { 301: if (dtn->dt == DT_1byte && dtn->DTonebyte == 0) 302: { 303: dt->DTazeros = 2; 304: goto L1; 305: } 306: else if (dtn->dt == DT_azeros) 307: { 308: dt->DTazeros = 1 + dtn->DTazeros; 309: L1: 310: dt->dt = DT_azeros; 311: dt->DTnext = dtn->DTnext; 312: dtn->DTnext = NULL; 313: dt_free(dtn); 314: dtn = dt; 315: } 316: } 317: break; 318: } 319: } 320: } 321: } 322: 323: /************************** 324: * Make a common block for s. 325: */ 326: 327: void init_common(symbol *s) 328: { 329: //printf("init_common('%s')\n", s->Sident); 330: dtnzeros(&s->Sdt,type_size(s->Stype)); 331: if (s->Sdt) 332: s->Sdt->dt = DT_common; 333: } 334: 335: /********************************** 336: * Compute size of a dt 337: */ 338: 339: unsigned dt_size(dt_t *dtstart) 340: { dt_t *dt; 341: unsigned datasize; 342: 343: datasize = 0; 344: for (dt = dtstart; dt; dt = dt->DTnext) 345: { 346: switch (dt->dt) 347: { case DT_abytes: 348: datasize += size(dt->Dty); 349: break; 350: case DT_ibytes: 351: datasize += dt->DTn; 352: break; 353: case DT_nbytes: 354: datasize += dt->DTnbytes; 355: break; 356: case DT_symsize: 357: case DT_azeros: 358: datasize += dt->DTazeros; 359: break; 360: case DT_common: 361: break; 362: case DT_xoff: 363: case DT_coff: 364: datasize += size(dt->Dty); 365: break; 366: case DT_1byte: 367: datasize++; 368: break; 369: default: 370: #ifdef DEBUG 371: dbg_printf("dt = %p, dt = %d\n",dt,dt->dt); 372: #endif 373: assert(0); 374: } 375: } 376: return datasize; 377: } 378: 379: #endif /* !SPP */ 380: