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: