Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20120422210740

Diff

Diff from 1.80 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/cc/ccom/init.c

Annotated File View

plunky
1.80
1 /*      $Id: init.c,v 1.80 2012/04/22 21:07:41 plunky Exp $     */
ragge
1.1
2
ragge
1.8
3 /*
ragge
1.21
4  * Copyright (c) 2004, 2007 Anders Magnusson (ragge@ludd.ltu.se).
ragge
1.8
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 /*
31  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
32  *
33  * Redistribution and use in source and binary forms, with or without
34  * modification, are permitted provided that the following conditions
35  * are met:
36  *
37  * Redistributions of source code and documentation must retain the above
38  * copyright notice, this list of conditions and the following disclaimer.
39  * Redistributions in binary form must reproduce the above copyright
40  * notice, this list of conditions and the following disclaimer in the
41  * documentation and/or other materials provided with the distribution.
42  * All advertising materials mentioning features or use of this software
43  * must display the following acknowledgement:
44  *      This product includes software developed or owned by Caldera
45  *      International, Inc.
46  * Neither the name of Caldera International, Inc. nor the names of other
47  * contributors may be used to endorse or promote products derived from
48  * this software without specific prior written permission.
49  *
50  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
51  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
52  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
53  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
54  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
55  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
59  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
60  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
61  * POSSIBILITY OF SUCH DAMAGE.
62  */
ragge
1.1
63
ragge
1.21
64 #include "pass1.h"
ragge
1.16
65 #include <string.h>
ragge
1.1
66
ragge
1.2
67 /*
gmcgarry
1.35
68  * The following machine-dependent routines may be called during
69  * initialization:
ragge
1.2
70  * 
ragge
1.21
71  * zbits(OFFSZ, int)    - sets int bits of zero at position OFFSZ.
72  * infld(CONSZ off, int fsz, CONSZ val)
73  *                      - sets the bitfield val starting at off and size fsz.
gmcgarry
1.35
74  * ninval(CONSZ off, int fsz, NODE *)
ragge
1.21
75  *                      - prints an integer constant which may have
76  *                        a label associated with it, located at off and
77  *                        size fsz.
ragge
1.15
78  *
79  * Initialization may be of different kind:
80  * - Initialization at compile-time, all values are constants and laid
81  *   out in memory. Static or extern variables outside functions.
82  * - Initialization at run-time, written to their values as code.
83  *
84  * Currently run-time-initialized variables are only initialized by using
85  * move instructions.  An optimization might be to detect that it is
86  * initialized with constants and therefore copied from readonly memory.
87  */
ragge
1.21
88
ragge
1.15
89 /*
ragge
1.21
90  * The base element(s) of an initialized variable is kept in a linked 
91  * list, allocated while initialized.
ragge
1.15
92  *
93  * When a scalar is found, entries are popped of the instk until it's
94  * possible to find an entry for a new scalar; then onstk() is called 
95  * to get the correct type and size of that scalar.
96  *
97  * If a right brace is found, pop the stack until a matching left brace
98  * were found while filling the elements with zeros.  This left brace is
99  * also marking where the current level is for designated initializations.
100  *
101  * Position entries are increased when traversing back down into the stack.
ragge
1.2
102  */
ragge
1.1
103
104 /*
ragge
1.18
105  * Good-to-know entries from symtab:
106  *      soffset - # of bits from beginning of this structure.
107  */
108
109 /*
ragge
1.21
110  * TO FIX:
111  * - Alignment of structs on like i386 char members.
112  */
113
114 /*
ragge
1.1
115  * Struct used in array initialisation.
116  */
117 static struct instk {
118         struct  instk *in_prev/* linked list */
ragge
1.41
119         struct  symtab *in_lnk/* member in structure initializations */
120         struct  symtab *in_sym/* symtab index */
ragge
1.22
121         union   dimfun *in_df;  /* dimenston of array */
122         TWORD   in_t;           /* type for this level */
ragge
1.21
123         int     in_n;           /* number of arrays seen so far */
ragge
1.1
124         int     in_fl;  /* flag which says if this level is controlled by {} */
ragge
1.15
125 } *pstkpbase;
ragge
1.1
126
ragge
1.67
127 int doing_initstatinit;
ragge
1.2
128 static struct symtab *csym;
ragge
1.1
129
ragge
1.15
130 #ifdef PCC_DEBUG
131 static void prtstk(struct instk *in);
132 #endif
ragge
1.2
133
134 /*
ragge
1.21
135  * Linked lists for initializations.
ragge
1.16
136  */
ragge
1.21
137 struct ilist {
138         struct ilist *next;
139         CONSZ off;      /* bit offset of this entry */
140         int fsz;        /* bit size of this entry */
141         NODE *n;        /* node containing this data info */
142 };
143
ragge
1.16
144 struct llist {
145         SLIST_ENTRY(llistnext;
ragge
1.18
146         CONSZ begsz;    /* bit offset of this entry */
ragge
1.21
147         struct ilist *il;
ragge
1.46
148 };
ragge
1.47
149 static SLIST_HEAD(llhllistlpole;
ragge
1.16
150 static CONSZ basesz;
ragge
1.18
151 static int numents/* # of array entries allocated */
ragge
1.16
152
ragge
1.47
153 static struct initctx {
154         struct initctx *prev;
155         struct instk *pstk;
156         struct symtab *psym;
157         struct llh lpole;
158         CONSZ basesz;
159         int numents;
160 } *inilnk;
161
ragge
1.21
162 static struct ilist *
163 getil(struct ilist *nextCONSZ bint szNODE *n)
164 {
165         struct ilist *il = tmpalloc(sizeof(struct ilist));
166
167         il->off = b;
168         il->fsz = sz;
169         il->n = n;
170         il->next = next;
171         return il;
172 }
173
ragge
1.16
174 /*
ragge
1.22
175  * Allocate a new struct defining a block of initializers appended to the
ragge
1.16
176  * end of the llist. Return that entry.
177  */
178 static struct llist *
179 getll(void)
180 {
181         struct llist *ll;
182
183         ll = tmpalloc(sizeof(struct llist));
ragge
1.18
184         ll->begsz = numents * basesz;
ragge
1.23
185         ll->il = NULL;
ragge
1.16
186         SLIST_INSERT_LAST(&lpolellnext);
ragge
1.18
187         numents++;
ragge
1.16
188         return ll;
189 }
190
ragge
1.18
191 /*
192  * Return structure containing off bitnumber.
193  * Allocate more entries, if needed.
194  */
195 static struct llist *
ragge
1.21
196 setll(OFFSZ off)
ragge
1.18
197 {
otto
1.34
198         struct llist *ll = NULL;
ragge
1.18
199
200         /* Ensure that we have enough entries */
201         while (off >= basesz * numents)
otto
1.34
202                  ll = getll();
203
204         if (ll != NULL && ll->begsz <= off && ll->begsz + basesz > off)
205                 return ll;
206
ragge
1.18
207         SLIST_FOREACH(ll, &lpolenext)
208                 if (ll->begsz <= off && ll->begsz + basesz > off)
209                         break;
210         return ll/* ``cannot fail'' */
ragge
1.2
211 }
ragge
1.69
212 char *astypnames[] = { 00"\t.byte""\t.byte""\t.short""\t.short",
213         "\t.word""\t.word""\t.long""\t.long""\t.quad""\t.quad",
214         "ERR""ERR""ERR",
215 };
ragge
1.1
216
ragge
1.69
217 void
ragge
1.66
218 inval(CONSZ offint fszNODE *p)
219 {
ragge
1.69
220         struct symtab *sp;
221         CONSZ val;
222         TWORD t;
223
ragge
1.76
224         if (p->n_op != ICON && p->n_op != FCON) {
ragge
1.66
225                 uerror("constant required");
ragge
1.76
226                 return;
227         }
ragge
1.69
228         if (p->n_type == BOOL) {
229                 if ((U_CONSZ)p->n_lval > 1)
230                         p->n_lval = 1;
231                 p->n_type = BOOL_TYPE;
232         }
233         if (ninval(offfszp))
234                 return/* dealt with in local.c */
235         t = p->n_type;
236         if (t > BTMASK)
237                 t = INTPTR;
238
ragge
1.70
239         val = (CONSZ)(p->n_lval & SZMASK(sztable[t]));
ragge
1.69
240         if (t <= ULONGLONG) {
241                 sp = p->n_sp;
242                 printf("%s ",astypnames[t]);
243                 if (val || sp == NULL)
244                         printf(CONFMTval);
245                 if (val && sp != NULL)
246                         printf("+");
247                 if (sp != NULL) {
248                         if ((sp->sclass == STATIC && sp->slevel > 0)) {
249                                 printf(LABFMTsp->soffset);
250                         } else
251                                 printf("%s"sp->soname ?
252                                     sp->soname : exname(sp->sname));
253                 }
254                 printf("\n");
255         } else
256                 cerror("inval: unhandled type %d", (int)t);
ragge
1.66
257 }
258
ragge
1.70
259 #ifndef MYBFINIT
260
261 static int inbits;
262 static CONSZ xinval;
263 /*
264  * Initialize a bitfield.
ragge
1.72
265  * XXX - use U_CONSZ?
ragge
1.70
266  */
267 void
268 infld(CONSZ offint fszCONSZ val)
269 {
270 #ifdef PCC_DEBUG
271         if (idebug)
272                 printf("infld off %lld, fsz %d, val %lld inbits %d\n",
273                     offfszvalinbits);
274 #endif
275         val &= SZMASK(fsz);
ragge
1.72
276 #if TARGET_ENDIAN == TARGET_BE
277         while (fsz + inbits >= SZCHAR) {
278                 int shsz = SZCHAR-inbits;
279                 xinval = (xinval << shsz) | (val >> (fsz - shsz));
280                 printf("%s " CONFMT "\n",
281                     astypnames[CHAR], xinval & SZMASK(SZCHAR));
282                 fsz -= shsz;
283                 val &= SZMASK(fsz);
284                 xinval = inbits = 0;
285         }
286         if (fsz) {
287                 xinval = (xinval << fsz) | val;
288                 inbits += fsz;
289         }
290 #else
ragge
1.70
291         while (fsz + inbits >= SZCHAR) {
ragge
1.72
292                 int shsz = SZCHAR-inbits;
ragge
1.70
293                 xinval |= (val << inbits);
294                 printf("%s " CONFMT "\n",
295                     astypnames[CHAR], xinval & SZMASK(SZCHAR));
ragge
1.72
296                 fsz -= shsz;
297                 val >>= shsz;
ragge
1.70
298                 xinval = inbits = 0;
299         }
300         if (fsz) {
301                 xinval |= (val << inbits);
302                 inbits += fsz;
303         }
ragge
1.72
304 #endif
ragge
1.70
305 }
306
307 char *asspace = "\t.space";
308
309 /*
310  * set fsz bits in sequence to zero.
311  */
312 void
313 zbits(OFFSZ offint fsz)
314 {
315         int m;
316
317 #ifdef PCC_DEBUG
318         if (idebug)
319                 printf("zbits off %lld, fsz %d inbits %d\n"offfszinbits);
320 #endif
ragge
1.72
321 #if TARGET_ENDIAN == TARGET_BE
322         if ((m = (inbits % SZCHAR))) {
323                 m = SZCHAR - m;
324                 if (fsz < m) {
325                         inbits += fsz;
326                         xinval <<= fsz;
327                         return;
328                 } else {
329                         fsz -= m;
330                         xinval <<= m;
331                         printf("%s " CONFMT "\n"
332                             astypnames[CHAR], xinval & SZMASK(SZCHAR));
333                         xinval = inbits = 0;
334                 }
335         }
336 #else
ragge
1.70
337         if ((m = (inbits % SZCHAR))) {
338                 m = SZCHAR - m;
339                 if (fsz < m) {
340                         inbits += fsz;
341                         return;
342                 } else {
343                         fsz -= m;
344                         printf("%s " CONFMT "\n"
345                             astypnames[CHAR], xinval & SZMASK(SZCHAR));
346                         xinval = inbits = 0;
347                 }
348         }
ragge
1.72
349 #endif
ragge
1.70
350         if (fsz >= SZCHAR) {
351                 printf("%s %d\n"asspacefsz/SZCHAR);
352                 fsz -= (fsz/SZCHAR) * SZCHAR;
353         }
354         if (fsz) {
355                 xinval = 0;
356                 inbits = fsz;
357         }
358 }
359 #endif
360
ragge
1.1
361 /*
362  * beginning of initialization; allocate space to store initialized data.
363  * remember storage class for writeout in endinit().
ragge
1.15
364  * p is the newly declarated type.
ragge
1.1
365  */
366 void
ragge
1.15
367 beginit(struct symtab *sp)
ragge
1.1
368 {
ragge
1.47
369         struct initctx *ict;
ragge
1.15
370         struct instk *is = &pbase;
371
ragge
1.1
372 #ifdef PCC_DEBUG
ragge
1.21
373         if (idebug)
ragge
1.61
374                 printf("beginit(%p), sclass %s\n"spscnames(sp->sclass));
ragge
1.1
375 #endif
376
ragge
1.47
377         if (pstk) {
378 #ifdef PCC_DEBUG
379                 if (idebug)
380                         printf("beginit: saving ctx pstk %p\n"pstk);
381 #endif
382                 /* save old context */
383                 ict = tmpalloc(sizeof(struct initctx));
384                 ict->prev = inilnk;
385                 inilnk = ict;
386                 ict->pstk = pstk;
387                 ict->psym = csym;
388                 ict->lpole = lpole;
389                 ict->basesz = basesz;
390                 ict->numents = numents;
391                 is = tmpalloc(sizeof(struct instk));
392         }
ragge
1.15
393         csym = sp;
ragge
1.1
394
ragge
1.18
395         numents = 0/* no entries in array list */
ragge
1.58
396         if (ISARY(sp->stype)) {
ragge
1.61
397                 basesz = tsize(DECREF(sp->stype), sp->sdf+1sp->sap);
ragge
1.58
398                 if (basesz == 0) {
399                         uerror("array has incomplete type");
400                         basesz = SZINT;
401                 }
402         } else
ragge
1.77
403                 basesz = tsize(sp->stypesp->sdfsp->sap);
ragge
1.16
404         SLIST_INIT(&lpole);
405
ragge
1.15
406         /* first element */
ragge
1.61
407         if (ISSOU(sp->stype)) {
408                 is->in_lnk = strmemb(sp->sap);
409         } else
410                 is->in_lnk = NULL;
ragge
1.15
411         is->in_n = 0;
412         is->in_t = sp->stype;
413         is->in_sym = sp;
ragge
1.22
414         is->in_df = sp->sdf;
ragge
1.20
415         is->in_fl = 0;
ragge
1.15
416         is->in_prev = NULL;
417         pstk = is;
ragge
1.66
418         doing_init++;
ragge
1.67
419         if (sp->sclass == STATIC || sp->sclass == EXTDEF)
420                 statinit++;
ragge
1.15
421 }
422
423 /*
424  * Push a new entry on the initializer stack.
425  * The new entry will be "decremented" to the new sub-type of the previous
426  * entry when called.
427  * Popping of entries is done elsewhere.
428  */
ragge
1.21
429 static void
430 stkpush(void)
431 {
ragge
1.15
432         struct instk *is;
ragge
1.24
433         struct symtab *sq, *sp;
434         TWORD t;
435
436         if (pstk == NULL) {
437                 sp = csym;
438                 t = 0;
439         } else {
440                 t = pstk->in_t;
441                 sp = pstk->in_sym;
442         }
ragge
1.15
443
444 #ifdef PCC_DEBUG
ragge
1.16
445         if (idebug) {
ragge
1.21
446                 printf("stkpush: '%s' %s "sp->snamescnames(sp->sclass));
ragge
1.16
447                 tprint(stdoutt0);
448         }
ragge
1.15
449 #endif
ragge
1.1
450
ragge
1.15
451         /*
ragge
1.22
452          * Figure out what the next initializer will be, and push it on 
ragge
1.15
453          * the stack.  If this is an array, just decrement type, if it
454          * is a struct or union, extract the next element.
455          */
ragge
1.22
456         is = tmpalloc(sizeof(struct instk));
ragge
1.16
457         is->in_fl = 0;
458         is->in_n = 0;
ragge
1.24
459         if (pstk == NULL) {
460                 /* stack empty */
ragge
1.61
461                 is->in_lnk = ISSOU(sp->stype) ? strmemb(sp->sap) : NULL;
ragge
1.24
462                 is->in_t = sp->stype;
463                 is->in_sym = sp;
464                 is->in_df = sp->sdf;
465         } else if (ISSOU(t)) {
ragge
1.41
466                 sq = pstk->in_lnk;
ragge
1.29
467                 if (sq == NULL) {
468                         uerror("excess of initializing elements");
469                 } else {
ragge
1.61
470                         is->in_lnk = ISSOU(sq->stype) ? strmemb(sq->sap) : NULL;
ragge
1.29
471                         is->in_t = sq->stype;
472                         is->in_sym = sq;
473                         is->in_df = sq->sdf;
474                 }
ragge
1.16
475         } else if (ISARY(t)) {
ragge
1.61
476                 is->in_lnk = ISSOU(DECREF(t)) ? strmemb(pstk->in_sym->sap) : 0;
ragge
1.16
477                 is->in_t = DECREF(t);
ragge
1.15
478                 is->in_sym = sp;
ragge
1.57
479                 if (pstk->in_df->ddim != NOOFFSET && pstk->in_df->ddim &&
ragge
1.44
480                     pstk->in_n >= pstk->in_df->ddim) {
ragge
1.26
481                         werror("excess of initializing elements");
482                         pstk->in_n--;
483                 }
ragge
1.61
484                 is->in_df = pstk->in_df+1;
ragge
1.15
485         } else
ragge
1.30
486                 uerror("too many left braces");
ragge
1.15
487         is->in_prev = pstk;
488         pstk = is;
ragge
1.1
489
490 #ifdef PCC_DEBUG
ragge
1.16
491         if (idebug) {
492                 printf(" newtype ");
493                 tprint(stdoutis->in_t0);
494                 printf("\n");
495         }
ragge
1.2
496 #endif
ragge
1.1
497 }
ragge
1.15
498
499 /*
ragge
1.22
500  * pop down to either next level that can handle a new initializer or
ragge
1.15
501  * to the next braced level.
502  */
503 static void
504 stkpop(void)
505 {
ragge
1.18
506 #ifdef PCC_DEBUG
507         if (idebug)
508                 printf("stkpop\n");
509 #endif
ragge
1.15
510         for (; pstkpstk = pstk->in_prev) {
ragge
1.41
511                 if (pstk->in_t == STRTY && pstk->in_lnk != NULL) {
512                         pstk->in_lnk = pstk->in_lnk->snext;
513                         if (pstk->in_lnk != NULL)
ragge
1.20
514                                 break;
515                 }
ragge
1.21
516                 if (ISSOU(pstk->in_t) && pstk->in_fl)
517                         break/* need } */
518                 if (ISARY(pstk->in_t)) {
ragge
1.15
519                         pstk->in_n++;
ragge
1.22
520                         if (pstk->in_fl)
521                                 break;
ragge
1.44
522                         if (pstk->in_df->ddim == NOOFFSET ||
ragge
1.22
523                             pstk->in_n < pstk->in_df->ddim)
ragge
1.21
524                                 break/* ger more elements */
525                 }
ragge
1.15
526         }
ragge
1.22
527 #ifdef PCC_DEBUG
528         if (idebug > 1)
529                 prtstk(pstk);
530 #endif
531 }
532
533 /*
534  * Count how many elements an array may consist of.
535  */
536 static int
537 acalc(struct instk *isint n)
538 {
539         if (is == NULL || !ISARY(is->in_t))
540                 return 0;
541         return acalc(is->in_prevn * is->in_df->ddim) + n * is->in_n;
ragge
1.15
542 }
543
544 /*
ragge
1.18
545  * Find current bit offset of the top element on the stack from
546  * the beginning of the aggregate.
547  */
548 static CONSZ
549 findoff(void)
550 {
ragge
1.20
551         struct instk *is;
ragge
1.22
552         OFFSZ off;
ragge
1.18
553
554 #ifdef PCC_DEBUG
ragge
1.60
555         if (ISARY(pstk->in_t))
ragge
1.56
556                 cerror("findoff on bad type %x"pstk->in_t);
ragge
1.18
557 #endif
558
ragge
1.20
559         /*
560          * Offset calculations. If:
561          * - previous type is STRTY, soffset has in-struct offset.
562          * - this type is ARY, offset is ninit*stsize.
563          */
564         for (off = 0is = pstkisis = is->in_prev) {
565                 if (is->in_prev && is->in_prev->in_t == STRTY)
566                         off += is->in_sym->soffset;
ragge
1.22
567                 if (ISARY(is->in_t)) {
568                         /* suesize is the basic type, so adjust */
569                         TWORD t = is->in_t;
570                         OFFSZ o;
571                         while (ISARY(t))
572                                 t = DECREF(t);
ragge
1.61
573                         if (ISPTR(t)) {
574                                 o = SZPOINT(t); /* XXX use tsize() */
575                         } else {
576                                 o = tsize(tis->in_sym->sdfis->in_sym->sap);
577                         }
ragge
1.22
578                         off += o * acalc(is1);
ragge
1.27
579                         while (is->in_prev && ISARY(is->in_prev->in_t)) {
580                                 if (is->in_prev->in_prev &&
581                                     is->in_prev->in_prev->in_t == STRTY)
582                                         off += is->in_sym->soffset;
ragge
1.22
583                                 is = is->in_prev;
ragge
1.27
584                         }
ragge
1.22
585                 }
ragge
1.18
586         }
gmcgarry
1.42
587 #ifdef PCC_DEBUG
ragge
1.20
588         if (idebug>1) {
ragge
1.18
589                 printf("findoff: off %lld\n"off);
ragge
1.20
590                 prtstk(pstk);
591         }
gmcgarry
1.42
592 #endif
ragge
1.18
593         return off;
594 }
595
596 /*
ragge
1.21
597  * Insert the node p with size fsz at position off.
598  * Bit fields are already dealt with, so a node of correct type
599  * with correct alignment and correct bit offset is given.
ragge
1.18
600  */
601 static void
ragge
1.21
602 nsetval(CONSZ offint fszNODE *p)
ragge
1.18
603 {
ragge
1.21
604         struct llist *ll;
605         struct ilist *il;
ragge
1.18
606
607         if (idebug>1)
ragge
1.21
608                 printf("setval: off %lld fsz %d p %p\n"offfszp);
ragge
1.18
609
ragge
1.19
610         if (fsz == 0)
611                 return;
612
ragge
1.21
613         ll = setll(off);
614         off -= ll->begsz;
615         if (ll->il == NULL) {
616                 ll->il = getil(NULLofffszp);
617         } else {
ragge
1.24
618                 il = ll->il;
619                 if (il->off > off) {
620                         ll->il = getil(ll->ilofffszp);
621                 } else {
622                         for (il = ll->ilil->nextil = il->next)
623                                 if (il->off <= off && il->next->off > off)
624                                         break;
625                         if (il->off == off) {
626                                 /* replace */
627                                 nfree(il->n);
628                                 il->n = p;
629                         } else
630                                 il->next = getil(il->nextofffszp);
631                 }
ragge
1.21
632         }
ragge
1.18
633 }
634
635 /*
ragge
1.15
636  * take care of generating a value for the initializer p
637  * inoff has the current offset (last bit written)
638  * in the current word being generated
ragge
1.56
639  * Returns the offset.
ragge
1.15
640  */
ragge
1.56
641 CONSZ
ragge
1.15
642 scalinit(NODE *p)
643 {
ragge
1.21
644         CONSZ woff;
ragge
1.15
645         NODE *q;
ragge
1.21
646         int fsz;
ragge
1.15
647
648 #ifdef PCC_DEBUG
649         if (idebug > 2) {
ragge
1.20
650                 printf("scalinit(%p)\n"p);
ragge
1.15
651                 fwalk(peprint0);
652                 prtstk(pstk);
653         }
654 #endif
655
656         if (nerrors)
ragge
1.56
657                 return 0;
ragge
1.15
658
ragge
1.23
659         p = optim(p);
660
ragge
1.36
661 #ifdef notdef /* leave to the target to decide if useable */
ragge
1.22
662         if (csym->sclass != AUTO && p->n_op != ICON &&
663             p->n_op != FCON && p->n_op != NAME)
ragge
1.16
664                 cerror("scalinit not leaf");
ragge
1.36
665 #endif
ragge
1.20
666
667         /* Out of elements? */
668         if (pstk == NULL) {
ragge
1.21
669                 uerror("excess of initializing elements");
ragge
1.56
670                 return 0;
ragge
1.20
671         }
672
ragge
1.15
673         /*
674          * Get to the simple type if needed.
675          */
ragge
1.60
676         while (ISSOU(pstk->in_t) || ISARY(pstk->in_t)) {
ragge
1.15
677                 stkpush();
ragge
1.60
678                 /* If we are doing auto struct init */
679                 if (ISSOU(pstk->in_t) && ISSOU(p->n_type) &&
ragge
1.61
680                     suemeq(pstk->in_sym->sapp->n_ap))
ragge
1.60
681                         break;
682         }
683
684         if (ISSOU(pstk->in_t) == 0) {
685                 /* let buildtree do typechecking (and casting) */
ragge
1.61
686                 q = block(NAMENIL,NILpstk->in_tpstk->in_df,
687                     pstk->in_sym->sap);
ragge
1.60
688                 p = buildtree(ASSIGNqp);
689                 nfree(p->n_left);
ragge
1.75
690                 q = p->n_right;
ragge
1.60
691                 nfree(p);
692         } else
693                 q = p;
ragge
1.79
694
695         q = optloop(q);
ragge
1.60
696
697         woff = findoff();
ragge
1.15
698
ragge
1.21
699         /* bitfield sizes are special */
700         if (pstk->in_sym->sclass & FIELD)
701                 fsz = -(pstk->in_sym->sclass & FLDSIZ);
702         else
ragge
1.60
703                 fsz = (int)tsize(pstk->in_tpstk->in_sym->sdf,
ragge
1.61
704                     pstk->in_sym->sap);
ragge
1.19
705
ragge
1.21
706         nsetval(wofffszq);
ragge
1.18
707
ragge
1.15
708         stkpop();
ragge
1.2
709 #ifdef PCC_DEBUG
ragge
1.8
710         if (idebug > 2) {
ragge
1.60
711                 printf("scalinit e(%p)\n"q);
ragge
1.8
712         }
ragge
1.2
713 #endif
ragge
1.56
714         return woff;
ragge
1.1
715 }
716
ragge
1.7
717 /*
ragge
1.21
718  * Generate code to insert a value into a bitfield.
719  */
720 static void
721 insbf(OFFSZ offint fszint val)
722 {
723         struct symtab sym;
724         NODE *p, *r;
725         TWORD typ;
726
727 #ifdef PCC_DEBUG
728         if (idebug > 1)
729                 printf("insbf: off %lld fsz %d val %d\n"offfszval);
730 #endif
731
732         if (fsz == 0)
733                 return;
734
735         /* small opt: do char instead of bf asg */
736         if ((off & (ALCHAR-1)) == 0 && fsz == SZCHAR)
737                 typ = CHAR;
738         else
739                 typ = INT;
740         /* Fake a struct reference */
ragge
1.43
741         p = buildtree(ADDROFnametree(csym), NIL);
ragge
1.21
742         sym.stype = typ;
743         sym.squal = 0;
744         sym.sdf = 0;
ragge
1.63
745         sym.sap = NULL;
gmcgarry
1.55
746         sym.soffset = (int)off;
747         sym.sclass = (char)(typ == INT ? FIELD | fsz : MOU);
stefan
1.39
748         r = xbcon(0, &symtyp);
ragge
1.63
749         p = block(STREFprINT00);
ragge
1.68
750         ecomp(buildtree(ASSIGNstref(p), bcon(val)));
ragge
1.21
751 }
752
753 /*
754  * Clear a bitfield, starting at off and size fsz.
755  */
756 static void
757 clearbf(OFFSZ offOFFSZ fsz)
758 {
759         /* Pad up to the next even initializer */
760         if ((off & (ALCHAR-1)) || (fsz < SZCHAR)) {
gmcgarry
1.55
761                 int ba = (int)(((off + (SZCHAR-1)) & ~(SZCHAR-1)) - off);
ragge
1.21
762                 if (ba > fsz)
gmcgarry
1.55
763                         ba = (int)fsz;
ragge
1.21
764                 insbf(offba0);
765                 off += ba;
766                 fsz -= ba;
767         }
768         while (fsz >= SZCHAR) {
769                 insbf(offSZCHAR0);
770                 off += SZCHAR;
771                 fsz -= SZCHAR;
772         }
773         if (fsz)
774                 insbf(offfsz0);
775 }
776
777 /*
ragge
1.7
778  * final step of initialization.
779  * print out init nodes and generate copy code (if needed).
780  */
ragge
1.1
781 void
ragge
1.73
782 endinit(int seg)
ragge
1.1
783 {
ragge
1.18
784         struct llist *ll;
ragge
1.21
785         struct ilist *il;
786         int fsz;
787         OFFSZ lastofftbit;
ragge
1.1
788
789 #ifdef PCC_DEBUG
790         if (idebug)
ragge
1.18
791                 printf("endinit()\n");
ragge
1.1
792 #endif
793
ragge
1.21
794         /* Calculate total block size */
ragge
1.44
795         if (ISARY(csym->stype) && csym->sdf->ddim == NOOFFSET) {
ragge
1.21
796                 tbit = numents*basesz/* open-ended arrays */
797                 csym->sdf->ddim = numents;
ragge
1.22
798                 if (csym->sclass == AUTO) { /* Get stack space */
799                         csym->soffset = NOOFFSET;
ragge
1.21
800                         oalloc(csym, &autooff);
ragge
1.22
801                 }
ragge
1.21
802         } else
ragge
1.61
803                 tbit = tsize(csym->stypecsym->sdfcsym->sap);
ragge
1.21
804
ragge
1.74
805         /* Setup symbols */
806         if (csym->sclass != AUTO) {
807                 locctr(seg ? UDATA : DATAcsym);
808                 defloc(csym);
809         }
810
ragge
1.17
811         /* Traverse all entries and print'em out */
ragge
1.21
812         lastoff = 0;
ragge
1.18
813         SLIST_FOREACH(ll, &lpolenext) {
ragge
1.21
814                 for (il = ll->ililil = il->next) {
815 #ifdef PCC_DEBUG
816                         if (idebug > 1) {
817                                 printf("off %lld size %d val %lld type ",
818                                     ll->begsz+il->offil->fszil->n->n_lval);
819                                 tprint(stdoutil->n->n_type0);
820                                 printf("\n");
821                         }
822 #endif
823                         fsz = il->fsz;
824                         if (csym->sclass == AUTO) {
825                                 struct symtab sym;
826                                 NODE *p, *r, *n;
827
828                                 if (ll->begsz + il->off > lastoff)
829                                         clearbf(lastoff,
830                                             (ll->begsz + il->off) - lastoff);
831
832                                 /* Fake a struct reference */
ragge
1.43
833                                 p = buildtree(ADDROFnametree(csym), NIL);
ragge
1.21
834                                 n = il->n;
835                                 sym.stype = n->n_type;
836                                 sym.squal = n->n_qual;
837                                 sym.sdf = n->n_df;
ragge
1.61
838                                 sym.sap = n->n_ap;
gmcgarry
1.55
839                                 sym.soffset = (int)(ll->begsz + il->off);
840                                 sym.sclass = (char)(fsz < 0 ? FIELD | -fsz : 0);
stefan
1.39
841                                 r = xbcon(0, &symINT);
ragge
1.63
842                                 p = block(STREFprINT00);
ragge
1.45
843                                 ecomp(buildtree(ASSIGNstref(p), il->n));
ragge
1.21
844                                 if (fsz < 0)
845                                         fsz = -fsz;
846
847                         } else {
848                                 if (ll->begsz + il->off > lastoff)
849                                         zbits(lastoff,
850                                             (ll->begsz + il->off) - lastoff);
851                                 if (fsz < 0) {
852                                         fsz = -fsz;
853                                         infld(il->offfszil->n->n_lval);
854                                 } else
ragge
1.66
855                                         inval(il->offfszil->n);
ragge
1.36
856                                 tfree(il->n);
ragge
1.21
857                         }
858                         lastoff = ll->begsz + il->off + fsz;
ragge
1.2
859                 }
860         }
ragge
1.21
861         if (csym->sclass == AUTO) {
862                 clearbf(lastofftbit-lastoff);
863         } else
864                 zbits(lastofftbit-lastoff);
ragge
1.56
865         
ragge
1.67
866         doing_init--;
867         if (csym->sclass == STATIC || csym->sclass == EXTDEF)
868                 statinit--;
ragge
1.56
869         endictx();
870 }
871
872 void
873 endictx(void)
874 {
875         struct initctx *ict = inilnk;
876
877         if (ict == NULL)
878                 return;
879
880         pstk = ict->pstk;
881         csym = ict->psym;
882         lpole = ict->lpole;
883         basesz = ict->basesz;
884         numents = ict->numents;
885         inilnk = inilnk->prev;
ragge
1.47
886 #ifdef PCC_DEBUG
ragge
1.56
887         if (idebug)
888                 printf("endinit: restoring ctx pstk %p\n"pstk);
ragge
1.47
889 #endif
ragge
1.1
890 }
891
892 /*
893  * process an initializer's left brace
894  */
895 void
plunky
1.80
896 ilbrace(void)
ragge
1.1
897 {
ragge
1.15
898 #ifdef PCC_DEBUG
899         if (idebug)
900                 printf("ilbrace()\n");
901 #endif
ragge
1.1
902
ragge
1.20
903         if (pstk == NULL)
904                 return;
905
ragge
1.18
906         stkpush();
907         pstk->in_fl = 1/* mark lbrace */
ragge
1.22
908 #ifdef PCC_DEBUG
909         if (idebug > 1)
910                 prtstk(pstk);
911 #endif
ragge
1.1
912 }
913
914 /*
915  * called when a '}' is seen
916  */
917 void
plunky
1.80
918 irbrace(void)
ragge
1.1
919 {
920 #ifdef PCC_DEBUG
ragge
1.18
921         if (idebug)
922                 printf("irbrace()\n");
ragge
1.15
923         if (idebug > 2)
924                 prtstk(pstk);
ragge
1.1
925 #endif
926
ragge
1.21
927         if (pstk == NULL)
928                 return;
929
ragge
1.18
930         /* Got right brace, search for corresponding in the stack */
ragge
1.1
931         for (; pstk->in_prev != NULLpstk = pstk->in_prev) {
932                 if(!pstk->in_fl)
933                         continue;
934
935                 /* we have one now */
936
937                 pstk->in_fl = 0;  /* cancel { */
ragge
1.20
938                 if (ISARY(pstk->in_t))
ragge
1.22
939                         pstk->in_n = pstk->in_df->ddim;
940                 else if (pstk->in_t == STRTY) {
ragge
1.41
941                         while (pstk->in_lnk != NULL &&
942                             pstk->in_lnk->snext != NULL)
943                                 pstk->in_lnk = pstk->in_lnk->snext;
ragge
1.22
944                 }
ragge
1.18
945                 stkpop();
ragge
1.1
946                 return;
947         }
948 }
949
ragge
1.15
950 /*
ragge
1.22
951  * Create a new init stack based on given elements.
ragge
1.15
952  */
953 static void
ragge
1.22
954 mkstack(NODE *p)
ragge
1.15
955 {
ragge
1.22
956
957 #ifdef PCC_DEBUG
ragge
1.57
958         if (idebug) {
ragge
1.22
959                 printf("mkstack: %p\n"p);
ragge
1.57
960                 if (idebug > 1 && p)
961                         fwalk(peprint0);
962         }
ragge
1.15
963 #endif
ragge
1.22
964
965         if (p == NULL)
966                 return;
967         mkstack(p->n_left);
968
969         switch (p->n_op) {
970         case LB/* Array index */
971                 if (p->n_right->n_op != ICON)
972                         cerror("mkstack");
973