1 /* $Id: init.c,v 1.6 2015/11/24 17:30:20 ragge Exp $ */
4 * Copyright (c) 2004, 2007 Anders Magnusson (ragge@ludd.ltu.se).
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
31 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
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
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.
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.
68 * The following machine-dependent routines may be called during
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.
74 * ninval(CONSZ off, int fsz, NODE *)
75 * - prints an integer constant which may have
76 * a label associated with it, located at off and
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.
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.
90 * The base element(s) of an initialized variable is kept in a linked
91 * list, allocated while initialized.
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.
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.
101 * Position entries are increased when traversing back down into the stack.
105 * Good-to-know entries from symtab:
106 * soffset - # of bits from beginning of this structure.
111 * - Alignment of structs on like i386 char members.
115 * Struct used in array initialisation.
117 static struct instk
{
118 struct instk
*in_prev
; /* linked list */
119 struct symtab
*in_lnk
; /* member in structure initializations */
120 struct symtab
*in_sym
; /* symtab index */
121 union dimfun
*in_df
; /* dimenston of array */
122 TWORD in_t
; /* type for this level */
123 int in_n
; /* number of arrays seen so far */
124 int in_fl
; /* flag which says if this level is controlled by {} */
127 int doing_init
, statinit
;
128 static struct symtab
*csym
;
131 static void prtstk(struct instk
*in
);
135 * Linked lists for initializations.
139 CONSZ off
; /* bit offset of this entry */
140 int fsz
; /* bit size of this entry */
141 NODE
*n
; /* node containing this data info */
145 SLIST_ENTRY(llist
) next
;
146 CONSZ begsz
; /* bit offset of this entry */
149 static SLIST_HEAD(llh
, llist
) lpole
;
151 static int numents
; /* # of array entries allocated */
153 static struct initctx
{
154 struct initctx
*prev
;
162 static struct ilist
*
163 getil(struct ilist
*next
, CONSZ b
, int sz
, NODE
*n
)
165 struct ilist
*il
= tmpalloc(sizeof(struct ilist
));
175 * Allocate a new struct defining a block of initializers appended to the
176 * end of the llist. Return that entry.
178 static struct llist
*
183 ll
= tmpalloc(sizeof(struct llist
));
184 ll
->begsz
= numents
* basesz
;
186 SLIST_INSERT_LAST(&lpole
, ll
, next
);
192 * Return structure containing off bitnumber.
193 * Allocate more entries, if needed.
195 static struct llist
*
198 struct llist
*ll
= NULL
;
200 /* Ensure that we have enough entries */
201 while (off
>= basesz
* numents
)
204 if (ll
!= NULL
&& ll
->begsz
<= off
&& ll
->begsz
+ basesz
> off
)
207 SLIST_FOREACH(ll
, &lpole
, next
)
208 if (ll
->begsz
<= off
&& ll
->begsz
+ basesz
> off
)
210 return ll
; /* ``cannot fail'' */
212 char *astypnames
[] = { 0, 0, "\t.byte", "\t.byte", "\t.short", "\t.short",
213 "\t.word", "\t.word", "\t.long", "\t.long", "\t.quad", "\t.quad",
218 inval(CONSZ off
, int fsz
, NODE
*p
)
224 if (p
->n_op
!= ICON
&& p
->n_op
!= FCON
) {
225 uerror("constant required");
228 if (p
->n_type
== BOOL
) {
229 if ((U_CONSZ
)glval(p
) > 1)
231 p
->n_type
= BOOL_TYPE
;
233 if (ninval(off
, fsz
, p
))
234 return; /* dealt with in local.c */
239 val
= (CONSZ
)(glval(p
) & SZMASK(sztable
[t
]));
240 if (t
<= ULONGLONG
) {
242 printf("%s ",astypnames
[t
]);
243 if (val
|| sp
== NULL
)
245 if (val
&& sp
!= NULL
)
248 if ((sp
->sclass
== STATIC
&& sp
->slevel
> 0)) {
249 printf(LABFMT
, sp
->soffset
);
251 printf("%s", sp
->soname
?
252 sp
->soname
: exname(sp
->sname
));
256 cerror("inval: unhandled type %d", (int)t
);
264 * Initialize a bitfield.
268 infld(CONSZ off
, int fsz
, CONSZ val
)
272 printf("infld off " CONFMT
", fsz %d, val " CONFMT
" inbits %d\n",
273 off
, fsz
, val
, inbits
);
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
], (CONSZ
)(xinval
& SZMASK(SZCHAR
)));
287 xinval
= (xinval
<< fsz
) | val
;
291 while (fsz
+ inbits
>= SZCHAR
) {
292 int shsz
= SZCHAR
-inbits
;
293 xinval
|= (val
<< inbits
);
294 printf("%s " CONFMT
"\n",
295 astypnames
[CHAR
], (CONSZ
)(xinval
& SZMASK(SZCHAR
)));
301 xinval
|= (val
<< inbits
);
307 char *asspace
= "\t.space";
310 * set fsz bits in sequence to zero.
313 zbits(OFFSZ off
, int fsz
)
319 printf("zbits off " CONFMT
", fsz %d inbits %d\n", off
, fsz
, inbits
);
321 #if TARGET_ENDIAN == TARGET_BE
322 if ((m
= (inbits
% SZCHAR
))) {
331 printf("%s " CONFMT
"\n",
332 astypnames
[CHAR
], xinval
& SZMASK(SZCHAR
));
337 if ((m
= (inbits
% SZCHAR
))) {
344 printf("%s " CONFMT
"\n",
345 astypnames
[CHAR
], (CONSZ
)(xinval
& SZMASK(SZCHAR
)));
351 printf("%s %d\n", asspace
, fsz
/SZCHAR
);
352 fsz
-= (fsz
/SZCHAR
) * SZCHAR
;
362 * beginning of initialization; allocate space to store initialized data.
363 * remember storage class for writeout in endinit().
364 * p is the newly declarated type.
367 beginit(struct symtab
*sp
)
370 struct instk
*is
= &pbase
;
374 printf("beginit(%p), sclass %s\n", sp
, scnames(sp
->sclass
));
380 printf("beginit: saving ctx pstk %p\n", pstk
);
382 /* save old context */
383 ict
= tmpalloc(sizeof(struct initctx
));
389 ict
->basesz
= basesz
;
390 ict
->numents
= numents
;
391 is
= tmpalloc(sizeof(struct instk
));
395 numents
= 0; /* no entries in array list */
396 if (ISARY(sp
->stype
)) {
397 basesz
= tsize(DECREF(sp
->stype
), sp
->sdf
+1, sp
->sap
);
399 uerror("array has incomplete type");
403 basesz
= tsize(sp
->stype
, sp
->sdf
, sp
->sap
);
407 if (ISSOU(sp
->stype
)) {
408 is
->in_lnk
= strmemb(sp
->sap
);
412 is
->in_t
= sp
->stype
;
419 if (sp
->sclass
== STATIC
|| sp
->sclass
== EXTDEF
)
424 * Push a new entry on the initializer stack.
425 * The new entry will be "decremented" to the new sub-type of the previous
427 * Popping of entries is done elsewhere.
433 struct symtab
*sq
, *sp
;
446 printf("stkpush: '%s' %s ", sp
->sname
, scnames(sp
->sclass
));
452 * Figure out what the next initializer will be, and push it on
453 * the stack. If this is an array, just decrement type, if it
454 * is a struct or union, extract the next element.
456 is
= tmpalloc(sizeof(struct instk
));
461 is
->in_lnk
= ISSOU(sp
->stype
) ? strmemb(sp
->sap
) : NULL
;
462 is
->in_t
= sp
->stype
;
465 } else if (ISSOU(t
)) {
468 uerror("excess of initializing elements");
470 is
->in_lnk
= ISSOU(sq
->stype
) ? strmemb(sq
->sap
) : NULL
;
471 is
->in_t
= sq
->stype
;
475 } else if (ISARY(t
)) {
476 is
->in_lnk
= ISSOU(DECREF(t
)) ? strmemb(pstk
->in_sym
->sap
) : 0;
477 is
->in_t
= DECREF(t
);
479 if (pstk
->in_df
->ddim
!= NOOFFSET
&& pstk
->in_df
->ddim
&&
480 pstk
->in_n
>= pstk
->in_df
->ddim
) {
481 werror("excess of initializing elements");
484 is
->in_df
= pstk
->in_df
+1;
486 uerror("too many left braces");
500 * pop down to either next level that can handle a new initializer or
501 * to the next braced level.
510 for (; pstk
; pstk
= pstk
->in_prev
) {
511 if (pstk
->in_t
== STRTY
&& pstk
->in_lnk
!= NULL
) {
512 pstk
->in_lnk
= pstk
->in_lnk
->snext
;
513 if (pstk
->in_lnk
!= NULL
)
516 if (ISSOU(pstk
->in_t
) && pstk
->in_fl
)
518 if (ISARY(pstk
->in_t
)) {
522 if (pstk
->in_df
->ddim
== NOOFFSET
||
523 pstk
->in_n
< pstk
->in_df
->ddim
)
524 break; /* ger more elements */
534 * Count how many elements an array may consist of.
537 acalc(struct instk
*is
, int n
)
539 if (is
== NULL
|| !ISARY(is
->in_t
))
541 return acalc(is
->in_prev
, n
* is
->in_df
->ddim
) + n
* is
->in_n
;
545 * Find current bit offset of the top element on the stack from
546 * the beginning of the aggregate.
555 if (ISARY(pstk
->in_t
))
556 cerror("findoff on bad type %x", pstk
->in_t
);
560 * Offset calculations. If:
561 * - previous type is STRTY, soffset has in-struct offset.
562 * - this type is ARY, offset is ninit*stsize.
564 for (off
= 0, is
= pstk
; is
; is
= is
->in_prev
) {
565 if (is
->in_prev
&& is
->in_prev
->in_t
== STRTY
)
566 off
+= is
->in_sym
->soffset
;
567 if (ISARY(is
->in_t
)) {
568 /* suesize is the basic type, so adjust */
574 o
= SZPOINT(t
); /* XXX use tsize() */
576 o
= tsize(t
, is
->in_sym
->sdf
, is
->in_sym
->sap
);
578 off
+= o
* acalc(is
, 1);
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
;
589 printf("findoff: off " CONFMT
"\n", off
);
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.
602 nsetval(CONSZ off
, int fsz
, NODE
*p
)
608 printf("setval: off " CONFMT
" fsz %d p %p\n", off
, fsz
, p
);
615 if (ll
->il
== NULL
) {
616 ll
->il
= getil(NULL
, off
, fsz
, p
);
620 ll
->il
= getil(ll
->il
, off
, fsz
, p
);
622 for (il
= ll
->il
; il
->next
; il
= il
->next
)
623 if (il
->off
<= off
&& il
->next
->off
> off
)
625 if (il
->off
== off
) {
630 il
->next
= getil(il
->next
, off
, fsz
, p
);
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
639 * Returns the offset.
650 printf("scalinit(%p)\n", p
);
661 #ifdef notdef /* leave to the target to decide if useable */
662 if (csym
->sclass
!= AUTO
&& p
->n_op
!= ICON
&&
663 p
->n_op
!= FCON
&& p
->n_op
!= NAME
)
664 cerror("scalinit not leaf");
667 /* Out of elements? */
669 uerror("excess of initializing elements");
674 * Get to the simple type if needed.
676 while (ISSOU(pstk
->in_t
) || ISARY(pstk
->in_t
)) {
678 /* If we are doing auto struct init */
679 if (ISSOU(pstk
->in_t
) && ISSOU(p
->n_type
) &&
680 suemeq(pstk
->in_sym
->sap
, p
->n_ap
))
684 if (ISSOU(pstk
->in_t
) == 0) {
685 /* let buildtree do typechecking (and casting) */
686 q
= block(NAME
, NIL
,NIL
, pstk
->in_t
, pstk
->in_df
,
688 p
= buildtree(ASSIGN
, q
, p
);
694 #ifndef WORD_ADDRESSED
695 if (csym
->sclass
!= AUTO
)
696 q
= rmpconv(optim(rmpconv(q
)));
702 /* bitfield sizes are special */
703 if (pstk
->in_sym
->sclass
& FIELD
)
704 fsz
= -(pstk
->in_sym
->sclass
& FLDSIZ
);
706 fsz
= (int)tsize(pstk
->in_t
, pstk
->in_sym
->sdf
,
709 nsetval(woff
, fsz
, q
);
714 printf("scalinit e(%p)\n", q
);
721 * Generate code to insert a value into a bitfield.
724 insbf(OFFSZ off
, int fsz
, int val
)
732 printf("insbf: off " CONFMT
" fsz %d val %d\n", off
, fsz
, val
);
738 /* small opt: do char instead of bf asg */
739 if ((off
& (ALCHAR
-1)) == 0 && fsz
== SZCHAR
)
743 /* Fake a struct reference */
744 p
= buildtree(ADDROF
, nametree(csym
), NIL
);
749 sym
.soffset
= (int)off
;
750 sym
.sclass
= (char)(typ
== INT
? FIELD
| fsz
: MOU
);
751 r
= xbcon(0, &sym
, typ
);
752 p
= block(STREF
, p
, r
, INT
, 0, 0);
753 ecomp(buildtree(ASSIGN
, stref(p
), bcon(val
)));
757 * Clear a bitfield, starting at off and size fsz.
760 clearbf(OFFSZ off
, OFFSZ fsz
)
762 /* Pad up to the next even initializer */
763 if ((off
& (ALCHAR
-1)) || (fsz
< SZCHAR
)) {
764 int ba
= (int)(((off
+ (SZCHAR
-1)) & ~(SZCHAR
-1)) - off
);
771 while (fsz
>= SZCHAR
) {
772 insbf(off
, SZCHAR
, 0);
781 * final step of initialization.
782 * print out init nodes and generate copy code (if needed).
794 printf("endinit()\n");
797 /* Calculate total block size */
798 if (ISARY(csym
->stype
) && csym
->sdf
->ddim
== NOOFFSET
) {
799 tbit
= numents
*basesz
; /* open-ended arrays */
800 csym
->sdf
->ddim
= numents
;
801 if (csym
->sclass
== AUTO
) { /* Get stack space */
802 csym
->soffset
= NOOFFSET
;
803 oalloc(csym
, &autooff
);
806 tbit
= tsize(csym
->stype
, csym
->sdf
, csym
->sap
);
809 if (csym
->sclass
!= AUTO
) {
810 locctr(seg
? UDATA
: DATA
, csym
);
814 /* Traverse all entries and print'em out */
816 SLIST_FOREACH(ll
, &lpole
, next
) {
817 for (il
= ll
->il
; il
; il
= il
->next
) {
820 printf("off " CONFMT
" size %d val " CONFMT
" type ",
821 ll
->begsz
+il
->off
, il
->fsz
, glval(il
->n
));
822 tprint(il
->n
->n_type
, 0);
827 if (csym
->sclass
== AUTO
) {
831 if (ll
->begsz
+ il
->off
> lastoff
)
833 (ll
->begsz
+ il
->off
) - lastoff
);
835 /* Fake a struct reference */
836 p
= buildtree(ADDROF
, nametree(csym
), NIL
);
838 sym
.stype
= n
->n_type
;
839 sym
.squal
= n
->n_qual
;
842 sym
.soffset
= (int)(ll
->begsz
+ il
->off
);
843 sym
.sclass
= (char)(fsz
< 0 ? FIELD
| -fsz
: 0);
844 r
= xbcon(0, &sym
, INT
);
845 p
= block(STREF
, p
, r
, INT
, 0, 0);
846 ecomp(buildtree(ASSIGN
, stref(p
), il
->n
));
851 if (ll
->begsz
+ il
->off
> lastoff
)
853 (ll
->begsz
+ il
->off
) - lastoff
);
856 infld(il
->off
, fsz
, glval(il
->n
));
858 inval(il
->off
, fsz
, il
->n
);
861 lastoff
= ll
->begsz
+ il
->off
+ fsz
;
864 if (csym
->sclass
== AUTO
) {
865 clearbf(lastoff
, tbit
-lastoff
);
867 zbits(lastoff
, tbit
-lastoff
);
870 if (csym
->sclass
== STATIC
|| csym
->sclass
== EXTDEF
)
878 struct initctx
*ict
= inilnk
;
886 basesz
= ict
->basesz
;
887 numents
= ict
->numents
;
888 inilnk
= inilnk
->prev
;
891 printf("endinit: restoring ctx pstk %p\n", pstk
);
896 * process an initializer's left brace
903 printf("ilbrace()\n");
910 pstk
->in_fl
= 1; /* mark lbrace */
918 * called when a '}' is seen
925 printf("irbrace()\n");
933 /* Got right brace, search for corresponding in the stack */
934 for (; pstk
->in_prev
!= NULL
; pstk
= pstk
->in_prev
) {
938 /* we have one now */
940 pstk
->in_fl
= 0; /* cancel { */
941 if (ISARY(pstk
->in_t
))
942 pstk
->in_n
= pstk
->in_df
->ddim
;
943 else if (pstk
->in_t
== STRTY
) {
944 while (pstk
->in_lnk
!= NULL
&&
945 pstk
->in_lnk
->snext
!= NULL
)
946 pstk
->in_lnk
= pstk
->in_lnk
->snext
;
954 * Create a new init stack based on given elements.
962 printf("mkstack: %p\n", p
);
973 case LB
: /* Array index */
974 if (p
->n_right
->n_op
!= ICON
)
976 if (!ISARY(pstk
->in_t
))
977 uerror("array indexing non-array");
978 pstk
->in_n
= (int)glval(p
->n_right
);
984 for (; pstk
->in_lnk
; pstk
->in_lnk
= pstk
->in_lnk
->snext
)
985 if (pstk
->in_lnk
->sname
== (char *)p
->n_sp
)
987 if (pstk
->in_lnk
== NULL
)
988 uerror("member missing");
990 uerror("not a struct/union");
1002 * Initialize a specific element, as per C99.
1010 stkpush(); /* passed end of array */
1011 while (pstk
->in_prev
&& pstk
->in_fl
== 0)
1012 pstk
= pstk
->in_prev
; /* Empty stack */
1014 if (ISSOU(pstk
->in_t
))
1015 pstk
->in_lnk
= strmemb(pstk
->in_sym
->sap
);
1017 mkstack(p
); /* Setup for assignment */
1019 /* pop one step if SOU, ilbrace will push */
1020 if (op
== NAME
|| op
== LB
)
1021 pstk
= pstk
->in_prev
;
1025 printf("desinit e\n");
1032 * Convert a string to an array of char/wchar for asginit.
1043 if (p
->n_op
== UMUL
&& p
->n_left
->n_op
== ADDROF
)
1044 p
= p
->n_left
->n_left
;
1047 for (s
= p
->n_sp
->sname
; *s
!= 0; ) {
1051 i
= (unsigned char)s
[-1];
1058 * Do an assignment to a struct element.
1067 printf("asginit %p\n", p
);
1068 if (idebug
> 1 && p
)
1069 fwalk(p
, eprint
, 0);
1072 /* convert string to array of char/wchar */
1073 if (p
&& (DEUNSIGN(p
->n_type
) == ARY
+CHAR
||
1074 p
->n_type
== ARY
+WCHAR_TYPE
)) {
1078 t
= p
->n_type
== ARY
+WCHAR_TYPE
? ARY
+WCHAR_TYPE
: ARY
+CHAR
;
1080 * ...but only if next element is ARY+CHAR, otherwise
1081 * just fall through.
1089 while (ISSOU(pstk
->in_t
) || ISARY(pstk
->in_t
))
1091 if (pstk
->in_prev
&&
1092 (DEUNSIGN(pstk
->in_prev
->in_t
) == t
||
1093 pstk
->in_prev
->in_t
== t
)) {
1094 pstk
= pstk
->in_prev
;
1095 if ((g
= pstk
->in_fl
) == 0)
1096 pstk
->in_fl
= 1; /* simulate ilbrace */
1100 irbrace(); /* will fill with zeroes */
1103 pstk
= is
; /* no array of char */
1104 /* END HACKHACKHACK */
1107 if (p
== NULL
) { /* only end of compound stmt */
1109 } else /* assign next element */
1115 prtstk(struct instk
*in
)
1119 printf("init stack:\n");
1120 for (; in
!= NULL
; in
= in
->in_prev
) {
1121 for (i
= 0; i
< o
; i
++)
1123 printf("%p) '%s' ", in
, in
->in_sym
->sname
);
1124 tprint(in
->in_t
, 0);
1125 printf(" %s ", scnames(in
->in_sym
->sclass
));
1126 if (in
->in_df
/* && in->in_df->ddim */)
1127 printf("arydim=%d ", in
->in_df
->ddim
);
1128 printf("ninit=%d ", in
->in_n
);
1129 if (BTYPE(in
->in_t
) == STRTY
|| ISARY(in
->in_t
))
1130 printf("stsize=%d ",
1131 (int)tsize(in
->in_t
, in
->in_df
, in
->in_sym
->sap
));
1132 if (in
->in_fl
) printf("{ ");
1133 printf("soff=%d ", in
->in_sym
->soffset
);
1134 if (in
->in_t
== STRTY
) {
1136 printf("curel %s ", in
->in_lnk
->sname
);
1138 printf("END struct");
1147 * Do a simple initialization.
1148 * At block 0, just print out the value, at higher levels generate
1152 simpleinit(struct symtab
*sp
, NODE
*p
)
1158 /* May be an initialization of an array of char by a string */
1159 if ((DEUNSIGN(p
->n_type
) == ARY
+CHAR
&&
1160 DEUNSIGN(sp
->stype
) == ARY
+CHAR
) ||
1161 (DEUNSIGN(p
->n_type
) == DEUNSIGN(ARY
+WCHAR_TYPE
) &&
1162 DEUNSIGN(sp
->stype
) == DEUNSIGN(ARY
+WCHAR_TYPE
))) {
1163 /* Handle "aaa" as { 'a', 'a', 'a' } */
1166 if (csym
->sdf
->ddim
== NOOFFSET
)
1167 scalinit(bcon(0)); /* Null-term arrays */
1173 switch (sp
->sclass
) {
1180 if (ANYCX(q
) || ANYCX(p
)) {
1181 r
= cxop(ASSIGN
, q
, p
);
1182 /* XXX must unwind the code generated here */
1183 /* We can rely on correct code generated */
1184 p
= r
->n_left
->n_right
->n_left
;
1185 r
->n_left
->n_right
->n_left
= bcon(0);
1187 r
= p
->n_left
->n_right
;
1188 sz
= (int)tsize(r
->n_type
, r
->n_df
, r
->n_ap
);
1190 inval(0, sz
, p
->n_right
->n_right
);
1195 p
= optim(buildtree(ASSIGN
, nt
, p
));
1196 #ifndef WORD_ADDRESSED
1197 p
= optim(rmpconv(p
));
1201 sz
= (int)tsize(t
, q
->n_df
, q
->n_ap
);
1208 if (ISARY(sp
->stype
))
1209 cerror("no array init");
1213 if (ANYCX(q
) || ANYCX(p
))
1214 r
= cxop(ASSIGN
, q
, p
);
1217 r
= buildtree(ASSIGN
, q
, p
);
1222 uerror("illegal initialization");