Relicensing TinyCC
[tinycc.git] / tccgen.c
1 /*
2  *  TCC - Tiny C Compiler
3  * 
4  *  Copyright (c) 2001-2004 Fabrice Bellard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "tcc.h"
22
23 /********************************************************/
24 /* global variables */
25
26 /* loc : local variable index
27    ind : output code index
28    rsym: return symbol
29    anon_sym: anonymous symbol index
30 */
31 ST_DATA int rsym, anon_sym, ind, loc;
32
33 ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
34 ST_DATA Section *cur_text_section; /* current section where function code is generated */
35 #ifdef CONFIG_TCC_ASM
36 ST_DATA Section *last_text_section; /* to handle .previous asm directive */
37 #endif
38 #ifdef CONFIG_TCC_BCHECK
39 /* bound check related sections */
40 ST_DATA Section *bounds_section; /* contains global data bound description */
41 ST_DATA Section *lbounds_section; /* contains local data bound description */
42 #endif
43 /* symbol sections */
44 ST_DATA Section *symtab_section, *strtab_section;
45 /* debug sections */
46 ST_DATA Section *stab_section, *stabstr_section;
47 ST_DATA Sym *sym_free_first;
48 ST_DATA void **sym_pools;
49 ST_DATA int nb_sym_pools;
50
51 ST_DATA Sym *global_stack;
52 ST_DATA Sym *local_stack;
53 ST_DATA Sym *scope_stack_bottom;
54 ST_DATA Sym *define_stack;
55 ST_DATA Sym *global_label_stack;
56 ST_DATA Sym *local_label_stack;
57
58 ST_DATA int vla_sp_loc_tmp; /* vla_sp_loc is set to this when the value won't be needed later */
59 ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */
60 ST_DATA int *vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */
61 ST_DATA int vla_flags; /* VLA_* flags */
62
63 ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop;
64
65 ST_DATA int const_wanted; /* true if constant wanted */
66 ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
67 ST_DATA int global_expr;  /* true if compound literals must be allocated globally (used during initializers parsing */
68 ST_DATA CType func_vt; /* current function return type (used by return instruction) */
69 ST_DATA int func_vc;
70 ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
71 ST_DATA char *funcname;
72
73 ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
74
75 /* ------------------------------------------------------------------------- */
76 static void gen_cast(CType *type);
77 static inline CType *pointed_type(CType *type);
78 static int is_compatible_types(CType *type1, CType *type2);
79 static int parse_btype(CType *type, AttributeDef *ad);
80 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
81 static void parse_expr_type(CType *type);
82 static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
83 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr);
84 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, char *asm_label, int scope);
85 static int decl0(int l, int is_for_loop_init);
86 static void expr_eq(void);
87 static void unary_type(CType *type);
88 static void vla_runtime_type_size(CType *type, int *a);
89 static void vla_sp_save(void);
90 static int is_compatible_parameter_types(CType *type1, CType *type2);
91 static void expr_type(CType *type);
92
93 ST_INLN int is_float(int t)
94 {
95     int bt;
96     bt = t & VT_BTYPE;
97     return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT;
98 }
99
100 /* we use our own 'finite' function to avoid potential problems with
101    non standard math libs */
102 /* XXX: endianness dependent */
103 ST_FUNC int ieee_finite(double d)
104 {
105     int *p = (int *)&d;
106     return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
107 }
108
109 ST_FUNC void test_lvalue(void)
110 {
111     if (!(vtop->r & VT_LVAL))
112         expect("lvalue");
113 }
114
115 /* ------------------------------------------------------------------------- */
116 /* symbol allocator */
117 static Sym *__sym_malloc(void)
118 {
119     Sym *sym_pool, *sym, *last_sym;
120     int i;
121
122     sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
123     dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
124
125     last_sym = sym_free_first;
126     sym = sym_pool;
127     for(i = 0; i < SYM_POOL_NB; i++) {
128         sym->next = last_sym;
129         last_sym = sym;
130         sym++;
131     }
132     sym_free_first = last_sym;
133     return last_sym;
134 }
135
136 static inline Sym *sym_malloc(void)
137 {
138     Sym *sym;
139     sym = sym_free_first;
140     if (!sym)
141         sym = __sym_malloc();
142     sym_free_first = sym->next;
143     return sym;
144 }
145
146 ST_INLN void sym_free(Sym *sym)
147 {
148     sym->next = sym_free_first;
149     tcc_free(sym->asm_label);
150     sym_free_first = sym;
151 }
152
153 /* push, without hashing */
154 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
155 {
156     Sym *s;
157     if (ps == &local_stack) {
158         for (s = *ps; s && s != scope_stack_bottom; s = s->prev)
159             if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM && s->v == v)
160                 tcc_error("incompatible types for redefinition of '%s'",
161                           get_tok_str(v, NULL));
162     }
163     s = *ps;
164     s = sym_malloc();
165     s->asm_label = NULL;
166     s->v = v;
167     s->type.t = t;
168     s->type.ref = NULL;
169 #ifdef _WIN64
170     s->d = NULL;
171 #endif
172     s->c = c;
173     s->next = NULL;
174     /* add in stack */
175     s->prev = *ps;
176     *ps = s;
177     return s;
178 }
179
180 /* find a symbol and return its associated structure. 's' is the top
181    of the symbol stack */
182 ST_FUNC Sym *sym_find2(Sym *s, int v)
183 {
184     while (s) {
185         if (s->v == v)
186             return s;
187         s = s->prev;
188     }
189     return NULL;
190 }
191
192 /* structure lookup */
193 ST_INLN Sym *struct_find(int v)
194 {
195     v -= TOK_IDENT;
196     if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
197         return NULL;
198     return table_ident[v]->sym_struct;
199 }
200
201 /* find an identifier */
202 ST_INLN Sym *sym_find(int v)
203 {
204     v -= TOK_IDENT;
205     if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
206         return NULL;
207     return table_ident[v]->sym_identifier;
208 }
209
210 /* push a given symbol on the symbol stack */
211 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
212 {
213     Sym *s, **ps;
214     TokenSym *ts;
215
216     if (local_stack)
217         ps = &local_stack;
218     else
219         ps = &global_stack;
220     s = sym_push2(ps, v, type->t, c);
221     s->type.ref = type->ref;
222     s->r = r;
223     /* don't record fields or anonymous symbols */
224     /* XXX: simplify */
225     if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
226         /* record symbol in token array */
227         ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
228         if (v & SYM_STRUCT)
229             ps = &ts->sym_struct;
230         else
231             ps = &ts->sym_identifier;
232         s->prev_tok = *ps;
233         *ps = s;
234     }
235     return s;
236 }
237
238 /* push a global identifier */
239 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
240 {
241     Sym *s, **ps;
242     s = sym_push2(&global_stack, v, t, c);
243     /* don't record anonymous symbol */
244     if (v < SYM_FIRST_ANOM) {
245         ps = &table_ident[v - TOK_IDENT]->sym_identifier;
246         /* modify the top most local identifier, so that
247            sym_identifier will point to 's' when popped */
248         while (*ps != NULL)
249             ps = &(*ps)->prev_tok;
250         s->prev_tok = NULL;
251         *ps = s;
252     }
253     return s;
254 }
255
256 /* pop symbols until top reaches 'b' */
257 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
258 {
259     Sym *s, *ss, **ps;
260     TokenSym *ts;
261     int v;
262
263     s = *ptop;
264     while(s != b) {
265         ss = s->prev;
266         v = s->v;
267         /* remove symbol in token array */
268         /* XXX: simplify */
269         if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
270             ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
271             if (v & SYM_STRUCT)
272                 ps = &ts->sym_struct;
273             else
274                 ps = &ts->sym_identifier;
275             *ps = s->prev_tok;
276         }
277         sym_free(s);
278         s = ss;
279     }
280     *ptop = b;
281 }
282
283 static void weaken_symbol(Sym *sym)
284 {
285     sym->type.t |= VT_WEAK;
286     if (sym->c > 0) {
287         int esym_type;
288         ElfW(Sym) *esym;
289         
290         esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
291         esym_type = ELFW(ST_TYPE)(esym->st_info);
292         esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
293     }
294 }
295
296 /* ------------------------------------------------------------------------- */
297
298 ST_FUNC void swap(int *p, int *q)
299 {
300     int t;
301     t = *p;
302     *p = *q;
303     *q = t;
304 }
305
306 static void vsetc(CType *type, int r, CValue *vc)
307 {
308     int v;
309
310     if (vtop >= vstack + (VSTACK_SIZE - 1))
311         tcc_error("memory full");
312     /* cannot let cpu flags if other instruction are generated. Also
313        avoid leaving VT_JMP anywhere except on the top of the stack
314        because it would complicate the code generator. */
315     if (vtop >= vstack) {
316         v = vtop->r & VT_VALMASK;
317         if (v == VT_CMP || (v & ~1) == VT_JMP)
318             gv(RC_INT);
319     }
320     vtop++;
321     vtop->type = *type;
322     vtop->r = r;
323     vtop->r2 = VT_CONST;
324     vtop->c = *vc;
325 }
326
327 /* push constant of type "type" with useless value */
328 void vpush(CType *type)
329 {
330     CValue cval;
331     vsetc(type, VT_CONST, &cval);
332 }
333
334 /* push integer constant */
335 ST_FUNC void vpushi(int v)
336 {
337     CValue cval;
338     cval.i = v;
339     vsetc(&int_type, VT_CONST, &cval);
340 }
341
342 /* push a pointer sized constant */
343 static void vpushs(long long v)
344 {
345   CValue cval;
346   if (PTR_SIZE == 4)
347     cval.i = (int)v;
348   else
349     cval.ull = v;
350   vsetc(&size_type, VT_CONST, &cval);
351 }
352
353 /* push arbitrary 64bit constant */
354 void vpush64(int ty, unsigned long long v)
355 {
356     CValue cval;
357     CType ctype;
358     ctype.t = ty;
359     ctype.ref = NULL;
360     cval.ull = v;
361     vsetc(&ctype, VT_CONST, &cval);
362 }
363
364 /* push long long constant */
365 static inline void vpushll(long long v)
366 {
367     vpush64(VT_LLONG, v);
368 }
369
370 /* Return a static symbol pointing to a section */
371 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
372 {
373     int v;
374     Sym *sym;
375
376     v = anon_sym++;
377     sym = global_identifier_push(v, type->t | VT_STATIC, 0);
378     sym->type.ref = type->ref;
379     sym->r = VT_CONST | VT_SYM;
380     put_extern_sym(sym, sec, offset, size);
381     return sym;
382 }
383
384 /* push a reference to a section offset by adding a dummy symbol */
385 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
386 {
387     CValue cval;
388
389     cval.ul = 0;
390     vsetc(type, VT_CONST | VT_SYM, &cval);
391     vtop->sym = get_sym_ref(type, sec, offset, size);
392 }
393
394 /* define a new external reference to a symbol 'v' of type 'u' */
395 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
396 {
397     Sym *s;
398
399     s = sym_find(v);
400     if (!s) {
401         /* push forward reference */
402         s = global_identifier_push(v, type->t | VT_EXTERN, 0);
403         s->type.ref = type->ref;
404         s->r = r | VT_CONST | VT_SYM;
405     }
406     return s;
407 }
408
409 /* define a new external reference to a symbol 'v' with alternate asm
410    name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
411    is no alternate name (most cases) */
412 static Sym *external_sym(int v, CType *type, int r, char *asm_label)
413 {
414     Sym *s;
415
416     s = sym_find(v);
417     if (!s) {
418         /* push forward reference */
419         s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
420         s->asm_label = asm_label;
421         s->type.t |= VT_EXTERN;
422     } else if (s->type.ref == func_old_type.ref) {
423         s->type.ref = type->ref;
424         s->r = r | VT_CONST | VT_SYM;
425         s->type.t |= VT_EXTERN;
426     } else if (!is_compatible_types(&s->type, type)) {
427         tcc_error("incompatible types for redefinition of '%s'", 
428               get_tok_str(v, NULL));
429     }
430     return s;
431 }
432
433 /* push a reference to global symbol v */
434 ST_FUNC void vpush_global_sym(CType *type, int v)
435 {
436     Sym *sym;
437     CValue cval;
438
439     sym = external_global_sym(v, type, 0);
440     cval.ul = 0;
441     vsetc(type, VT_CONST | VT_SYM, &cval);
442     vtop->sym = sym;
443 }
444
445 ST_FUNC void vset(CType *type, int r, int v)
446 {
447     CValue cval;
448
449     cval.i = v;
450     vsetc(type, r, &cval);
451 }
452
453 static void vseti(int r, int v)
454 {
455     CType type;
456     type.t = VT_INT;
457     type.ref = 0;
458     vset(&type, r, v);
459 }
460
461 ST_FUNC void vswap(void)
462 {
463     SValue tmp;
464     /* cannot let cpu flags if other instruction are generated. Also
465        avoid leaving VT_JMP anywhere except on the top of the stack
466        because it would complicate the code generator. */
467     if (vtop >= vstack) {
468         int v = vtop->r & VT_VALMASK;
469         if (v == VT_CMP || (v & ~1) == VT_JMP)
470             gv(RC_INT);
471     }
472     tmp = vtop[0];
473     vtop[0] = vtop[-1];
474     vtop[-1] = tmp;
475
476 /* XXX: +2% overall speed possible with optimized memswap
477  *
478  *  memswap(&vtop[0], &vtop[1], sizeof *vtop);
479  */
480 }
481
482 ST_FUNC void vpushv(SValue *v)
483 {
484     if (vtop >= vstack + (VSTACK_SIZE - 1))
485         tcc_error("memory full");
486     vtop++;
487     *vtop = *v;
488 }
489
490 static void vdup(void)
491 {
492     vpushv(vtop);
493 }
494
495 /* save r to the memory stack, and mark it as being free */
496 ST_FUNC void save_reg(int r)
497 {
498     int l, saved, size, align;
499     SValue *p, sv;
500     CType *type;
501
502     /* modify all stack values */
503     saved = 0;
504     l = 0;
505     for(p=vstack;p<=vtop;p++) {
506         if ((p->r & VT_VALMASK) == r ||
507             ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
508             /* must save value on stack if not already done */
509             if (!saved) {
510                 /* NOTE: must reload 'r' because r might be equal to r2 */
511                 r = p->r & VT_VALMASK;
512                 /* store register in the stack */
513                 type = &p->type;
514                 if ((p->r & VT_LVAL) ||
515                     (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
516 #ifdef TCC_TARGET_X86_64
517                     type = &char_pointer_type;
518 #else
519                     type = &int_type;
520 #endif
521                 size = type_size(type, &align);
522                 loc = (loc - size) & -align;
523                 sv.type.t = type->t;
524                 sv.r = VT_LOCAL | VT_LVAL;
525                 sv.c.ul = loc;
526                 store(r, &sv);
527 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
528                 /* x86 specific: need to pop fp register ST0 if saved */
529                 if (r == TREG_ST0) {
530                     o(0xd8dd); /* fstp %st(0) */
531                 }
532 #endif
533 #ifndef TCC_TARGET_X86_64
534                 /* special long long case */
535                 if ((type->t & VT_BTYPE) == VT_LLONG) {
536                     sv.c.ul += 4;
537                     store(p->r2, &sv);
538                 }
539 #endif
540                 l = loc;
541                 saved = 1;
542             }
543             /* mark that stack entry as being saved on the stack */
544             if (p->r & VT_LVAL) {
545                 /* also clear the bounded flag because the
546                    relocation address of the function was stored in
547                    p->c.ul */
548                 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
549             } else {
550                 p->r = lvalue_type(p->type.t) | VT_LOCAL;
551             }
552             p->r2 = VT_CONST;
553             p->c.ul = l;
554         }
555     }
556 }
557
558 #ifdef TCC_TARGET_ARM
559 /* find a register of class 'rc2' with at most one reference on stack.
560  * If none, call get_reg(rc) */
561 ST_FUNC int get_reg_ex(int rc, int rc2)
562 {
563     int r;
564     SValue *p;
565     
566     for(r=0;r<NB_REGS;r++) {
567         if (reg_classes[r] & rc2) {
568             int n;
569             n=0;
570             for(p = vstack; p <= vtop; p++) {
571                 if ((p->r & VT_VALMASK) == r ||
572                     (p->r2 & VT_VALMASK) == r)
573                     n++;
574             }
575             if (n <= 1)
576                 return r;
577         }
578     }
579     return get_reg(rc);
580 }
581 #endif
582
583 /* find a free register of class 'rc'. If none, save one register */
584 ST_FUNC int get_reg(int rc)
585 {
586     int r;
587     SValue *p;
588
589     /* find a free register */
590     for(r=0;r<NB_REGS;r++) {
591         if (reg_classes[r] & rc) {
592             for(p=vstack;p<=vtop;p++) {
593                 if ((p->r & VT_VALMASK) == r ||
594                     (p->r2 & VT_VALMASK) == r)
595                     goto notfound;
596             }
597             return r;
598         }
599     notfound: ;
600     }
601     
602     /* no register left : free the first one on the stack (VERY
603        IMPORTANT to start from the bottom to ensure that we don't
604        spill registers used in gen_opi()) */
605     for(p=vstack;p<=vtop;p++) {
606         /* look at second register (if long long) */
607         r = p->r2 & VT_VALMASK;
608         if (r < VT_CONST && (reg_classes[r] & rc))
609             goto save_found;
610         r = p->r & VT_VALMASK;
611         if (r < VT_CONST && (reg_classes[r] & rc)) {
612         save_found:
613             save_reg(r);
614             return r;
615         }
616     }
617     /* Should never comes here */
618     return -1;
619 }
620
621 /* save registers up to (vtop - n) stack entry */
622 ST_FUNC void save_regs(int n)
623 {
624     int r;
625     SValue *p, *p1;
626     p1 = vtop - n;
627     for(p = vstack;p <= p1; p++) {
628         r = p->r & VT_VALMASK;
629         if (r < VT_CONST) {
630             save_reg(r);
631         }
632     }
633 }
634
635 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
636    if needed */
637 static void move_reg(int r, int s, int t)
638 {
639     SValue sv;
640
641     if (r != s) {
642         save_reg(r);
643         sv.type.t = t;
644         sv.type.ref = NULL;
645         sv.r = s;
646         sv.c.ul = 0;
647         load(r, &sv);
648     }
649 }
650
651 /* get address of vtop (vtop MUST BE an lvalue) */
652 static void gaddrof(void)
653 {
654     if (vtop->r & VT_REF)
655         gv(RC_INT);
656     vtop->r &= ~VT_LVAL;
657     /* tricky: if saved lvalue, then we can go back to lvalue */
658     if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
659         vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
660
661
662 }
663
664 #ifdef CONFIG_TCC_BCHECK
665 /* generate lvalue bound code */
666 static void gbound(void)
667 {
668     int lval_type;
669     CType type1;
670
671     vtop->r &= ~VT_MUSTBOUND;
672     /* if lvalue, then use checking code before dereferencing */
673     if (vtop->r & VT_LVAL) {
674         /* if not VT_BOUNDED value, then make one */
675         if (!(vtop->r & VT_BOUNDED)) {
676             lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
677             /* must save type because we must set it to int to get pointer */
678             type1 = vtop->type;
679             vtop->type.t = VT_INT;
680             gaddrof();
681             vpushi(0);
682             gen_bounded_ptr_add();
683             vtop->r |= lval_type;
684             vtop->type = type1;
685         }
686         /* then check for dereferencing */
687         gen_bounded_ptr_deref();
688     }
689 }
690 #endif
691
692 /* store vtop a register belonging to class 'rc'. lvalues are
693    converted to values. Cannot be used if cannot be converted to
694    register value (such as structures). */
695 ST_FUNC int gv(int rc)
696 {
697     int r, bit_pos, bit_size, size, align, i;
698     int rc2;
699
700     /* NOTE: get_reg can modify vstack[] */
701     if (vtop->type.t & VT_BITFIELD) {
702         CType type;
703         int bits = 32;
704         bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
705         bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
706         /* remove bit field info to avoid loops */
707         vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
708         /* cast to int to propagate signedness in following ops */
709         if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
710             type.t = VT_LLONG;
711             bits = 64;
712         } else
713             type.t = VT_INT;
714         if((vtop->type.t & VT_UNSIGNED) ||
715            (vtop->type.t & VT_BTYPE) == VT_BOOL)
716             type.t |= VT_UNSIGNED;
717         gen_cast(&type);
718         /* generate shifts */
719         vpushi(bits - (bit_pos + bit_size));
720         gen_op(TOK_SHL);
721         vpushi(bits - bit_size);
722         /* NOTE: transformed to SHR if unsigned */
723         gen_op(TOK_SAR);
724         r = gv(rc);
725     } else {
726         if (is_float(vtop->type.t) && 
727             (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
728             Sym *sym;
729             int *ptr;
730             unsigned long offset;
731 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
732             CValue check;
733 #endif
734             
735             /* XXX: unify with initializers handling ? */
736             /* CPUs usually cannot use float constants, so we store them
737                generically in data segment */
738             size = type_size(&vtop->type, &align);
739             offset = (data_section->data_offset + align - 1) & -align;
740             data_section->data_offset = offset;
741             /* XXX: not portable yet */
742 #if defined(__i386__) || defined(__x86_64__)
743             /* Zero pad x87 tenbyte long doubles */
744             if (size == LDOUBLE_SIZE) {
745                 vtop->c.tab[2] &= 0xffff;
746 #if LDOUBLE_SIZE == 16
747                 vtop->c.tab[3] = 0;
748 #endif
749             }
750 #endif
751             ptr = section_ptr_add(data_section, size);
752             size = size >> 2;
753 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
754             check.d = 1;
755             if(check.tab[0])
756                 for(i=0;i<size;i++)
757                     ptr[i] = vtop->c.tab[size-1-i];
758             else
759 #endif
760             for(i=0;i<size;i++)
761                 ptr[i] = vtop->c.tab[i];
762             sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
763             vtop->r |= VT_LVAL | VT_SYM;
764             vtop->sym = sym;
765             vtop->c.ul = 0;
766         }
767 #ifdef CONFIG_TCC_BCHECK
768         if (vtop->r & VT_MUSTBOUND) 
769             gbound();
770 #endif
771
772         r = vtop->r & VT_VALMASK;
773         rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
774         if (rc == RC_IRET)
775             rc2 = RC_LRET;
776 #ifdef TCC_TARGET_X86_64
777         else if (rc == RC_FRET)
778             rc2 = RC_QRET;
779 #endif
780
781         /* need to reload if:
782            - constant
783            - lvalue (need to dereference pointer)
784            - already a register, but not in the right class */
785         if (r >= VT_CONST
786          || (vtop->r & VT_LVAL)
787          || !(reg_classes[r] & rc)
788 #ifdef TCC_TARGET_X86_64
789          || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
790          || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
791 #else
792          || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
793 #endif
794             )
795         {
796             r = get_reg(rc);
797 #ifdef TCC_TARGET_X86_64
798             if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
799                 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
800 #else
801             if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
802                 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
803 #endif
804                 int r2, original_type;
805                 unsigned long long ll;
806                 original_type = vtop->type.t;
807                 /* two register type load : expand to two words
808                    temporarily */
809 #ifndef TCC_TARGET_X86_64
810                 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
811                     /* load constant */
812                     ll = vtop->c.ull;
813                     vtop->c.ui = ll; /* first word */
814                     load(r, vtop);
815                     vtop->r = r; /* save register value */
816                     vpushi(ll >> 32); /* second word */
817                 } else
818 #endif
819                 if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
820                            (vtop->r & VT_LVAL)) {
821                     /* We do not want to modifier the long long
822                        pointer here, so the safest (and less
823                        efficient) is to save all the other registers
824                        in the stack. XXX: totally inefficient. */
825                     save_regs(1);
826                     /* load from memory */
827                     vtop->type.t = load_type;
828                     load(r, vtop);
829                     vdup();
830                     vtop[-1].r = r; /* save register value */
831                     /* increment pointer to get second word */
832                     vtop->type.t = addr_type;
833                     gaddrof();
834                     vpushi(load_size);
835                     gen_op('+');
836                     vtop->r |= VT_LVAL;
837                     vtop->type.t = load_type;
838                 } else {
839                     /* move registers */
840                     load(r, vtop);
841                     vdup();
842                     vtop[-1].r = r; /* save register value */
843                     vtop->r = vtop[-1].r2;
844                 }
845                 /* Allocate second register. Here we rely on the fact that
846                    get_reg() tries first to free r2 of an SValue. */
847                 r2 = get_reg(rc2);
848                 load(r2, vtop);
849                 vpop();
850                 /* write second register */
851                 vtop->r2 = r2;
852                 vtop->type.t = original_type;
853             } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
854                 int t1, t;
855                 /* lvalue of scalar type : need to use lvalue type
856                    because of possible cast */
857                 t = vtop->type.t;
858                 t1 = t;
859                 /* compute memory access type */
860                 if (vtop->r & VT_REF)
861 #ifdef TCC_TARGET_X86_64
862                     t = VT_PTR;
863 #else
864                     t = VT_INT;
865 #endif
866                 else if (vtop->r & VT_LVAL_BYTE)
867                     t = VT_BYTE;
868                 else if (vtop->r & VT_LVAL_SHORT)
869                     t = VT_SHORT;
870                 if (vtop->r & VT_LVAL_UNSIGNED)
871                     t |= VT_UNSIGNED;
872                 vtop->type.t = t;
873                 load(r, vtop);
874                 /* restore wanted type */
875                 vtop->type.t = t1;
876             } else {
877                 /* one register type load */
878                 load(r, vtop);
879             }
880         }
881         vtop->r = r;
882 #ifdef TCC_TARGET_C67
883         /* uses register pairs for doubles */
884         if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) 
885             vtop->r2 = r+1;
886 #endif
887     }
888     return r;
889 }
890
891 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
892 ST_FUNC void gv2(int rc1, int rc2)
893 {
894     int v;
895
896     /* generate more generic register first. But VT_JMP or VT_CMP
897        values must be generated first in all cases to avoid possible
898        reload errors */
899     v = vtop[0].r & VT_VALMASK;
900     if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
901         vswap();
902         gv(rc1);
903         vswap();
904         gv(rc2);
905         /* test if reload is needed for first register */
906         if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
907             vswap();
908             gv(rc1);
909             vswap();
910         }
911     } else {
912         gv(rc2);
913         vswap();
914         gv(rc1);
915         vswap();
916         /* test if reload is needed for first register */
917         if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
918             gv(rc2);
919         }
920     }
921 }
922
923 /* wrapper around RC_FRET to return a register by type */
924 static int rc_fret(int t)
925 {
926 #ifdef TCC_TARGET_X86_64
927     if (t == VT_LDOUBLE) {
928         return RC_ST0;
929     }
930 #endif
931     return RC_FRET;
932 }
933
934 /* wrapper around REG_FRET to return a register by type */
935 static int reg_fret(int t)
936 {
937 #ifdef TCC_TARGET_X86_64
938     if (t == VT_LDOUBLE) {
939         return TREG_ST0;
940     }
941 #endif
942     return REG_FRET;
943 }
944
945 /* expand long long on stack in two int registers */
946 static void lexpand(void)
947 {
948     int u;
949
950     u = vtop->type.t & VT_UNSIGNED;
951     gv(RC_INT);
952     vdup();
953     vtop[0].r = vtop[-1].r2;
954     vtop[0].r2 = VT_CONST;
955     vtop[-1].r2 = VT_CONST;
956     vtop[0].type.t = VT_INT | u;
957     vtop[-1].type.t = VT_INT | u;
958 }
959
960 #ifdef TCC_TARGET_ARM
961 /* expand long long on stack */
962 ST_FUNC void lexpand_nr(void)
963 {
964     int u,v;
965
966     u = vtop->type.t & VT_UNSIGNED;
967     vdup();
968     vtop->r2 = VT_CONST;
969     vtop->type.t = VT_INT | u;
970     v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
971     if (v == VT_CONST) {
972       vtop[-1].c.ui = vtop->c.ull;
973       vtop->c.ui = vtop->c.ull >> 32;
974       vtop->r = VT_CONST;
975     } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
976       vtop->c.ui += 4;
977       vtop->r = vtop[-1].r;
978     } else if (v > VT_CONST) {
979       vtop--;
980       lexpand();
981     } else
982       vtop->r = vtop[-1].r2;
983     vtop[-1].r2 = VT_CONST;
984     vtop[-1].type.t = VT_INT | u;
985 }
986 #endif
987
988 /* build a long long from two ints */
989 static void lbuild(int t)
990 {
991     gv2(RC_INT, RC_INT);
992     vtop[-1].r2 = vtop[0].r;
993     vtop[-1].type.t = t;
994     vpop();
995 }
996
997 /* rotate n first stack elements to the bottom 
998    I1 ... In -> I2 ... In I1 [top is right]
999 */
1000 ST_FUNC void vrotb(int n)
1001 {
1002     int i;
1003     SValue tmp;
1004
1005     tmp = vtop[-n + 1];
1006     for(i=-n+1;i!=0;i++)
1007         vtop[i] = vtop[i+1];
1008     vtop[0] = tmp;
1009 }
1010
1011 /* rotate the n elements before entry e towards the top
1012    I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1013  */
1014 ST_FUNC void vrote(SValue *e, int n)
1015 {
1016     int i;
1017     SValue tmp;
1018
1019     tmp = *e;
1020     for(i = 0;i < n - 1; i++)
1021         e[-i] = e[-i - 1];
1022     e[-n + 1] = tmp;
1023 }
1024
1025 /* rotate n first stack elements to the top
1026    I1 ... In -> In I1 ... I(n-1)  [top is right]
1027  */
1028 ST_FUNC void vrott(int n)
1029 {
1030     vrote(vtop, n);
1031 }
1032
1033 /* pop stack value */
1034 ST_FUNC void vpop(void)
1035 {
1036     int v;
1037     v = vtop->r & VT_VALMASK;
1038 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1039     /* for x86, we need to pop the FP stack */
1040     if (v == TREG_ST0 && !nocode_wanted) {
1041         o(0xd8dd); /* fstp %st(0) */
1042     } else
1043 #endif
1044     if (v == VT_JMP || v == VT_JMPI) {
1045         /* need to put correct jump if && or || without test */
1046         gsym(vtop->c.ul);
1047     }
1048     vtop--;
1049 }
1050
1051 /* convert stack entry to register and duplicate its value in another
1052    register */
1053 static void gv_dup(void)
1054 {
1055     int rc, t, r, r1;
1056     SValue sv;
1057
1058     t = vtop->type.t;
1059     if ((t & VT_BTYPE) == VT_LLONG) {
1060         lexpand();
1061         gv_dup();
1062         vswap();
1063         vrotb(3);
1064         gv_dup();
1065         vrotb(4);
1066         /* stack: H L L1 H1 */
1067         lbuild(t);
1068         vrotb(3);
1069         vrotb(3);
1070         vswap();
1071         lbuild(t);
1072         vswap();
1073     } else {
1074         /* duplicate value */
1075         rc = RC_INT;
1076         sv.type.t = VT_INT;
1077         if (is_float(t)) {
1078             rc = RC_FLOAT;
1079 #ifdef TCC_TARGET_X86_64
1080             if ((t & VT_BTYPE) == VT_LDOUBLE) {
1081                 rc = RC_ST0;
1082             }
1083 #endif
1084             sv.type.t = t;
1085         }
1086         r = gv(rc);
1087         r1 = get_reg(rc);
1088         sv.r = r;
1089         sv.c.ul = 0;
1090         load(r1, &sv); /* move r to r1 */
1091         vdup();
1092         /* duplicates value */
1093         if (r != r1)
1094             vtop->r = r1;
1095     }
1096 }
1097
1098 #ifndef TCC_TARGET_X86_64
1099 /* generate CPU independent (unsigned) long long operations */
1100 static void gen_opl(int op)
1101 {
1102     int t, a, b, op1, c, i;
1103     int func;
1104     unsigned short reg_iret = REG_IRET;
1105     unsigned short reg_lret = REG_LRET;
1106     SValue tmp;
1107
1108     switch(op) {
1109     case '/':
1110     case TOK_PDIV:
1111         func = TOK___divdi3;
1112         goto gen_func;
1113     case TOK_UDIV:
1114         func = TOK___udivdi3;
1115         goto gen_func;
1116     case '%':
1117         func = TOK___moddi3;
1118         goto gen_mod_func;
1119     case TOK_UMOD:
1120         func = TOK___umoddi3;
1121     gen_mod_func:
1122 #ifdef TCC_ARM_EABI
1123         reg_iret = TREG_R2;
1124         reg_lret = TREG_R3;
1125 #endif
1126     gen_func:
1127         /* call generic long long function */
1128         vpush_global_sym(&func_old_type, func);
1129         vrott(3);
1130         gfunc_call(2);
1131         vpushi(0);
1132         vtop->r = reg_iret;
1133         vtop->r2 = reg_lret;
1134         break;
1135     case '^':
1136     case '&':
1137     case '|':
1138     case '*':
1139     case '+':
1140     case '-':
1141         t = vtop->type.t;
1142         vswap();
1143         lexpand();
1144         vrotb(3);
1145         lexpand();
1146         /* stack: L1 H1 L2 H2 */
1147         tmp = vtop[0];
1148         vtop[0] = vtop[-3];
1149         vtop[-3] = tmp;
1150         tmp = vtop[-2];
1151         vtop[-2] = vtop[-3];
1152         vtop[-3] = tmp;
1153         vswap();
1154         /* stack: H1 H2 L1 L2 */
1155         if (op == '*') {
1156             vpushv(vtop - 1);
1157             vpushv(vtop - 1);
1158             gen_op(TOK_UMULL);
1159             lexpand();
1160             /* stack: H1 H2 L1 L2 ML MH */
1161             for(i=0;i<4;i++)
1162                 vrotb(6);
1163             /* stack: ML MH H1 H2 L1 L2 */
1164             tmp = vtop[0];
1165             vtop[0] = vtop[-2];
1166             vtop[-2] = tmp;
1167             /* stack: ML MH H1 L2 H2 L1 */
1168             gen_op('*');
1169             vrotb(3);
1170             vrotb(3);
1171             gen_op('*');
1172             /* stack: ML MH M1 M2 */
1173             gen_op('+');
1174             gen_op('+');
1175         } else if (op == '+' || op == '-') {
1176             /* XXX: add non carry method too (for MIPS or alpha) */
1177             if (op == '+')
1178                 op1 = TOK_ADDC1;
1179             else
1180                 op1 = TOK_SUBC1;
1181             gen_op(op1);
1182             /* stack: H1 H2 (L1 op L2) */
1183             vrotb(3);
1184             vrotb(3);
1185             gen_op(op1 + 1); /* TOK_xxxC2 */
1186         } else {
1187             gen_op(op);
1188             /* stack: H1 H2 (L1 op L2) */
1189             vrotb(3);
1190             vrotb(3);
1191             /* stack: (L1 op L2) H1 H2 */
1192             gen_op(op);
1193             /* stack: (L1 op L2) (H1 op H2) */
1194         }
1195         /* stack: L H */
1196         lbuild(t);
1197         break;
1198     case TOK_SAR:
1199     case TOK_SHR:
1200     case TOK_SHL:
1201         if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1202             t = vtop[-1].type.t;
1203             vswap();
1204             lexpand();
1205             vrotb(3);
1206             /* stack: L H shift */
1207             c = (int)vtop->c.i;
1208             /* constant: simpler */
1209             /* NOTE: all comments are for SHL. the other cases are
1210                done by swaping words */
1211             vpop();
1212             if (op != TOK_SHL)
1213                 vswap();
1214             if (c >= 32) {
1215                 /* stack: L H */
1216                 vpop();
1217                 if (c > 32) {
1218                     vpushi(c - 32);
1219                     gen_op(op);
1220                 }
1221                 if (op != TOK_SAR) {
1222                     vpushi(0);
1223                 } else {
1224                     gv_dup();
1225                     vpushi(31);
1226                     gen_op(TOK_SAR);
1227                 }
1228                 vswap();
1229             } else {
1230                 vswap();
1231                 gv_dup();
1232                 /* stack: H L L */
1233                 vpushi(c);
1234                 gen_op(op);
1235                 vswap();
1236                 vpushi(32 - c);
1237                 if (op == TOK_SHL)
1238                     gen_op(TOK_SHR);
1239                 else
1240                     gen_op(TOK_SHL);
1241                 vrotb(3);
1242                 /* stack: L L H */
1243                 vpushi(c);
1244                 if (op == TOK_SHL)
1245                     gen_op(TOK_SHL);
1246                 else
1247                     gen_op(TOK_SHR);
1248                 gen_op('|');
1249             }
1250             if (op != TOK_SHL)
1251                 vswap();
1252             lbuild(t);
1253         } else {
1254             /* XXX: should provide a faster fallback on x86 ? */
1255             switch(op) {
1256             case TOK_SAR:
1257                 func = TOK___ashrdi3;
1258                 goto gen_func;
1259             case TOK_SHR:
1260                 func = TOK___lshrdi3;
1261                 goto gen_func;
1262             case TOK_SHL:
1263                 func = TOK___ashldi3;
1264                 goto gen_func;
1265             }
1266         }
1267         break;
1268     default:
1269         /* compare operations */
1270         t = vtop->type.t;
1271         vswap();
1272         lexpand();
1273         vrotb(3);
1274         lexpand();
1275         /* stack: L1 H1 L2 H2 */
1276         tmp = vtop[-1];
1277         vtop[-1] = vtop[-2];
1278         vtop[-2] = tmp;
1279         /* stack: L1 L2 H1 H2 */
1280         /* compare high */
1281         op1 = op;
1282         /* when values are equal, we need to compare low words. since
1283            the jump is inverted, we invert the test too. */
1284         if (op1 == TOK_LT)
1285             op1 = TOK_LE;
1286         else if (op1 == TOK_GT)
1287             op1 = TOK_GE;
1288         else if (op1 == TOK_ULT)
1289             op1 = TOK_ULE;
1290         else if (op1 == TOK_UGT)
1291             op1 = TOK_UGE;
1292         a = 0;
1293         b = 0;
1294         gen_op(op1);
1295         if (op1 != TOK_NE) {
1296             a = gtst(1, 0);
1297         }
1298         if (op != TOK_EQ) {
1299             /* generate non equal test */
1300             /* XXX: NOT PORTABLE yet */
1301             if (a == 0) {
1302                 b = gtst(0, 0);
1303             } else {
1304 #if defined(TCC_TARGET_I386)
1305                 b = psym(0x850f, 0);
1306 #elif defined(TCC_TARGET_ARM)
1307                 b = ind;
1308                 o(0x1A000000 | encbranch(ind, 0, 1));
1309 #elif defined(TCC_TARGET_C67)
1310                 tcc_error("not implemented");
1311 #else
1312 #error not supported
1313 #endif
1314             }
1315         }
1316         /* compare low. Always unsigned */
1317         op1 = op;
1318         if (op1 == TOK_LT)
1319             op1 = TOK_ULT;
1320         else if (op1 == TOK_LE)
1321             op1 = TOK_ULE;
1322         else if (op1 == TOK_GT)
1323             op1 = TOK_UGT;
1324         else if (op1 == TOK_GE)
1325             op1 = TOK_UGE;
1326         gen_op(op1);
1327         a = gtst(1, a);
1328         gsym(b);
1329         vseti(VT_JMPI, a);
1330         break;
1331     }
1332 }
1333 #endif
1334
1335 /* handle integer constant optimizations and various machine
1336    independent opt */
1337 static void gen_opic(int op)
1338 {
1339     int c1, c2, t1, t2, n;
1340     SValue *v1, *v2;
1341     long long l1, l2;
1342     typedef unsigned long long U;
1343
1344     v1 = vtop - 1;
1345     v2 = vtop;
1346     t1 = v1->type.t & VT_BTYPE;
1347     t2 = v2->type.t & VT_BTYPE;
1348
1349     if (t1 == VT_LLONG)
1350         l1 = v1->c.ll;
1351     else if (v1->type.t & VT_UNSIGNED)
1352         l1 = v1->c.ui;
1353     else
1354         l1 = v1->c.i;
1355
1356     if (t2 == VT_LLONG)
1357         l2 = v2->c.ll;
1358     else if (v2->type.t & VT_UNSIGNED)
1359         l2 = v2->c.ui;
1360     else
1361         l2 = v2->c.i;
1362
1363     /* currently, we cannot do computations with forward symbols */
1364     c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1365     c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1366     if (c1 && c2) {
1367         switch(op) {
1368         case '+': l1 += l2; break;
1369         case '-': l1 -= l2; break;
1370         case '&': l1 &= l2; break;
1371         case '^': l1 ^= l2; break;
1372         case '|': l1 |= l2; break;
1373         case '*': l1 *= l2; break;
1374
1375         case TOK_PDIV:
1376         case '/':
1377         case '%':
1378         case TOK_UDIV:
1379         case TOK_UMOD:
1380             /* if division by zero, generate explicit division */
1381             if (l2 == 0) {
1382                 if (const_wanted)
1383                     tcc_error("division by zero in constant");
1384                 goto general_case;
1385             }
1386             switch(op) {
1387             default: l1 /= l2; break;
1388             case '%': l1 %= l2; break;
1389             case TOK_UDIV: l1 = (U)l1 / l2; break;
1390             case TOK_UMOD: l1 = (U)l1 % l2; break;
1391             }
1392             break;
1393         case TOK_SHL: l1 <<= l2; break;
1394         case TOK_SHR: l1 = (U)l1 >> l2; break;
1395         case TOK_SAR: l1 >>= l2; break;
1396             /* tests */
1397         case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1398         case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1399         case TOK_EQ: l1 = l1 == l2; break;
1400         case TOK_NE: l1 = l1 != l2; break;
1401         case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1402         case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1403         case TOK_LT: l1 = l1 < l2; break;
1404         case TOK_GE: l1 = l1 >= l2; break;
1405         case TOK_LE: l1 = l1 <= l2; break;
1406         case TOK_GT: l1 = l1 > l2; break;
1407             /* logical */
1408         case TOK_LAND: l1 = l1 && l2; break;
1409         case TOK_LOR: l1 = l1 || l2; break;
1410         default:
1411             goto general_case;
1412         }
1413         v1->c.ll = l1;
1414         vtop--;
1415     } else {
1416         /* if commutative ops, put c2 as constant */
1417         if (c1 && (op == '+' || op == '&' || op == '^' || 
1418                    op == '|' || op == '*')) {
1419             vswap();
1420             c2 = c1; //c = c1, c1 = c2, c2 = c;
1421             l2 = l1; //l = l1, l1 = l2, l2 = l;
1422         }
1423         /* Filter out NOP operations like x*1, x-0, x&-1... */
1424         if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV || 
1425                      op == TOK_PDIV) && 
1426                     l2 == 1) ||
1427                    ((op == '+' || op == '-' || op == '|' || op == '^' || 
1428                      op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) && 
1429                     l2 == 0) ||
1430                    (op == '&' && 
1431                     l2 == -1))) {
1432             /* nothing to do */
1433             vtop--;
1434         } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1435             /* try to use shifts instead of muls or divs */
1436             if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1437                 n = -1;
1438                 while (l2) {
1439                     l2 >>= 1;
1440                     n++;
1441                 }
1442                 vtop->c.ll = n;
1443                 if (op == '*')
1444                     op = TOK_SHL;
1445                 else if (op == TOK_PDIV)
1446                     op = TOK_SAR;
1447                 else
1448                     op = TOK_SHR;
1449             }
1450             goto general_case;
1451         } else if (c2 && (op == '+' || op == '-') &&
1452                    (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1453                     || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1454             /* symbol + constant case */
1455             if (op == '-')
1456                 l2 = -l2;
1457             vtop--;
1458             vtop->c.ll += l2;
1459         } else {
1460         general_case:
1461             if (!nocode_wanted) {
1462                 /* call low level op generator */
1463                 if (t1 == VT_LLONG || t2 == VT_LLONG) 
1464                     gen_opl(op);
1465                 else
1466                     gen_opi(op);
1467             } else {
1468                 vtop--;
1469             }
1470         }
1471     }
1472 }
1473
1474 /* generate a floating point operation with constant propagation */
1475 static void gen_opif(int op)
1476 {
1477     int c1, c2;
1478     SValue *v1, *v2;
1479     long double f1, f2;
1480
1481     v1 = vtop - 1;
1482     v2 = vtop;
1483     /* currently, we cannot do computations with forward symbols */
1484     c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1485     c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1486     if (c1 && c2) {
1487         if (v1->type.t == VT_FLOAT) {
1488             f1 = v1->c.f;
1489             f2 = v2->c.f;
1490         } else if (v1->type.t == VT_DOUBLE) {
1491             f1 = v1->c.d;
1492             f2 = v2->c.d;
1493         } else {
1494             f1 = v1->c.ld;
1495             f2 = v2->c.ld;
1496         }
1497
1498         /* NOTE: we only do constant propagation if finite number (not
1499            NaN or infinity) (ANSI spec) */
1500         if (!ieee_finite(f1) || !ieee_finite(f2))
1501             goto general_case;
1502
1503         switch(op) {
1504         case '+': f1 += f2; break;
1505         case '-': f1 -= f2; break;
1506         case '*': f1 *= f2; break;
1507         case '/': 
1508             if (f2 == 0.0) {
1509                 if (const_wanted)
1510                     tcc_error("division by zero in constant");
1511                 goto general_case;
1512             }
1513             f1 /= f2; 
1514             break;
1515             /* XXX: also handles tests ? */
1516         default:
1517             goto general_case;
1518         }
1519         /* XXX: overflow test ? */
1520         if (v1->type.t == VT_FLOAT) {
1521             v1->c.f = f1;
1522         } else if (v1->type.t == VT_DOUBLE) {
1523             v1->c.d = f1;
1524         } else {
1525             v1->c.ld = f1;
1526         }
1527         vtop--;
1528     } else {
1529     general_case:
1530         if (!nocode_wanted) {
1531             gen_opf(op);
1532         } else {
1533             vtop--;
1534         }
1535     }
1536 }
1537
1538 static int pointed_size(CType *type)
1539 {
1540     int align;
1541     return type_size(pointed_type(type), &align);
1542 }
1543
1544 static void vla_runtime_pointed_size(CType *type)
1545 {
1546     int align;
1547     vla_runtime_type_size(pointed_type(type), &align);
1548 }
1549
1550 static inline int is_null_pointer(SValue *p)
1551 {
1552     if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1553         return 0;
1554     return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1555         ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||
1556         ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr == 0);
1557 }
1558
1559 static inline int is_integer_btype(int bt)
1560 {
1561     return (bt == VT_BYTE || bt == VT_SHORT || 
1562             bt == VT_INT || bt == VT_LLONG);
1563 }
1564
1565 /* check types for comparison or substraction of pointers */
1566 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1567 {
1568     CType *type1, *type2, tmp_type1, tmp_type2;
1569     int bt1, bt2;
1570     
1571     /* null pointers are accepted for all comparisons as gcc */
1572     if (is_null_pointer(p1) || is_null_pointer(p2))
1573         return;
1574     type1 = &p1->type;
1575     type2 = &p2->type;
1576     bt1 = type1->t & VT_BTYPE;
1577     bt2 = type2->t & VT_BTYPE;
1578     /* accept comparison between pointer and integer with a warning */
1579     if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1580         if (op != TOK_LOR && op != TOK_LAND )
1581             tcc_warning("comparison between pointer and integer");
1582         return;
1583     }
1584
1585     /* both must be pointers or implicit function pointers */
1586     if (bt1 == VT_PTR) {
1587         type1 = pointed_type(type1);
1588     } else if (bt1 != VT_FUNC) 
1589         goto invalid_operands;
1590
1591     if (bt2 == VT_PTR) {
1592         type2 = pointed_type(type2);
1593     } else if (bt2 != VT_FUNC) { 
1594     invalid_operands:
1595         tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
1596     }
1597     if ((type1->t & VT_BTYPE) == VT_VOID || 
1598         (type2->t & VT_BTYPE) == VT_VOID)
1599         return;
1600     tmp_type1 = *type1;
1601     tmp_type2 = *type2;
1602     tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1603     tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1604     if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1605         /* gcc-like error if '-' is used */
1606         if (op == '-')
1607             goto invalid_operands;
1608         else
1609             tcc_warning("comparison of distinct pointer types lacks a cast");
1610     }
1611 }
1612
1613 /* generic gen_op: handles types problems */
1614 ST_FUNC void gen_op(int op)
1615 {
1616     int u, t1, t2, bt1, bt2, t;
1617     CType type1;
1618
1619     t1 = vtop[-1].type.t;
1620     t2 = vtop[0].type.t;
1621     bt1 = t1 & VT_BTYPE;
1622     bt2 = t2 & VT_BTYPE;
1623         
1624     if (bt1 == VT_PTR || bt2 == VT_PTR) {
1625         /* at least one operand is a pointer */
1626         /* relationnal op: must be both pointers */
1627         if (op >= TOK_ULT && op <= TOK_LOR) {
1628             check_comparison_pointer_types(vtop - 1, vtop, op);
1629             /* pointers are handled are unsigned */
1630 #ifdef TCC_TARGET_X86_64
1631             t = VT_LLONG | VT_UNSIGNED;
1632 #else
1633             t = VT_INT | VT_UNSIGNED;
1634 #endif
1635             goto std_op;
1636         }
1637         /* if both pointers, then it must be the '-' op */
1638         if (bt1 == VT_PTR && bt2 == VT_PTR) {
1639             if (op != '-')
1640                 tcc_error("cannot use pointers here");
1641             check_comparison_pointer_types(vtop - 1, vtop, op);
1642             /* XXX: check that types are compatible */
1643             if (vtop[-1].type.t & VT_VLA) {
1644                 vla_runtime_pointed_size(&vtop[-1].type);
1645             } else {
1646                 vpushi(pointed_size(&vtop[-1].type));
1647             }
1648             vrott(3);
1649             gen_opic(op);
1650             /* set to integer type */
1651 #ifdef TCC_TARGET_X86_64
1652             vtop->type.t = VT_LLONG;
1653 #else
1654             vtop->type.t = VT_INT; 
1655 #endif
1656             vswap();
1657             gen_op(TOK_PDIV);
1658         } else {
1659             /* exactly one pointer : must be '+' or '-'. */
1660             if (op != '-' && op != '+')
1661                 tcc_error("cannot use pointers here");
1662             /* Put pointer as first operand */
1663             if (bt2 == VT_PTR) {
1664                 vswap();
1665                 swap(&t1, &t2);
1666             }
1667             type1 = vtop[-1].type;
1668             type1.t &= ~VT_ARRAY;
1669             if (vtop[-1].type.t & VT_VLA)
1670                 vla_runtime_pointed_size(&vtop[-1].type);
1671             else {
1672                 u = pointed_size(&vtop[-1].type);
1673                 if (u < 0)
1674                     tcc_error("unknown array element size");
1675 #ifdef TCC_TARGET_X86_64
1676                 vpushll(u);
1677 #else
1678                 /* XXX: cast to int ? (long long case) */
1679                 vpushi(u);
1680 #endif
1681             }
1682             gen_op('*');
1683 #ifdef CONFIG_TCC_BCHECK
1684             /* if evaluating constant expression, no code should be
1685                generated, so no bound check */
1686             if (tcc_state->do_bounds_check && !const_wanted) {
1687                 /* if bounded pointers, we generate a special code to
1688                    test bounds */
1689                 if (op == '-') {
1690                     vpushi(0);
1691                     vswap();
1692                     gen_op('-');
1693                 }
1694                 gen_bounded_ptr_add();
1695             } else
1696 #endif
1697             {
1698                 gen_opic(op);
1699             }
1700             /* put again type if gen_opic() swaped operands */
1701             vtop->type = type1;
1702         }
1703     } else if (is_float(bt1) || is_float(bt2)) {
1704         /* compute bigger type and do implicit casts */
1705         if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1706             t = VT_LDOUBLE;
1707         } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1708             t = VT_DOUBLE;
1709         } else {
1710             t = VT_FLOAT;
1711         }
1712         /* floats can only be used for a few operations */
1713         if (op != '+' && op != '-' && op != '*' && op != '/' &&
1714             (op < TOK_ULT || op > TOK_GT))
1715             tcc_error("invalid operands for binary operation");
1716         goto std_op;
1717     } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
1718         t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
1719         if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (t | VT_UNSIGNED))
1720           t |= VT_UNSIGNED;
1721         goto std_op;
1722     } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1723         /* cast to biggest op */
1724         t = VT_LLONG;
1725         /* convert to unsigned if it does not fit in a long long */
1726         if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1727             (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1728             t |= VT_UNSIGNED;
1729         goto std_op;
1730     } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
1731         tcc_error("comparison of struct");
1732     } else {
1733         /* integer operations */
1734         t = VT_INT;
1735         /* convert to unsigned if it does not fit in an integer */
1736         if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1737             (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1738             t |= VT_UNSIGNED;
1739     std_op:
1740         /* XXX: currently, some unsigned operations are explicit, so
1741            we modify them here */
1742         if (t & VT_UNSIGNED) {
1743             if (op == TOK_SAR)
1744                 op = TOK_SHR;
1745             else if (op == '/')
1746                 op = TOK_UDIV;
1747             else if (op == '%')
1748                 op = TOK_UMOD;
1749             else if (op == TOK_LT)
1750                 op = TOK_ULT;
1751             else if (op == TOK_GT)
1752                 op = TOK_UGT;
1753             else if (op == TOK_LE)
1754                 op = TOK_ULE;
1755             else if (op == TOK_GE)
1756                 op = TOK_UGE;
1757         }
1758         vswap();
1759         type1.t = t;
1760         gen_cast(&type1);
1761         vswap();
1762         /* special case for shifts and long long: we keep the shift as
1763            an integer */
1764         if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1765             type1.t = VT_INT;
1766         gen_cast(&type1);
1767         if (is_float(t))
1768             gen_opif(op);
1769         else
1770             gen_opic(op);
1771         if (op >= TOK_ULT && op <= TOK_GT) {
1772             /* relationnal op: the result is an int */
1773             vtop->type.t = VT_INT;
1774         } else {
1775             vtop->type.t = t;
1776         }
1777     }
1778 }
1779
1780 #ifndef TCC_TARGET_ARM
1781 /* generic itof for unsigned long long case */
1782 static void gen_cvt_itof1(int t)
1783 {
1784     if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == 
1785         (VT_LLONG | VT_UNSIGNED)) {
1786
1787         if (t == VT_FLOAT)
1788             vpush_global_sym(&func_old_type, TOK___floatundisf);
1789 #if LDOUBLE_SIZE != 8
1790         else if (t == VT_LDOUBLE)
1791             vpush_global_sym(&func_old_type, TOK___floatundixf);
1792 #endif
1793         else
1794             vpush_global_sym(&func_old_type, TOK___floatundidf);
1795         vrott(2);
1796         gfunc_call(1);
1797         vpushi(0);
1798         vtop->r = reg_fret(t);
1799     } else {
1800         gen_cvt_itof(t);
1801     }
1802 }
1803 #endif
1804
1805 /* generic ftoi for unsigned long long case */
1806 static void gen_cvt_ftoi1(int t)
1807 {
1808     int st;
1809
1810     if (t == (VT_LLONG | VT_UNSIGNED)) {
1811         /* not handled natively */
1812         st = vtop->type.t & VT_BTYPE;
1813         if (st == VT_FLOAT)
1814             vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1815 #if LDOUBLE_SIZE != 8
1816         else if (st == VT_LDOUBLE)
1817             vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1818 #endif
1819         else
1820             vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1821         vrott(2);
1822         gfunc_call(1);
1823         vpushi(0);
1824         vtop->r = REG_IRET;
1825         vtop->r2 = REG_LRET;
1826     } else {
1827         gen_cvt_ftoi(t);
1828     }
1829 }
1830
1831 /* force char or short cast */
1832 static void force_charshort_cast(int t)
1833 {
1834     int bits, dbt;
1835     dbt = t & VT_BTYPE;
1836     /* XXX: add optimization if lvalue : just change type and offset */
1837     if (dbt == VT_BYTE)
1838         bits = 8;
1839     else
1840         bits = 16;
1841     if (t & VT_UNSIGNED) {
1842         vpushi((1 << bits) - 1);
1843         gen_op('&');
1844     } else {
1845         bits = 32 - bits;
1846         vpushi(bits);
1847         gen_op(TOK_SHL);
1848         /* result must be signed or the SAR is converted to an SHL
1849            This was not the case when "t" was a signed short
1850            and the last value on the stack was an unsigned int */
1851         vtop->type.t &= ~VT_UNSIGNED;
1852         vpushi(bits);
1853         gen_op(TOK_SAR);
1854     }
1855 }
1856
1857 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1858 static void gen_cast(CType *type)
1859 {
1860     int sbt, dbt, sf, df, c, p;
1861
1862     /* special delayed cast for char/short */
1863     /* XXX: in some cases (multiple cascaded casts), it may still
1864        be incorrect */
1865     if (vtop->r & VT_MUSTCAST) {
1866         vtop->r &= ~VT_MUSTCAST;
1867         force_charshort_cast(vtop->type.t);
1868     }
1869
1870     /* bitfields first get cast to ints */
1871     if (vtop->type.t & VT_BITFIELD) {
1872         gv(RC_INT);
1873     }
1874
1875     dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1876     sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1877
1878     if (sbt != dbt) {
1879         sf = is_float(sbt);
1880         df = is_float(dbt);
1881         c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1882         p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1883         if (c) {
1884             /* constant case: we can do it now */
1885             /* XXX: in ISOC, cannot do it if error in convert */
1886             if (sbt == VT_FLOAT)
1887                 vtop->c.ld = vtop->c.f;
1888             else if (sbt == VT_DOUBLE)
1889                 vtop->c.ld = vtop->c.d;
1890
1891             if (df) {
1892                 if ((sbt & VT_BTYPE) == VT_LLONG) {
1893                     if (sbt & VT_UNSIGNED)
1894                         vtop->c.ld = vtop->c.ull;
1895                     else
1896                         vtop->c.ld = vtop->c.ll;
1897                 } else if(!sf) {
1898                     if (sbt & VT_UNSIGNED)
1899                         vtop->c.ld = vtop->c.ui;
1900                     else
1901                         vtop->c.ld = vtop->c.i;
1902                 }
1903
1904                 if (dbt == VT_FLOAT)
1905                     vtop->c.f = (float)vtop->c.ld;
1906                 else if (dbt == VT_DOUBLE)
1907                     vtop->c.d = (double)vtop->c.ld;
1908             } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1909                 vtop->c.ull = (unsigned long long)vtop->c.ld;
1910             } else if (sf && dbt == VT_BOOL) {
1911                 vtop->c.i = (vtop->c.ld != 0);
1912             } else {
1913                 if(sf)
1914                     vtop->c.ll = (long long)vtop->c.ld;
1915                 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1916                     vtop->c.ll = vtop->c.ull;
1917                 else if (sbt & VT_UNSIGNED)
1918                     vtop->c.ll = vtop->c.ui;
1919 #ifdef TCC_TARGET_X86_64
1920                 else if (sbt == VT_PTR)
1921                     ;
1922 #endif
1923                 else if (sbt != VT_LLONG)
1924                     vtop->c.ll = vtop->c.i;
1925
1926                 if (dbt == (VT_LLONG|VT_UNSIGNED))
1927                     vtop->c.ull = vtop->c.ll;
1928                 else if (dbt == VT_BOOL)
1929                     vtop->c.i = (vtop->c.ll != 0);
1930                 else if (dbt != VT_LLONG) {
1931                     int s = 0;
1932                     if ((dbt & VT_BTYPE) == VT_BYTE)
1933                         s = 24;
1934                     else if ((dbt & VT_BTYPE) == VT_SHORT)
1935                         s = 16;
1936
1937                     if(dbt & VT_UNSIGNED)
1938                         vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
1939                     else
1940                         vtop->c.i = ((int)vtop->c.ll << s) >> s;
1941                 }
1942             }
1943         } else if (p && dbt == VT_BOOL) {
1944             vtop->r = VT_CONST;
1945             vtop->c.i = 1;
1946         } else if (!nocode_wanted) {
1947             /* non constant case: generate code */
1948             if (sf && df) {
1949                 /* convert from fp to fp */
1950                 gen_cvt_ftof(dbt);
1951             } else if (df) {
1952                 /* convert int to fp */
1953                 gen_cvt_itof1(dbt);
1954             } else if (sf) {
1955                 /* convert fp to int */
1956                 if (dbt == VT_BOOL) {
1957                      vpushi(0);
1958                      gen_op(TOK_NE);
1959                 } else {
1960                     /* we handle char/short/etc... with generic code */
1961                     if (dbt != (VT_INT | VT_UNSIGNED) &&
1962                         dbt != (VT_LLONG | VT_UNSIGNED) &&
1963                         dbt != VT_LLONG)
1964                         dbt = VT_INT;
1965                     gen_cvt_ftoi1(dbt);
1966                     if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
1967                         /* additional cast for char/short... */
1968                         vtop->type.t = dbt;
1969                         gen_cast(type);
1970                     }
1971                 }
1972 #ifndef TCC_TARGET_X86_64
1973             } else if ((dbt & VT_BTYPE) == VT_LLONG) {
1974                 if ((sbt & VT_BTYPE) != VT_LLONG) {
1975                     /* scalar to long long */
1976                     /* machine independent conversion */
1977                     gv(RC_INT);
1978                     /* generate high word */
1979                     if (sbt == (VT_INT | VT_UNSIGNED)) {
1980                         vpushi(0);
1981                         gv(RC_INT);
1982                     } else {
1983                         if (sbt == VT_PTR) {
1984                             /* cast from pointer to int before we apply
1985                                shift operation, which pointers don't support*/
1986                             gen_cast(&int_type);
1987                         }
1988                         gv_dup();
1989                         vpushi(31);
1990                         gen_op(TOK_SAR);
1991                     }
1992                     /* patch second register */
1993                     vtop[-1].r2 = vtop->r;
1994                     vpop();
1995                 }
1996 #else
1997             } else if ((dbt & VT_BTYPE) == VT_LLONG ||
1998                        (dbt & VT_BTYPE) == VT_PTR ||
1999                        (dbt & VT_BTYPE) == VT_FUNC) {
2000                 if ((sbt & VT_BTYPE) != VT_LLONG &&
2001                     (sbt & VT_BTYPE) != VT_PTR &&
2002                     (sbt & VT_BTYPE) != VT_FUNC) {
2003                     /* need to convert from 32bit to 64bit */
2004                     int r = gv(RC_INT);
2005                     if (sbt != (VT_INT | VT_UNSIGNED)) {
2006                         /* x86_64 specific: movslq */
2007                         o(0x6348);
2008                         o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
2009                     }
2010                 }
2011 #endif
2012             } else if (dbt == VT_BOOL) {
2013                 /* scalar to bool */
2014                 vpushi(0);
2015                 gen_op(TOK_NE);
2016             } else if ((dbt & VT_BTYPE) == VT_BYTE || 
2017                        (dbt & VT_BTYPE) == VT_SHORT) {
2018                 if (sbt == VT_PTR) {
2019                     vtop->type.t = VT_INT;
2020                     tcc_warning("nonportable conversion from pointer to char/short");
2021                 }
2022                 force_charshort_cast(dbt);
2023             } else if ((dbt & VT_BTYPE) == VT_INT) {
2024                 /* scalar to int */
2025                 if (sbt == VT_LLONG) {
2026                     /* from long long: just take low order word */
2027                     lexpand();
2028                     vpop();
2029                 } 
2030                 /* if lvalue and single word type, nothing to do because
2031                    the lvalue already contains the real type size (see
2032                    VT_LVAL_xxx constants) */
2033             }
2034         }
2035     } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
2036         /* if we are casting between pointer types,
2037            we must update the VT_LVAL_xxx size */
2038         vtop->r = (vtop->r & ~VT_LVAL_TYPE)
2039                   | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
2040     }
2041     vtop->type = *type;
2042 }
2043
2044 /* return type size as known at compile time. Put alignment at 'a' */
2045 ST_FUNC int type_size(CType *type, int *a)
2046 {
2047     Sym *s;
2048     int bt;
2049
2050     bt = type->t & VT_BTYPE;
2051     if (bt == VT_STRUCT) {
2052         /* struct/union */
2053         s = type->ref;
2054         *a = s->r;
2055         return s->c;
2056     } else if (bt == VT_PTR) {
2057         if (type->t & VT_ARRAY) {
2058             int ts;
2059
2060             s = type->ref;
2061             ts = type_size(&s->type, a);
2062
2063             if (ts < 0 && s->c < 0)
2064                 ts = -ts;
2065
2066             return ts * s->c;
2067         } else {
2068             *a = PTR_SIZE;
2069             return PTR_SIZE;
2070         }
2071     } else if (bt == VT_LDOUBLE) {
2072         *a = LDOUBLE_ALIGN;
2073         return LDOUBLE_SIZE;
2074     } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2075 #ifdef TCC_TARGET_I386
2076 #ifdef TCC_TARGET_PE
2077         *a = 8;
2078 #else
2079         *a = 4;
2080 #endif
2081 #elif defined(TCC_TARGET_ARM)
2082 #ifdef TCC_ARM_EABI
2083         *a = 8; 
2084 #else
2085         *a = 4;
2086 #endif
2087 #else
2088         *a = 8;
2089 #endif
2090         return 8;
2091     } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
2092         *a = 4;
2093         return 4;
2094     } else if (bt == VT_SHORT) {
2095         *a = 2;
2096         return 2;
2097     } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
2098         *a = 8;
2099         return 16;
2100     } else {
2101         /* char, void, function, _Bool */
2102         *a = 1;
2103         return 1;
2104     }
2105 }
2106
2107 /* push type size as known at runtime time on top of value stack. Put
2108    alignment at 'a' */
2109 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2110 {
2111     if (type->t & VT_VLA) {
2112         vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2113     } else {
2114         vpushi(type_size(type, a));
2115     }
2116 }
2117
2118 static void vla_sp_save(void) {
2119     if (!(vla_flags & VLA_SP_LOC_SET)) {
2120         *vla_sp_loc = (loc -= PTR_SIZE);
2121         vla_flags |= VLA_SP_LOC_SET;
2122     }
2123     if (!(vla_flags & VLA_SP_SAVED)) {
2124         gen_vla_sp_save(*vla_sp_loc);
2125         vla_flags |= VLA_SP_SAVED;
2126     }
2127 }
2128
2129 /* return the pointed type of t */
2130 static inline CType *pointed_type(CType *type)
2131 {
2132     return &type->ref->type;
2133 }
2134
2135 /* modify type so that its it is a pointer to type. */
2136 ST_FUNC void mk_pointer(CType *type)
2137 {
2138     Sym *s;
2139     s = sym_push(SYM_FIELD, type, 0, -1);
2140     type->t = VT_PTR | (type->t & ~VT_TYPE);
2141     type->ref = s;
2142 }
2143
2144 /* compare function types. OLD functions match any new functions */
2145 static int is_compatible_func(CType *type1, CType *type2)
2146 {
2147     Sym *s1, *s2;
2148
2149     s1 = type1->ref;
2150     s2 = type2->ref;
2151     if (!is_compatible_types(&s1->type, &s2->type))
2152         return 0;
2153     /* check func_call */
2154     if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
2155         return 0;
2156     /* XXX: not complete */
2157     if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2158         return 1;
2159     if (s1->c != s2->c)
2160         return 0;
2161     while (s1 != NULL) {
2162         if (s2 == NULL)
2163             return 0;
2164         if (!is_compatible_parameter_types(&s1->type, &s2->type))
2165             return 0;
2166         s1 = s1->next;
2167         s2 = s2->next;
2168     }
2169     if (s2)
2170         return 0;
2171     return 1;
2172 }
2173
2174 /* return true if type1 and type2 are the same.  If unqualified is
2175    true, qualifiers on the types are ignored.
2176
2177    - enums are not checked as gcc __builtin_types_compatible_p () 
2178  */
2179 static int compare_types(CType *type1, CType *type2, int unqualified)
2180 {
2181     int bt1, t1, t2;
2182
2183     t1 = type1->t & VT_TYPE;
2184     t2 = type2->t & VT_TYPE;
2185     if (unqualified) {
2186         /* strip qualifiers before comparing */
2187         t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2188         t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2189     }
2190     /* XXX: bitfields ? */
2191     if (t1 != t2)
2192         return 0;
2193     /* test more complicated cases */
2194     bt1 = t1 & VT_BTYPE;
2195     if (bt1 == VT_PTR) {
2196         type1 = pointed_type(type1);
2197         type2 = pointed_type(type2);
2198         return is_compatible_types(type1, type2);
2199     } else if (bt1 == VT_STRUCT) {
2200         return (type1->ref == type2->ref);
2201     } else if (bt1 == VT_FUNC) {
2202         return is_compatible_func(type1, type2);
2203     } else {
2204         return 1;
2205     }
2206 }
2207
2208 /* return true if type1 and type2 are exactly the same (including
2209    qualifiers). 
2210 */
2211 static int is_compatible_types(CType *type1, CType *type2)
2212 {
2213     return compare_types(type1,type2,0);
2214 }
2215
2216 /* return true if type1 and type2 are the same (ignoring qualifiers).
2217 */
2218 static int is_compatible_parameter_types(CType *type1, CType *type2)
2219 {
2220     return compare_types(type1,type2,1);
2221 }
2222
2223 /* print a type. If 'varstr' is not NULL, then the variable is also
2224    printed in the type */
2225 /* XXX: union */
2226 /* XXX: add array and function pointers */
2227 static void type_to_str(char *buf, int buf_size, 
2228                  CType *type, const char *varstr)
2229 {
2230     int bt, v, t;
2231     Sym *s, *sa;
2232     char buf1[256];
2233     const char *tstr;
2234
2235     t = type->t & VT_TYPE;
2236     bt = t & VT_BTYPE;
2237     buf[0] = '\0';
2238     if (t & VT_CONSTANT)
2239         pstrcat(buf, buf_size, "const ");
2240     if (t & VT_VOLATILE)
2241         pstrcat(buf, buf_size, "volatile ");
2242     if (t & VT_UNSIGNED)
2243         pstrcat(buf, buf_size, "unsigned ");
2244     switch(bt) {
2245     case VT_VOID:
2246         tstr = "void";
2247         goto add_tstr;
2248     case VT_BOOL:
2249         tstr = "_Bool";
2250         goto add_tstr;
2251     case VT_BYTE:
2252         tstr = "char";
2253         goto add_tstr;
2254     case VT_SHORT:
2255         tstr = "short";
2256         goto add_tstr;
2257     case VT_INT:
2258         tstr = "int";
2259         goto add_tstr;
2260     case VT_LONG:
2261         tstr = "long";
2262         goto add_tstr;
2263     case VT_LLONG:
2264         tstr = "long long";
2265         goto add_tstr;
2266     case VT_FLOAT:
2267         tstr = "float";
2268         goto add_tstr;
2269     case VT_DOUBLE:
2270         tstr = "double";
2271         goto add_tstr;
2272     case VT_LDOUBLE:
2273         tstr = "long double";
2274     add_tstr:
2275         pstrcat(buf, buf_size, tstr);
2276         break;
2277     case VT_ENUM:
2278     case VT_STRUCT:
2279         if (bt == VT_STRUCT)
2280             tstr = "struct ";
2281         else
2282             tstr = "enum ";
2283         pstrcat(buf, buf_size, tstr);
2284         v = type->ref->v & ~SYM_STRUCT;
2285         if (v >= SYM_FIRST_ANOM)
2286             pstrcat(buf, buf_size, "<anonymous>");
2287         else
2288             pstrcat(buf, buf_size, get_tok_str(v, NULL));
2289         break;
2290     case VT_FUNC:
2291         s = type->ref;
2292         type_to_str(buf, buf_size, &s->type, varstr);
2293         pstrcat(buf, buf_size, "(");
2294         sa = s->next;
2295         while (sa != NULL) {
2296             type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2297             pstrcat(buf, buf_size, buf1);
2298             sa = sa->next;
2299             if (sa)
2300                 pstrcat(buf, buf_size, ", ");
2301         }
2302         pstrcat(buf, buf_size, ")");
2303         goto no_var;
2304     case VT_PTR:
2305         s = type->ref;
2306         pstrcpy(buf1, sizeof(buf1), "*");
2307         if (varstr)
2308             pstrcat(buf1, sizeof(buf1), varstr);
2309         type_to_str(buf, buf_size, &s->type, buf1);
2310         goto no_var;
2311     }
2312     if (varstr) {
2313         pstrcat(buf, buf_size, " ");
2314         pstrcat(buf, buf_size, varstr);
2315     }
2316  no_var: ;
2317 }
2318
2319 /* verify type compatibility to store vtop in 'dt' type, and generate
2320    casts if needed. */
2321 static void gen_assign_cast(CType *dt)
2322 {
2323     CType *st, *type1, *type2, tmp_type1, tmp_type2;
2324     char buf1[256], buf2[256];
2325     int dbt, sbt;
2326
2327     st = &vtop->type; /* source type */
2328     dbt = dt->t & VT_BTYPE;
2329     sbt = st->t & VT_BTYPE;
2330     if (sbt == VT_VOID)
2331         tcc_error("Cannot assign void value");
2332     if (dt->t & VT_CONSTANT)
2333         tcc_warning("assignment of read-only location");
2334     switch(dbt) {
2335     case VT_PTR:
2336         /* special cases for pointers */
2337         /* '0' can also be a pointer */
2338         if (is_null_pointer(vtop))
2339             goto type_ok;
2340         /* accept implicit pointer to integer cast with warning */
2341         if (is_integer_btype(sbt)) {
2342             tcc_warning("assignment makes pointer from integer without a cast");
2343             goto type_ok;
2344         }
2345         type1 = pointed_type(dt);
2346         /* a function is implicitely a function pointer */
2347         if (sbt == VT_FUNC) {
2348             if ((type1->t & VT_BTYPE) != VT_VOID &&
2349                 !is_compatible_types(pointed_type(dt), st))
2350                 tcc_warning("assignment from incompatible pointer type");
2351             goto type_ok;
2352         }
2353         if (sbt != VT_PTR)
2354             goto error;
2355         type2 = pointed_type(st);
2356         if ((type1->t & VT_BTYPE) == VT_VOID || 
2357             (type2->t & VT_BTYPE) == VT_VOID) {
2358             /* void * can match anything */
2359         } else {
2360             /* exact type match, except for unsigned */
2361             tmp_type1 = *type1;
2362             tmp_type2 = *type2;
2363             tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2364             tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2365             if (!is_compatible_types(&tmp_type1, &tmp_type2))
2366                 tcc_warning("assignment from incompatible pointer type");
2367         }
2368         /* check const and volatile */
2369         if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2370             (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2371             tcc_warning("assignment discards qualifiers from pointer target type");
2372         break;
2373     case VT_BYTE:
2374     case VT_SHORT:
2375     case VT_INT:
2376     case VT_LLONG:
2377         if (sbt == VT_PTR || sbt == VT_FUNC) {
2378             tcc_warning("assignment makes integer from pointer without a cast");
2379         }
2380         /* XXX: more tests */
2381         break;
2382     case VT_STRUCT:
2383         tmp_type1 = *dt;
2384         tmp_type2 = *st;
2385         tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2386         tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2387         if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2388         error:
2389             type_to_str(buf1, sizeof(buf1), st, NULL);
2390             type_to_str(buf2, sizeof(buf2), dt, NULL);
2391             tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
2392         }
2393         break;
2394     }
2395  type_ok:
2396     gen_cast(dt);
2397 }
2398
2399 /* store vtop in lvalue pushed on stack */
2400 ST_FUNC void vstore(void)
2401 {
2402     int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2403
2404     ft = vtop[-1].type.t;
2405     sbt = vtop->type.t & VT_BTYPE;
2406     dbt = ft & VT_BTYPE;
2407     if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2408          (sbt == VT_INT && dbt == VT_SHORT))
2409         && !(vtop->type.t & VT_BITFIELD)) {
2410         /* optimize char/short casts */
2411         delayed_cast = VT_MUSTCAST;
2412         vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2413         /* XXX: factorize */
2414         if (ft & VT_CONSTANT)
2415             tcc_warning("assignment of read-only location");
2416     } else {
2417         delayed_cast = 0;
2418         if (!(ft & VT_BITFIELD))
2419             gen_assign_cast(&vtop[-1].type);
2420     }
2421
2422     if (sbt == VT_STRUCT) {
2423         /* if structure, only generate pointer */
2424         /* structure assignment : generate memcpy */
2425         /* XXX: optimize if small size */
2426         if (!nocode_wanted) {
2427             size = type_size(&vtop->type, &align);
2428
2429             /* destination */
2430             vswap();
2431             vtop->type.t = VT_PTR;
2432             gaddrof();
2433
2434             /* address of memcpy() */
2435 #ifdef TCC_ARM_EABI
2436             if(!(align & 7))
2437                 vpush_global_sym(&func_old_type, TOK_memcpy8);
2438             else if(!(align & 3))
2439                 vpush_global_sym(&func_old_type, TOK_memcpy4);
2440             else
2441 #endif
2442             vpush_global_sym(&func_old_type, TOK_memcpy);
2443
2444             vswap();
2445             /* source */
2446             vpushv(vtop - 2);
2447             vtop->type.t = VT_PTR;
2448             gaddrof();
2449             /* type size */
2450             vpushi(size);
2451             gfunc_call(3);
2452         } else {
2453             vswap();
2454             vpop();
2455         }
2456         /* leave source on stack */
2457     } else if (ft & VT_BITFIELD) {
2458         /* bitfield store handling */
2459         bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2460         bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2461         /* remove bit field info to avoid loops */
2462         vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2463
2464         /* duplicate source into other register */
2465         gv_dup();
2466         vswap();
2467         vrott(3);
2468
2469         if((ft & VT_BTYPE) == VT_BOOL) {
2470             gen_cast(&vtop[-1].type);
2471             vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2472         }
2473
2474         /* duplicate destination */
2475         vdup();
2476         vtop[-1] = vtop[-2];
2477
2478         /* mask and shift source */
2479         if((ft & VT_BTYPE) != VT_BOOL) {
2480             if((ft & VT_BTYPE) == VT_LLONG) {
2481                 vpushll((1ULL << bit_size) - 1ULL);
2482             } else {
2483                 vpushi((1 << bit_size) - 1);
2484             }
2485             gen_op('&');
2486         }
2487         vpushi(bit_pos);
2488         gen_op(TOK_SHL);
2489         /* load destination, mask and or with source */
2490         vswap();
2491         if((ft & VT_BTYPE) == VT_LLONG) {
2492             vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2493         } else {
2494             vpushi(~(((1 << bit_size) - 1) << bit_pos));
2495         }
2496         gen_op('&');
2497         gen_op('|');
2498         /* store result */
2499         vstore();
2500
2501         /* pop off shifted source from "duplicate source..." above */
2502         vpop();
2503
2504     } else {
2505 #ifdef CONFIG_TCC_BCHECK
2506         /* bound check case */
2507         if (vtop[-1].r & VT_MUSTBOUND) {
2508             vswap();
2509             gbound();
2510             vswap();
2511         }
2512 #endif
2513         if (!nocode_wanted) {
2514             rc = RC_INT;
2515             if (is_float(ft)) {
2516                 rc = RC_FLOAT;
2517 #ifdef TCC_TARGET_X86_64
2518                 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2519                     rc = RC_ST0;
2520                 } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
2521                     rc = RC_FRET;
2522                 }
2523 #endif
2524             }
2525             r = gv(rc);  /* generate value */
2526             /* if lvalue was saved on stack, must read it */
2527             if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2528                 SValue sv;
2529                 t = get_reg(RC_INT);
2530 #ifdef TCC_TARGET_X86_64
2531                 sv.type.t = VT_PTR;
2532 #else
2533                 sv.type.t = VT_INT;
2534 #endif
2535                 sv.r = VT_LOCAL | VT_LVAL;
2536                 sv.c.ul = vtop[-1].c.ul;
2537                 load(t, &sv);
2538                 vtop[-1].r = t | VT_LVAL;
2539             }
2540             /* two word case handling : store second register at word + 4 (or +8 for x86-64)  */
2541 #ifdef TCC_TARGET_X86_64
2542             if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
2543                 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
2544 #else
2545             if ((ft & VT_BTYPE) == VT_LLONG) {
2546                 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
2547 #endif
2548                 vtop[-1].type.t = load_type;
2549                 store(r, vtop - 1);
2550                 vswap();
2551                 /* convert to int to increment easily */
2552                 vtop->type.t = addr_type;
2553                 gaddrof();
2554                 vpushi(load_size);
2555                 gen_op('+');
2556                 vtop->r |= VT_LVAL;
2557                 vswap();
2558                 vtop[-1].type.t = load_type;
2559                 /* XXX: it works because r2 is spilled last ! */
2560                 store(vtop->r2, vtop - 1);
2561             } else {
2562                 store(r, vtop - 1);
2563             }
2564         }
2565         vswap();
2566         vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2567         vtop->r |= delayed_cast;
2568     }
2569 }
2570
2571 /* post defines POST/PRE add. c is the token ++ or -- */
2572 ST_FUNC void inc(int post, int c)
2573 {
2574     test_lvalue();
2575     vdup(); /* save lvalue */
2576     if (post) {
2577         gv_dup(); /* duplicate value */
2578         vrotb(3);
2579         vrotb(3);
2580     }
2581     /* add constant */
2582     vpushi(c - TOK_MID); 
2583     gen_op('+');
2584     vstore(); /* store value */
2585     if (post)
2586         vpop(); /* if post op, return saved value */
2587 }
2588
2589 /* Parse GNUC __attribute__ extension. Currently, the following
2590    extensions are recognized:
2591    - aligned(n) : set data/function alignment.
2592    - packed : force data alignment to 1
2593    - section(x) : generate data/code in this section.
2594    - unused : currently ignored, but may be used someday.
2595    - regparm(n) : pass function parameters in registers (i386 only)
2596  */
2597 static void parse_attribute(AttributeDef *ad)
2598 {
2599     int t, n;
2600     
2601     while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2602     next();
2603     skip('(');
2604     skip('(');
2605     while (tok != ')') {
2606         if (tok < TOK_IDENT)
2607             expect("attribute name");
2608         t = tok;
2609         next();
2610         switch(t) {
2611         case TOK_SECTION1:
2612         case TOK_SECTION2:
2613             skip('(');
2614             if (tok != TOK_STR)
2615                 expect("section name");
2616             ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2617             next();
2618             skip(')');
2619             break;
2620         case TOK_ALIAS1:
2621         case TOK_ALIAS2:
2622             skip('(');
2623             if (tok != TOK_STR)
2624                 expect("alias(\"target\")");
2625             ad->alias_target = /* save string as token, for later */
2626               tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
2627             next();
2628             skip(')');
2629             break;
2630         case TOK_ALIGNED1:
2631         case TOK_ALIGNED2:
2632             if (tok == '(') {
2633                 next();
2634                 n = expr_const();
2635                 if (n <= 0 || (n & (n - 1)) != 0) 
2636                     tcc_error("alignment must be a positive power of two");
2637                 skip(')');
2638             } else {
2639                 n = MAX_ALIGN;
2640             }
2641             ad->aligned = n;
2642             break;
2643         case TOK_PACKED1:
2644         case TOK_PACKED2:
2645             ad->packed = 1;
2646             break;
2647         case TOK_WEAK1:
2648         case TOK_WEAK2:
2649             ad->weak = 1;
2650             break;
2651         case TOK_UNUSED1:
2652         case TOK_UNUSED2:
2653             /* currently, no need to handle it because tcc does not
2654                track unused objects */
2655             break;
2656         case TOK_NORETURN1:
2657         case TOK_NORETURN2:
2658             /* currently, no need to handle it because tcc does not
2659                track unused objects */
2660             break;
2661         case TOK_CDECL1:
2662         case TOK_CDECL2:
2663         case TOK_CDECL3:
2664             ad->func_call = FUNC_CDECL;
2665             break;
2666         case TOK_STDCALL1:
2667         case TOK_STDCALL2:
2668         case TOK_STDCALL3:
2669             ad->func_call = FUNC_STDCALL;
2670             break;
2671 #ifdef TCC_TARGET_I386
2672         case TOK_REGPARM1:
2673         case TOK_REGPARM2:
2674             skip('(');
2675             n = expr_const();
2676             if (n > 3) 
2677                 n = 3;
2678             else if (n < 0)
2679                 n = 0;
2680             if (n > 0)
2681                 ad->func_call = FUNC_FASTCALL1 + n - 1;
2682             skip(')');
2683             break;
2684         case TOK_FASTCALL1:
2685         case TOK_FASTCALL2:
2686         case TOK_FASTCALL3:
2687             ad->func_call = FUNC_FASTCALLW;
2688             break;            
2689 #endif
2690         case TOK_MODE:
2691             skip('(');
2692             switch(tok) {
2693                 case TOK_MODE_DI:
2694                     ad->mode = VT_LLONG + 1;
2695                     break;
2696                 case TOK_MODE_HI:
2697                     ad->mode = VT_SHORT + 1;
2698                     break;
2699                 case TOK_MODE_SI:
2700                     ad->mode = VT_INT + 1;
2701                     break;
2702                 default:
2703                     tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2704                     break;
2705             }
2706             next();
2707             skip(')');
2708             break;
2709         case TOK_DLLEXPORT:
2710             ad->func_export = 1;
2711             break;
2712         case TOK_DLLIMPORT:
2713             ad->func_import = 1;
2714             break;
2715         default:
2716             if (tcc_state->warn_unsupported)
2717                 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
2718             /* skip parameters */
2719             if (tok == '(') {
2720                 int parenthesis = 0;
2721                 do {
2722                     if (tok == '(') 
2723                         parenthesis++;
2724                     else if (tok == ')') 
2725                         parenthesis--;
2726                     next();
2727                 } while (parenthesis && tok != -1);
2728             }
2729             break;
2730         }
2731         if (tok != ',')
2732             break;
2733         next();
2734     }
2735     skip(')');
2736     skip(')');
2737     }
2738 }
2739
2740 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2741 static void struct_decl(CType *type, int u)
2742 {
2743     int a, v, size, align, maxalign, c, offset;
2744     int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2745     Sym *s, *ss, *ass, **ps;
2746     AttributeDef ad;
2747     CType type1, btype;
2748
2749     a = tok; /* save decl type */
2750     next();
2751     if (tok != '{') {
2752         v = tok;
2753         next();
2754         /* struct already defined ? return it */
2755         if (v < TOK_IDENT)
2756             expect("struct/union/enum name");
2757         s = struct_find(v);
2758         if (s) {
2759             if (s->type.t != a)
2760                 tcc_error("invalid type");
2761             goto do_decl;
2762         }
2763     } else {
2764         v = anon_sym++;
2765     }
2766     type1.t = a;
2767     /* we put an undefined size for struct/union */
2768     s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2769     s->r = 0; /* default alignment is zero as gcc */
2770     /* put struct/union/enum name in type */
2771  do_decl:
2772     type->t = u;
2773     type->ref = s;
2774     
2775     if (tok == '{') {
2776         next();
2777         if (s->c != -1)
2778             tcc_error("struct/union/enum already defined");
2779         /* cannot be empty */
2780         c = 0;
2781         /* non empty enums are not allowed */
2782         if (a == TOK_ENUM) {
2783             for(;;) {
2784                 v = tok;
2785                 if (v < TOK_UIDENT)
2786                     expect("identifier");
2787                 next();
2788                 if (tok == '=') {
2789                     next();
2790                     c = expr_const();
2791                 }
2792                 /* enum symbols have static storage */
2793                 ss = sym_push(v, &int_type, VT_CONST, c);
2794                 ss->type.t |= VT_STATIC;
2795                 if (tok != ',')
2796                     break;
2797                 next();
2798                 c++;
2799                 /* NOTE: we accept a trailing comma */
2800                 if (tok == '}')
2801                     break;
2802             }
2803             skip('}');
2804         } else {
2805             maxalign = 1;
2806             ps = &s->next;
2807             prevbt = VT_INT;
2808             bit_pos = 0;
2809             offset = 0;
2810             while (tok != '}') {
2811                 parse_btype(&btype, &ad);
2812                 while (1) {
2813                     bit_size = -1;
2814                     v = 0;
2815                     type1 = btype;
2816                     if (tok != ':') {
2817                         type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2818                         if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2819                             expect("identifier");
2820                         if ((type1.t & VT_BTYPE) == VT_FUNC ||
2821                             (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2822                             tcc_error("invalid type for '%s'", 
2823                                   get_tok_str(v, NULL));
2824                     }
2825                     if (tok == ':') {
2826                         next();
2827                         bit_size = expr_const();
2828                         /* XXX: handle v = 0 case for messages */
2829                         if (bit_size < 0)
2830                             tcc_error("negative width in bit-field '%s'", 
2831                                   get_tok_str(v, NULL));
2832                         if (v && bit_size == 0)
2833                             tcc_error("zero width for bit-field '%s'", 
2834                                   get_tok_str(v, NULL));
2835                     }
2836                     size = type_size(&type1, &align);
2837                     if (ad.aligned) {
2838                         if (align < ad.aligned)
2839                             align = ad.aligned;
2840                     } else if (ad.packed) {
2841                         align = 1;
2842                     } else if (*tcc_state->pack_stack_ptr) {
2843                         if (align > *tcc_state->pack_stack_ptr)
2844                             align = *tcc_state->pack_stack_ptr;
2845                     }
2846                     lbit_pos = 0;
2847                     if (bit_size >= 0) {
2848                         bt = type1.t & VT_BTYPE;
2849                         if (bt != VT_INT && 
2850                             bt != VT_BYTE && 
2851                             bt != VT_SHORT &&
2852                             bt != VT_BOOL &&
2853                             bt != VT_ENUM &&
2854                             bt != VT_LLONG)
2855                             tcc_error("bitfields must have scalar type");
2856                         bsize = size * 8;
2857                         if (bit_size > bsize) {
2858                             tcc_error("width of '%s' exceeds its type",
2859                                   get_tok_str(v, NULL));
2860                         } else if (bit_size == bsize) {
2861                             /* no need for bit fields */
2862                             bit_pos = 0;
2863                         } else if (bit_size == 0) {
2864                             /* XXX: what to do if only padding in a
2865                                structure ? */
2866                             /* zero size: means to pad */
2867                             bit_pos = 0;
2868                         } else {
2869                             /* we do not have enough room ?
2870                                did the type change?
2871                                is it a union? */
2872                             if ((bit_pos + bit_size) > bsize ||
2873                                 bt != prevbt || a == TOK_UNION)
2874                                 bit_pos = 0;
2875                             lbit_pos = bit_pos;
2876                             /* XXX: handle LSB first */
2877                             type1.t |= VT_BITFIELD | 
2878                                 (bit_pos << VT_STRUCT_SHIFT) |
2879                                 (bit_size << (VT_STRUCT_SHIFT + 6));
2880                             bit_pos += bit_size;
2881                         }
2882                         prevbt = bt;
2883                     } else {
2884                         bit_pos = 0;
2885                     }
2886                     if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
2887                         /* add new memory data only if starting
2888                            bit field */
2889                         if (lbit_pos == 0) {
2890                             if (a == TOK_STRUCT) {
2891                                 c = (c + align - 1) & -align;
2892                                 offset = c;
2893                                 if (size > 0)
2894                                     c += size;
2895                             } else {
2896                                 offset = 0;
2897                                 if (size > c)
2898                                     c = size;
2899                             }
2900                             if (align > maxalign)
2901                                 maxalign = align;
2902                         }
2903 #if 0
2904                         printf("add field %s offset=%d", 
2905                                get_tok_str(v, NULL), offset);
2906                         if (type1.t & VT_BITFIELD) {
2907                             printf(" pos=%d size=%d", 
2908                                    (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
2909                                    (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2910                         }
2911                         printf("\n");
2912 #endif
2913                     }
2914                     if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
2915                         ass = type1.ref;
2916                         while ((ass = ass->next) != NULL) {
2917                            ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
2918                            *ps = ss;
2919                            ps = &ss->next;
2920                         }
2921                     } else if (v) {
2922                         ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
2923                         *ps = ss;
2924                         ps = &ss->next;
2925                     }
2926                     if (tok == ';' || tok == TOK_EOF)
2927                         break;
2928                     skip(',');
2929                 }
2930                 skip(';');
2931             }
2932             skip('}');
2933             /* store size and alignment */
2934             s->c = (c + maxalign - 1) & -maxalign; 
2935             s->r = maxalign;
2936         }
2937     }
2938 }
2939
2940 /* return 0 if no type declaration. otherwise, return the basic type
2941    and skip it. 
2942  */
2943 static int parse_btype(CType *type, AttributeDef *ad)
2944 {
2945     int t, u, type_found, typespec_found, typedef_found;
2946     Sym *s;
2947     CType type1;
2948
2949     memset(ad, 0, sizeof(AttributeDef));
2950     type_found = 0;
2951     typespec_found = 0;
2952     typedef_found = 0;
2953     t = 0;
2954     while(1) {
2955         switch(tok) {
2956         case TOK_EXTENSION:
2957             /* currently, we really ignore extension */
2958             next();
2959             continue;
2960
2961             /* basic types */
2962         case TOK_CHAR:
2963             u = VT_BYTE;
2964         basic_type:
2965             next();
2966         basic_type1:
2967             if ((t & VT_BTYPE) != 0)
2968                 tcc_error("too many basic types");
2969             t |= u;
2970             typespec_found = 1;
2971             break;
2972         case TOK_VOID:
2973             u = VT_VOID;
2974             goto basic_type;
2975         case TOK_SHORT:
2976             u = VT_SHORT;
2977             goto basic_type;
2978         case TOK_INT:
2979             next();
2980             typespec_found = 1;
2981             break;
2982         case TOK_LONG:
2983             next();
2984             if ((t & VT_BTYPE) == VT_DOUBLE) {
2985 #ifndef TCC_TARGET_PE
2986                 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2987 #endif
2988             } else if ((t & VT_BTYPE) == VT_LONG) {
2989                 t = (t & ~VT_BTYPE) | VT_LLONG;
2990             } else {
2991                 u = VT_LONG;
2992                 goto basic_type1;
2993             }
2994             break;
2995         case TOK_BOOL:
2996             u = VT_BOOL;
2997             goto basic_type;
2998         case TOK_FLOAT:
2999             u = VT_FLOAT;
3000             goto basic_type;
3001         case TOK_DOUBLE:
3002             next();
3003             if ((t & VT_BTYPE) == VT_LONG) {
3004 #ifdef TCC_TARGET_PE
3005                 t = (t & ~VT_BTYPE) | VT_DOUBLE;
3006 #else
3007                 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3008 #endif
3009             } else {
3010                 u = VT_DOUBLE;
3011                 goto basic_type1;
3012             }
3013             break;
3014         case TOK_ENUM:
3015             struct_decl(&type1, VT_ENUM);
3016         basic_type2:
3017             u = type1.t;
3018             type->ref = type1.ref;
3019             goto basic_type1;
3020         case TOK_STRUCT:
3021         case TOK_UNION:
3022             struct_decl(&type1, VT_STRUCT);
3023             goto basic_type2;
3024
3025             /* type modifiers */
3026         case TOK_CONST1:
3027         case TOK_CONST2:
3028         case TOK_CONST3:
3029             t |= VT_CONSTANT;
3030             next();
3031             break;
3032         case TOK_VOLATILE1:
3033         case TOK_VOLATILE2:
3034         case TOK_VOLATILE3:
3035             t |= VT_VOLATILE;
3036             next();
3037             break;
3038         case TOK_SIGNED1:
3039         case TOK_SIGNED2:
3040         case TOK_SIGNED3:
3041             typespec_found = 1;
3042             t |= VT_SIGNED;
3043             next();
3044             break;
3045         case TOK_REGISTER:
3046         case TOK_AUTO:
3047         case TOK_RESTRICT1:
3048         case TOK_RESTRICT2:
3049         case TOK_RESTRICT3:
3050             next();
3051             break;
3052         case TOK_UNSIGNED:
3053             t |= VT_UNSIGNED;
3054             next();
3055             typespec_found = 1;
3056             break;
3057
3058             /* storage */
3059         case TOK_EXTERN:
3060             t |= VT_EXTERN;
3061             next();
3062             break;
3063         case TOK_STATIC:
3064             t |= VT_STATIC;
3065             next();
3066             break;
3067         case TOK_TYPEDEF:
3068             t |= VT_TYPEDEF;
3069             next();
3070             break;
3071         case TOK_INLINE1:
3072         case TOK_INLINE2:
3073         case TOK_INLINE3:
3074             t |= VT_INLINE;
3075             next();
3076             break;
3077
3078             /* GNUC attribute */
3079         case TOK_ATTRIBUTE1:
3080         case TOK_ATTRIBUTE2:
3081             parse_attribute(ad);
3082             if (ad->mode) {
3083                 u = ad->mode -1;
3084                 t = (t & ~VT_BTYPE) | u;
3085             }
3086             break;
3087             /* GNUC typeof */
3088         case TOK_TYPEOF1:
3089         case TOK_TYPEOF2:
3090         case TOK_TYPEOF3:
3091             next();
3092             parse_expr_type(&type1);
3093             /* remove all storage modifiers except typedef */
3094             type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
3095             goto basic_type2;
3096         default:
3097             if (typespec_found || typedef_found)
3098                 goto the_end;
3099             s = sym_find(tok);
3100             if (!s || !(s->type.t & VT_TYPEDEF))
3101                 goto the_end;
3102             typedef_found = 1;
3103             t |= (s->type.t & ~VT_TYPEDEF);
3104             type->ref = s->type.ref;
3105             if (s->r) {
3106                 /* get attributes from typedef */
3107                 if (0 == ad->aligned)
3108                     ad->aligned = FUNC_ALIGN(s->r);
3109                 if (0 == ad->func_call)
3110                     ad->func_call = FUNC_CALL(s->r);
3111                 ad->packed |= FUNC_PACKED(s->r);
3112             }
3113             next();
3114             typespec_found = 1;
3115             break;
3116         }
3117         type_found = 1;
3118     }
3119 the_end:
3120     if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
3121         tcc_error("signed and unsigned modifier");
3122     if (tcc_state->char_is_unsigned) {
3123         if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
3124             t |= VT_UNSIGNED;
3125     }
3126     t &= ~VT_SIGNED;
3127
3128     /* long is never used as type */
3129     if ((t & VT_BTYPE) == VT_LONG)
3130 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
3131         t = (t & ~VT_BTYPE) | VT_INT;
3132 #else
3133         t = (t & ~VT_BTYPE) | VT_LLONG;
3134 #endif
3135     type->t = t;
3136     return type_found;
3137 }
3138
3139 /* convert a function parameter type (array to pointer and function to
3140    function pointer) */
3141 static inline void convert_parameter_type(CType *pt)
3142 {
3143     /* remove const and volatile qualifiers (XXX: const could be used
3144        to indicate a const function parameter */
3145     pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3146     /* array must be transformed to pointer according to ANSI C */
3147     pt->t &= ~VT_ARRAY;
3148     if ((pt->t & VT_BTYPE) == VT_FUNC) {
3149         mk_pointer(pt);
3150     }
3151 }
3152
3153 ST_FUNC void parse_asm_str(CString *astr)
3154 {
3155     skip('(');
3156     /* read the string */
3157     if (tok != TOK_STR)
3158         expect("string constant");
3159     cstr_new(astr);
3160     while (tok == TOK_STR) {
3161         /* XXX: add \0 handling too ? */
3162         cstr_cat(astr, tokc.cstr->data);
3163         next();
3164     }
3165     cstr_ccat(astr, '\0');
3166 }
3167
3168 /* Parse an asm label and return the label
3169  * Don't forget to free the CString in the caller! */
3170 static void asm_label_instr(CString *astr)
3171 {
3172     next();
3173     parse_asm_str(astr);
3174     skip(')');
3175 #ifdef ASM_DEBUG
3176     printf("asm_alias: \"%s\"\n", (char *)astr->data);
3177 #endif
3178 }
3179
3180 static void post_type(CType *type, AttributeDef *ad)
3181 {
3182     int n, l, t1, arg_size, align;
3183     Sym **plast, *s, *first;
3184     AttributeDef ad1;
3185     CType pt;
3186
3187     if (tok == '(') {
3188         /* function declaration */
3189         next();
3190         l = 0;
3191         first = NULL;
3192         plast = &first;
3193         arg_size = 0;
3194         if (tok != ')') {
3195             for(;;) {
3196                 /* read param name and compute offset */
3197                 if (l != FUNC_OLD) {
3198                     if (!parse_btype(&pt, &ad1)) {
3199                         if (l) {
3200                             tcc_error("invalid type");
3201                         } else {
3202                             l = FUNC_OLD;
3203                             goto old_proto;
3204                         }
3205                     }
3206                     l = FUNC_NEW;
3207                     if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3208                         break;
3209                     type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3210                     if ((pt.t & VT_BTYPE) == VT_VOID)
3211                         tcc_error("parameter declared as void");
3212                     arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3213                 } else {
3214                 old_proto:
3215                     n = tok;
3216                     if (n < TOK_UIDENT)
3217                         expect("identifier");
3218                     pt.t = VT_INT;
3219                     next();
3220                 }
3221                 convert_parameter_type(&pt);
3222                 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3223                 *plast = s;
3224                 plast = &s->next;
3225                 if (tok == ')')
3226                     break;
3227                 skip(',');
3228                 if (l == FUNC_NEW && tok == TOK_DOTS) {
3229                     l = FUNC_ELLIPSIS;
3230                     next();
3231                     break;
3232                 }
3233             }
3234         }
3235         /* if no parameters, then old type prototype */
3236         if (l == 0)
3237             l = FUNC_OLD;
3238         skip(')');
3239         /* NOTE: const is ignored in returned type as it has a special
3240            meaning in gcc / C++ */
3241         type->t &= ~VT_CONSTANT; 
3242         /* some ancient pre-K&R C allows a function to return an array
3243            and the array brackets to be put after the arguments, such 
3244            that "int c()[]" means something like "int[] c()" */
3245         if (tok == '[') {
3246             next();
3247             skip(']'); /* only handle simple "[]" */
3248             type->t |= VT_PTR;
3249         }
3250         /* we push a anonymous symbol which will contain the function prototype */
3251         ad->func_args = arg_size;
3252         s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
3253         s->next = first;
3254         type->t = VT_FUNC;
3255         type->ref = s;
3256     } else if (tok == '[') {
3257         /* array definition */
3258         next();
3259         if (tok == TOK_RESTRICT1)
3260             next();
3261         n = -1;
3262         t1 = 0;
3263         if (tok != ']') {
3264             if (!local_stack || nocode_wanted)
3265                  vpushi(expr_const());
3266             else gexpr();
3267             if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3268                 n = vtop->c.i;
3269                 if (n < 0)
3270                     tcc_error("invalid array size");
3271             } else {
3272                 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3273                     tcc_error("size of variable length array should be an integer");
3274                 t1 = VT_VLA;
3275             }
3276         }
3277         skip(']');
3278         /* parse next post type */
3279         post_type(type, ad);
3280         t1 |= type->t & VT_VLA;
3281         
3282         if (t1 & VT_VLA) {
3283             loc -= type_size(&int_type, &align);
3284             loc &= -align;
3285             n = loc;
3286
3287             vla_runtime_type_size(type, &align);
3288             gen_op('*');
3289             vset(&int_type, VT_LOCAL|VT_LVAL, loc);
3290             vswap();
3291             vstore();
3292         }
3293         if (n != -1)
3294             vpop();
3295                 
3296         /* we push an anonymous symbol which will contain the array
3297            element type */
3298         s = sym_push(SYM_FIELD, type, 0, n);
3299         type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3300         type->ref = s;
3301     }
3302 }
3303
3304 /* Parse a type declaration (except basic type), and return the type
3305    in 'type'. 'td' is a bitmask indicating which kind of type decl is
3306    expected. 'type' should contain the basic type. 'ad' is the
3307    attribute definition of the basic type. It can be modified by
3308    type_decl(). 
3309  */
3310 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3311 {
3312     Sym *s;
3313     CType type1, *type2;
3314     int qualifiers, storage;
3315
3316     while (tok == '*') {
3317         qualifiers = 0;
3318     redo:
3319         next();
3320         switch(tok) {
3321         case TOK_CONST1:
3322         case TOK_CONST2:
3323         case TOK_CONST3:
3324             qualifiers |= VT_CONSTANT;
3325             goto redo;
3326         case TOK_VOLATILE1:
3327         case TOK_VOLATILE2:
3328         case TOK_VOLATILE3:
3329             qualifiers |= VT_VOLATILE;
3330             goto redo;
3331         case TOK_RESTRICT1:
3332         case TOK_RESTRICT2:
3333         case TOK_RESTRICT3:
3334             goto redo;
3335         }
3336         mk_pointer(type);
3337         type->t |= qualifiers;
3338     }
3339     
3340     /* XXX: clarify attribute handling */
3341     if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3342         parse_attribute(ad);
3343
3344     /* recursive type */
3345     /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3346     type1.t = 0; /* XXX: same as int */
3347     if (tok == '(') {
3348         next();
3349         /* XXX: this is not correct to modify 'ad' at this point, but
3350            the syntax is not clear */
3351         if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3352             parse_attribute(ad);
3353         type_decl(&type1, ad, v, td);
3354         skip(')');
3355     } else {
3356         /* type identifier */
3357         if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3358             *v = tok;
3359             next();
3360         } else {
3361             if (!(td & TYPE_ABSTRACT))
3362                 expect("identifier");
3363             *v = 0;
3364         }
3365     }
3366     storage = type->t & VT_STORAGE;
3367     type->t &= ~VT_STORAGE;
3368     if (storage & VT_STATIC) {
3369         int saved_nocode_wanted = nocode_wanted;
3370         nocode_wanted = 1;
3371         post_type(type, ad);
3372         nocode_wanted = saved_nocode_wanted;
3373     } else
3374         post_type(type, ad);
3375     type->t |= storage;
3376     if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3377         parse_attribute(ad);
3378     
3379     if (!type1.t)
3380         return;
3381     /* append type at the end of type1 */
3382     type2 = &type1;
3383     for(;;) {
3384         s = type2->ref;
3385         type2 = &s->type;
3386         if (!type2->t) {
3387             *type2 = *type;
3388             break;
3389         }
3390     }
3391     *type = type1;
3392 }
3393
3394 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3395 ST_FUNC int lvalue_type(int t)
3396 {
3397     int bt, r;
3398     r = VT_LVAL;
3399     bt = t & VT_BTYPE;
3400     if (bt == VT_BYTE || bt == VT_BOOL)
3401         r |= VT_LVAL_BYTE;
3402     else if (bt == VT_SHORT)
3403         r |= VT_LVAL_SHORT;
3404     else
3405         return r;
3406     if (t & VT_UNSIGNED)
3407         r |= VT_LVAL_UNSIGNED;
3408     return r;
3409 }
3410
3411 /* indirection with full error checking and bound check */
3412 ST_FUNC void indir(void)
3413 {
3414     if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3415         if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3416             return;
3417         expect("pointer");
3418     }
3419     if ((vtop->r & VT_LVAL) && !nocode_wanted)
3420         gv(RC_INT);
3421     vtop->type = *pointed_type(&vtop->type);
3422     /* Arrays and functions are never lvalues */
3423     if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3424         && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3425         vtop->r |= lvalue_type(vtop->type.t);
3426         /* if bound checking, the referenced pointer must be checked */
3427 #ifdef CONFIG_TCC_BCHECK
3428         if (tcc_state->do_bounds_check)
3429             vtop->r |= VT_MUSTBOUND;
3430 #endif
3431     }
3432 }
3433
3434 /* pass a parameter to a function and do type checking and casting */
3435 static void gfunc_param_typed(Sym *func, Sym *arg)
3436 {
3437     int func_type;
3438     CType type;
3439
3440     func_type = func->c;
3441     if (func_type == FUNC_OLD ||
3442         (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3443         /* default casting : only need to convert float to double */
3444         if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3445             type.t = VT_DOUBLE;
3446             gen_cast(&type);
3447         }
3448     } else if (arg == NULL) {
3449         tcc_error("too many arguments to function");
3450     } else {
3451         type = arg->type;
3452         type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3453         gen_assign_cast(&type);
3454     }
3455 }
3456
3457 /* parse an expression of the form '(type)' or '(expr)' and return its
3458    type */
3459 static void parse_expr_type(CType *type)
3460 {
3461     int n;
3462     AttributeDef ad;
3463
3464     skip('(');
3465     if (parse_btype(type, &ad)) {
3466         type_decl(type, &ad, &n, TYPE_ABSTRACT);
3467     } else {
3468         expr_type(type);
3469     }
3470     skip(')');
3471 }
3472
3473 static void parse_type(CType *type)
3474 {
3475     AttributeDef ad;
3476     int n;
3477
3478     if (!parse_btype(type, &ad)) {
3479         expect("type");
3480     }
3481     type_decl(type, &ad, &n, TYPE_ABSTRACT);
3482 }
3483
3484 static void vpush_tokc(int t)
3485 {
3486     CType type;
3487     type.t = t;
3488     type.ref = 0;
3489     vsetc(&type, VT_CONST, &tokc);
3490 }
3491
3492 ST_FUNC void unary(void)
3493 {
3494     int n, t, align, size, r, sizeof_caller;
3495     CType type;
3496     Sym *s;
3497     AttributeDef ad;
3498     static int in_sizeof = 0;
3499
3500     sizeof_caller = in_sizeof;
3501     in_sizeof = 0;
3502     /* XXX: GCC 2.95.3 does not generate a table although it should be
3503        better here */
3504  tok_next:
3505     switch(tok) {
3506     case TOK_EXTENSION:
3507         next();
3508         goto tok_next;
3509     case TOK_CINT:
3510     case TOK_CCHAR: 
3511     case TOK_LCHAR:
3512         vpushi(tokc.i);
3513         next();
3514         break;
3515     case TOK_CUINT:
3516         vpush_tokc(VT_INT | VT_UNSIGNED);
3517         next();
3518         break;
3519     case TOK_CLLONG:
3520         vpush_tokc(VT_LLONG);
3521         next();
3522         break;
3523     case TOK_CULLONG:
3524         vpush_tokc(VT_LLONG | VT_UNSIGNED);
3525         next();
3526         break;
3527     case TOK_CFLOAT:
3528         vpush_tokc(VT_FLOAT);
3529         next();
3530         break;
3531     case TOK_CDOUBLE:
3532         vpush_tokc(VT_DOUBLE);
3533         next();
3534         break;
3535     case TOK_CLDOUBLE:
3536         vpush_tokc(VT_LDOUBLE);
3537         next();
3538         break;
3539     case TOK___FUNCTION__:
3540         if (!gnu_ext)
3541             goto tok_identifier;
3542         /* fall thru */
3543     case TOK___FUNC__:
3544         {
3545             void *ptr;
3546             int len;
3547             /* special function name identifier */
3548             len = strlen(funcname) + 1;
3549             /* generate char[len] type */
3550             type.t = VT_BYTE;
3551             mk_pointer(&type);
3552             type.t |= VT_ARRAY;
3553             type.ref->c = len;
3554             vpush_ref(&type, data_section, data_section->data_offset, len);
3555             ptr = section_ptr_add(data_section, len);
3556             memcpy(ptr, funcname, len);
3557             next();
3558         }
3559         break;
3560     case TOK_LSTR:
3561 #ifdef TCC_TARGET_PE
3562         t = VT_SHORT | VT_UNSIGNED;
3563 #else
3564         t = VT_INT;
3565 #endif
3566         goto str_init;
3567     case TOK_STR:
3568         /* string parsing */
3569         t = VT_BYTE;
3570     str_init:
3571         if (tcc_state->warn_write_strings)
3572             t |= VT_CONSTANT;
3573         type.t = t;
3574         mk_pointer(&type);
3575         type.t |= VT_ARRAY;
3576         memset(&ad, 0, sizeof(AttributeDef));
3577         decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
3578         break;
3579     case '(':
3580         next();
3581         /* cast ? */
3582         if (parse_btype(&type, &ad)) {
3583             type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3584             skip(')');
3585             /* check ISOC99 compound literal */
3586             if (tok == '{') {
3587                     /* data is allocated locally by default */
3588                 if (global_expr)
3589                     r = VT_CONST;
3590                 else
3591                     r = VT_LOCAL;
3592                 /* all except arrays are lvalues */
3593                 if (!(type.t & VT_ARRAY))
3594                     r |= lvalue_type(type.t);
3595                 memset(&ad, 0, sizeof(AttributeDef));
3596                 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
3597             } else {
3598                 if (sizeof_caller) {
3599                     vpush(&type);
3600                     return;
3601                 }
3602                 unary();
3603                 gen_cast(&type);
3604             }
3605         } else if (tok == '{') {
3606             /* save all registers */
3607             save_regs(0); 
3608             /* statement expression : we do not accept break/continue
3609                inside as GCC does */
3610             block(NULL, NULL, NULL, NULL, 0, 1);
3611             skip(')');
3612         } else {
3613             gexpr();
3614             skip(')');
3615         }
3616         break;
3617     case '*':
3618         next();
3619         unary();
3620         indir();
3621         break;
3622     case '&':
3623         next();
3624         unary();
3625         /* functions names must be treated as function pointers,
3626            except for unary '&' and sizeof. Since we consider that
3627            functions are not lvalues, we only have to handle it
3628            there and in function calls. */
3629         /* arrays can also be used although they are not lvalues */
3630         if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3631             !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3632             test_lvalue();
3633         mk_pointer(&vtop->type);
3634         gaddrof();
3635         break;
3636     case '!':
3637         next();
3638         unary();
3639         if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3640             CType boolean;
3641             boolean.t = VT_BOOL;
3642             gen_cast(&boolean);
3643             vtop->c.i = !vtop->c.i;
3644         } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3645             vtop->c.i = vtop->c.i ^ 1;
3646         else {
3647             save_regs(1);
3648             vseti(VT_JMP, gtst(1, 0));
3649         }
3650         break;
3651     case '~':
3652         next();
3653         unary();
3654         vpushi(-1);
3655         gen_op('^');
3656         break;
3657     case '+':
3658         next();
3659         /* in order to force cast, we add zero */
3660         unary();
3661         if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3662             tcc_error("pointer not accepted for unary plus");
3663         vpushi(0);
3664         gen_op('+');
3665         break;
3666     case TOK_SIZEOF:
3667     case TOK_ALIGNOF1:
3668     case TOK_ALIGNOF2:
3669         t = tok;
3670         next();
3671         in_sizeof++;
3672         unary_type(&type); // Perform a in_sizeof = 0;
3673         size = type_size(&type, &align);
3674         if (t == TOK_SIZEOF) {
3675             if (!(type.t & VT_VLA)) {
3676                 if (size < 0)
3677                     tcc_error("sizeof applied to an incomplete type");
3678                 vpushs(size);
3679             } else {
3680                 vla_runtime_type_size(&type, &align);
3681             }
3682         } else {
3683             vpushs(align);
3684         }
3685         vtop->type.t |= VT_UNSIGNED;
3686         break;
3687
3688     case TOK_builtin_types_compatible_p:
3689         {
3690             CType type1, type2;
3691             next();
3692             skip('(');
3693             parse_type(&type1);
3694             skip(',');
3695             parse_type(&type2);
3696             skip(')');
3697             type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3698             type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3699             vpushi(is_compatible_types(&type1, &type2));
3700         }
3701         break;
3702     case TOK_builtin_constant_p:
3703         {
3704             int saved_nocode_wanted, res;
3705             next();
3706             skip('(');
3707             saved_nocode_wanted = nocode_wanted;
3708             nocode_wanted = 1;
3709             gexpr();
3710             res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3711             vpop();
3712             nocode_wanted = saved_nocode_wanted;
3713             skip(')');
3714             vpushi(res);
3715         }
3716         break;
3717     case TOK_builtin_frame_address:
3718         {
3719             int level;
3720             CType type;
3721             next();
3722             skip('(');
3723             if (tok != TOK_CINT || tokc.i < 0) {
3724                 tcc_error("__builtin_frame_address only takes positive integers");
3725             }
3726             level = tokc.i;
3727             next();
3728             skip(')');
3729             type.t = VT_VOID;
3730             mk_pointer(&type);
3731             vset(&type, VT_LOCAL, 0);       /* local frame */
3732             while (level--) {
3733                 mk_pointer(&vtop->type);
3734                 indir();                    /* -> parent frame */
3735             }
3736         }
3737         break;
3738 #ifdef TCC_TARGET_X86_64
3739 #ifdef TCC_TARGET_PE
3740     case TOK_builtin_va_start:
3741         {
3742             next();
3743             skip('(');
3744             expr_eq();
3745             skip(',');
3746             expr_eq();
3747             skip(')');
3748             if ((vtop->r & VT_VALMASK) != VT_LOCAL)
3749                 tcc_error("__builtin_va_start expects a local variable");
3750             vtop->r &= ~(VT_LVAL | VT_REF);
3751             vtop->type = char_pointer_type;
3752             vstore();
3753         }
3754         break;
3755 #else
3756     case TOK_builtin_va_arg_types:
3757         {
3758             CType type;
3759             int bt;
3760             next();
3761             skip('(');
3762             parse_type(&type);
3763             skip(')');
3764             vpushi(classify_x86_64_va_arg(&type));
3765         }
3766         break;
3767 #endif
3768 #endif
3769     case TOK_INC:
3770     case TOK_DEC:
3771         t = tok;
3772         next();
3773         unary();
3774         inc(0, t);
3775         break;
3776     case '-':
3777         next();
3778         vpushi(0);
3779         unary();
3780         gen_op('-');
3781         break;
3782     case TOK_LAND:
3783         if (!gnu_ext)
3784             goto tok_identifier;
3785         next();
3786         /* allow to take the address of a label */
3787         if (tok < TOK_UIDENT)
3788             expect("label identifier");
3789         s = label_find(tok);
3790         if (!s) {
3791             s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3792         } else {
3793             if (s->r == LABEL_DECLARED)
3794                 s->r = LABEL_FORWARD;
3795         }
3796         if (!s->type.t) {
3797             s->type.t = VT_VOID;
3798             mk_pointer(&s->type);
3799             s->type.t |= VT_STATIC;
3800         }
3801         vset(&s->type, VT_CONST | VT_SYM, 0);
3802         vtop->sym = s;
3803         next();
3804         break;
3805     
3806     // special qnan , snan and infinity values
3807     case TOK___NAN__:
3808         vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
3809         next();
3810         break;
3811     case TOK___SNAN__:
3812         vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
3813         next();
3814         break;
3815     case TOK___INF__:
3816         vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
3817         next();
3818         break;
3819
3820     default:
3821     tok_identifier:
3822         t = tok;
3823         next();
3824         if (t < TOK_UIDENT)
3825             expect("identifier");
3826         s = sym_find(t);
3827         if (!s) {
3828             if (tok != '(')
3829                 tcc_error("'%s' undeclared", get_tok_str(t, NULL));
3830             /* for simple function calls, we tolerate undeclared
3831                external reference to int() function */
3832             if (tcc_state->warn_implicit_function_declaration)
3833                 tcc_warning("implicit declaration of function '%s'",
3834                         get_tok_str(t, NULL));
3835             s = external_global_sym(t, &func_old_type, 0); 
3836         }
3837         if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3838             (VT_STATIC | VT_INLINE | VT_FUNC)) {
3839             /* if referencing an inline function, then we generate a
3840                symbol to it if not already done. It will have the
3841                effect to generate code for it at the end of the
3842                compilation unit. Inline function as always
3843                generated in the text section. */
3844             if (!s->c)
3845                 put_extern_sym(s, text_section, 0, 0);
3846             r = VT_SYM | VT_CONST;
3847         } else {
3848             r = s->r;
3849         }
3850         vset(&s->type, r, s->c);
3851         /* if forward reference, we must point to s */
3852         if (vtop->r & VT_SYM) {
3853             vtop->sym = s;
3854             vtop->c.ul = 0;
3855         }
3856         break;
3857     }
3858     
3859     /* post operations */
3860     while (1) {
3861         if (tok == TOK_INC || tok == TOK_DEC) {
3862             inc(1, tok);
3863             next();
3864         } else if (tok == '.' || tok == TOK_ARROW) {
3865             int qualifiers;
3866             /* field */ 
3867             if (tok == TOK_ARROW) 
3868                 indir();
3869             qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3870             test_lvalue();
3871             gaddrof();
3872             next();
3873             /* expect pointer on structure */
3874             if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3875                 expect("struct or union");
3876             s = vtop->type.ref;
3877             /* find field */
3878             tok |= SYM_FIELD;
3879             while ((s = s->next) != NULL) {
3880                 if (s->v == tok)
3881                     break;
3882             }
3883             if (!s)
3884                 tcc_error("field not found: %s",  get_tok_str(tok & ~SYM_FIELD, NULL));
3885             /* add field offset to pointer */
3886             vtop->type = char_pointer_type; /* change type to 'char *' */
3887             vpushi(s->c);
3888             gen_op('+');
3889             /* change type to field type, and set to lvalue */
3890             vtop->type = s->type;
3891             vtop->type.t |= qualifiers;
3892             /* an array is never an lvalue */
3893             if (!(vtop->type.t & VT_ARRAY)) {
3894                 vtop->r |= lvalue_type(vtop->type.t);
3895 #ifdef CONFIG_TCC_BCHECK
3896                 /* if bound checking, the referenced pointer must be checked */
3897                 if (tcc_state->do_bounds_check)
3898                     vtop->r |= VT_MUSTBOUND;
3899 #endif
3900             }
3901             next();
3902         } else if (tok == '[') {
3903             next();
3904             gexpr();
3905             gen_op('+');
3906             indir();
3907             skip(']');
3908         } else if (tok == '(') {
3909             SValue ret;
3910             Sym *sa;
3911             int nb_args, sret;
3912
3913             /* function call  */
3914             if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3915                 /* pointer test (no array accepted) */
3916                 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3917                     vtop->type = *pointed_type(&vtop->type);
3918                     if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3919                         goto error_func;
3920                 } else {
3921                 error_func:
3922                     expect("function pointer");
3923                 }
3924             } else {
3925                 vtop->r &= ~VT_LVAL; /* no lvalue */
3926             }
3927             /* get return type */
3928             s = vtop->type.ref;
3929             next();
3930             sa = s->next; /* first parameter */
3931             nb_args = 0;
3932             ret.r2 = VT_CONST;
3933             /* compute first implicit argument if a structure is returned */
3934             if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3935                 int ret_align;
3936                 sret = gfunc_sret(&s->type, &ret.type, &ret_align);
3937                 if (sret) {
3938                     /* get some space for the returned structure */
3939                     size = type_size(&s->type, &align);
3940                     loc = (loc - size) & -align;
3941                     ret.type = s->type;
3942                     ret.r = VT_LOCAL | VT_LVAL;
3943                     /* pass it as 'int' to avoid structure arg passing
3944                        problems */
3945                     vseti(VT_LOCAL, loc);
3946                     ret.c = vtop->c;
3947                     nb_args++;
3948                 }
3949             } else {
3950                 sret = 0;
3951                 ret.type = s->type;
3952             }
3953
3954             if (!sret) {
3955                 /* return in register */
3956                 if (is_float(ret.type.t)) {
3957                     ret.r = reg_fret(ret.type.t);
3958 #ifdef TCC_TARGET_X86_64
3959                     if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
3960                       ret.r2 = REG_QRET;
3961 #endif
3962                 } else {
3963 #ifdef TCC_TARGET_X86_64
3964                     if ((ret.type.t & VT_BTYPE) == VT_QLONG)
3965 #else
3966                     if ((ret.type.t & VT_BTYPE) == VT_LLONG)
3967 #endif
3968                         ret.r2 = REG_LRET;
3969                     ret.r = REG_IRET;
3970                 }
3971                 ret.c.i = 0;
3972             }
3973             if (tok != ')') {
3974                 for(;;) {
3975                     expr_eq();
3976                     gfunc_param_typed(s, sa);
3977                     nb_args++;
3978                     if (sa)
3979                         sa = sa->next;
3980                     if (tok == ')')
3981                         break;
3982                     skip(',');
3983                 }
3984             }
3985             if (sa)
3986                 tcc_error("too few arguments to function");
3987             skip(')');
3988             if (!nocode_wanted) {
3989                 gfunc_call(nb_args);
3990             } else {
3991                 vtop -= (nb_args + 1);
3992             }
3993             /* return value */
3994             vsetc(&ret.type, ret.r, &ret.c);
3995             vtop->r2 = ret.r2;
3996             /* handle packed struct return */
3997             if (((s->type.t & VT_BTYPE) == VT_STRUCT) && !sret) {
3998                 int addr;
3999                 size = type_size(&s->type, &align);
4000                 loc = (loc - size) & -align;
4001                 addr = loc;
4002                 vset(&ret.type, VT_LOCAL | VT_LVAL, addr);
4003                 vswap();
4004                 vstore();
4005                 vtop--;
4006                 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
4007             }
4008         } else {
4009             break;
4010         }
4011     }
4012 }
4013
4014 ST_FUNC void expr_prod(void)
4015 {
4016     int t;
4017
4018     unary();
4019     while (tok == '*' || tok == '/' || tok == '%') {
4020         t = tok;
4021         next();
4022         unary();
4023         gen_op(t);
4024     }
4025 }
4026
4027 ST_FUNC void expr_sum(void)
4028 {
4029     int t;
4030
4031     expr_prod();
4032     while (tok == '+' || tok == '-') {
4033         t = tok;
4034         next();
4035         expr_prod();
4036         gen_op(t);
4037     }
4038 }
4039
4040 static void expr_shift(void)
4041 {
4042     int t;
4043
4044     expr_sum();
4045     while (tok == TOK_SHL || tok == TOK_SAR) {
4046         t = tok;
4047         next();
4048         expr_sum();
4049         gen_op(t);
4050     }
4051 }
4052
4053 static void expr_cmp(void)
4054 {
4055     int t;
4056
4057     expr_shift();
4058     while ((tok >= TOK_ULE && tok <= TOK_GT) ||
4059            tok == TOK_ULT || tok == TOK_UGE) {
4060         t = tok;
4061         next();
4062         expr_shift();
4063         gen_op(t);
4064     }
4065 }
4066
4067 static void expr_cmpeq(void)
4068 {
4069     int t;
4070
4071     expr_cmp();
4072     while (tok == TOK_EQ || tok == TOK_NE) {
4073         t = tok;
4074         next();
4075         expr_cmp();
4076         gen_op(t);
4077     }
4078 }
4079
4080 static void expr_and(void)
4081 {
4082     expr_cmpeq();
4083     while (tok == '&') {
4084         next();
4085         expr_cmpeq();
4086         gen_op('&');
4087     }
4088 }
4089
4090 static void expr_xor(void)
4091 {
4092     expr_and();
4093     while (tok == '^') {
4094         next();
4095         expr_and();
4096         gen_op('^');
4097     }
4098 }
4099
4100 static void expr_or(void)
4101 {
4102     expr_xor();
4103     while (tok == '|') {
4104         next();
4105         expr_xor();
4106         gen_op('|');
4107     }
4108 }
4109
4110 /* XXX: fix this mess */
4111 static void expr_land_const(void)
4112 {
4113     expr_or();
4114     while (tok == TOK_LAND) {
4115         next();
4116         expr_or();
4117         gen_op(TOK_LAND);
4118     }
4119 }
4120
4121 /* XXX: fix this mess */
4122 static void expr_lor_const(void)
4123 {
4124     expr_land_const();
4125     while (tok == TOK_LOR) {
4126         next();
4127         expr_land_const();
4128         gen_op(TOK_LOR);
4129     }
4130 }
4131
4132 /* only used if non constant */
4133 static void expr_land(void)
4134 {
4135     int t;
4136
4137     expr_or();
4138     if (tok == TOK_LAND) {
4139         t = 0;
4140         save_regs(1);
4141         for(;;) {
4142             t = gtst(1, t);
4143             if (tok != TOK_LAND) {
4144                 vseti(VT_JMPI, t);
4145                 break;
4146             }
4147             next();
4148             expr_or();
4149         }
4150     }
4151 }
4152
4153 static void expr_lor(void)
4154 {
4155     int t;
4156
4157     expr_land();
4158     if (tok == TOK_LOR) {
4159         t = 0;
4160         save_regs(1);
4161         for(;;) {
4162             t = gtst(0, t);
4163             if (tok != TOK_LOR) {
4164                 vseti(VT_JMP, t);
4165                 break;
4166             }
4167             next();
4168             expr_land();
4169         }
4170     }
4171 }
4172
4173 /* XXX: better constant handling */
4174 static void expr_cond(void)
4175 {
4176     int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
4177     SValue sv;
4178     CType type, type1, type2;
4179
4180     if (const_wanted) {
4181         expr_lor_const();
4182         if (tok == '?') {
4183             CType boolean;
4184             int c;
4185             boolean.t = VT_BOOL;
4186             vdup();
4187             gen_cast(&boolean);
4188             c = vtop->c.i;
4189             vpop();
4190             next();
4191             if (tok != ':' || !gnu_ext) {
4192                 vpop();
4193                 gexpr();
4194             }
4195             if (!c)
4196                 vpop();
4197             skip(':');
4198             expr_cond();
4199             if (c)
4200                 vpop();
4201         }
4202     } else {
4203         expr_lor();
4204         if (tok == '?') {
4205             next();
4206             if (vtop != vstack) {
4207                 /* needed to avoid having different registers saved in
4208                    each branch */
4209                 if (is_float(vtop->type.t)) {
4210                     rc = RC_FLOAT;
4211 #ifdef TCC_TARGET_X86_64
4212                     if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4213                         rc = RC_ST0;
4214                     }
4215 #endif
4216                 }
4217                 else
4218                     rc = RC_INT;
4219                     gv(rc);
4220                     save_regs(1);
4221             }
4222             if (tok == ':' && gnu_ext) {
4223                 gv_dup();
4224                 tt = gtst(1, 0);
4225             } else {
4226                 tt = gtst(1, 0);
4227                 gexpr();
4228             }
4229             type1 = vtop->type;
4230             sv = *vtop; /* save value to handle it later */
4231             vtop--; /* no vpop so that FP stack is not flushed */
4232             skip(':');
4233             u = gjmp(0);
4234             gsym(tt);
4235             expr_cond();
4236             type2 = vtop->type;
4237
4238             t1 = type1.t;
4239             bt1 = t1 & VT_BTYPE;
4240             t2 = type2.t;
4241             bt2 = t2 & VT_BTYPE;
4242             /* cast operands to correct type according to ISOC rules */
4243             if (is_float(bt1) || is_float(bt2)) {
4244                 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4245                     type.t = VT_LDOUBLE;
4246                 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4247                     type.t = VT_DOUBLE;
4248                 } else {
4249                     type.t = VT_FLOAT;
4250                 }
4251             } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4252                 /* cast to biggest op */
4253                 type.t = VT_LLONG;
4254                 /* convert to unsigned if it does not fit in a long long */
4255                 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4256                     (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4257                     type.t |= VT_UNSIGNED;
4258             } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4259                 /* If one is a null ptr constant the result type
4260                    is the other.  */
4261                 if (is_null_pointer (vtop))
4262                   type = type1;
4263                 else if (is_null_pointer (&sv))
4264                   type = type2;
4265                 /* XXX: test pointer compatibility, C99 has more elaborate
4266                    rules here.  */
4267                 else
4268                   type = type1;
4269             } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4270                 /* XXX: test function pointer compatibility */
4271                 type = bt1 == VT_FUNC ? type1 : type2;
4272             } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4273                 /* XXX: test structure compatibility */
4274                 type = bt1 == VT_STRUCT ? type1 : type2;
4275             } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4276                 /* NOTE: as an extension, we accept void on only one side */
4277                 type.t = VT_VOID;
4278             } else {
4279                 /* integer operations */
4280                 type.t = VT_INT;
4281                 /* convert to unsigned if it does not fit in an integer */
4282                 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4283                     (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4284                     type.t |= VT_UNSIGNED;
4285             }
4286                 
4287             /* now we convert second operand */
4288             gen_cast(&type);
4289             if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4290                 gaddrof();
4291             rc = RC_INT;
4292             if (is_float(type.t)) {
4293                 rc = RC_FLOAT;
4294 #ifdef TCC_TARGET_X86_64
4295                 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4296                     rc = RC_ST0;
4297                 }
4298 #endif
4299             } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4300                 /* for long longs, we use fixed registers to avoid having
4301                    to handle a complicated move */
4302                 rc = RC_IRET; 
4303             }
4304             
4305             r2 = gv(rc);
4306             /* this is horrible, but we must also convert first
4307                operand */
4308             tt = gjmp(0);
4309             gsym(u);
4310             /* put again first value and cast it */
4311             *vtop = sv;
4312             gen_cast(&type);
4313             if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4314                 gaddrof();
4315             r1 = gv(rc);
4316             move_reg(r2, r1, type.t);
4317             vtop->r = r2;
4318             gsym(tt);
4319         }
4320     }
4321 }
4322
4323 static void expr_eq(void)
4324 {
4325     int t;
4326     
4327     expr_cond();
4328     if (tok == '=' ||
4329         (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4330         tok == TOK_A_XOR || tok == TOK_A_OR ||
4331         tok == TOK_A_SHL || tok == TOK_A_SAR) {
4332         test_lvalue();
4333         t = tok;
4334         next();
4335         if (t == '=') {
4336             expr_eq();
4337         } else {
4338             vdup();
4339             expr_eq();
4340             gen_op(t & 0x7f);
4341         }
4342         vstore();
4343     }
4344 }
4345
4346 ST_FUNC void gexpr(void)
4347 {
4348     while (1) {
4349         expr_eq();
4350         if (tok != ',')
4351             break;
4352         vpop();
4353         next();
4354     }
4355 }
4356
4357 /* parse an expression and return its type without any side effect. */
4358 static void expr_type(CType *type)
4359 {
4360     int saved_nocode_wanted;
4361
4362     saved_nocode_wanted = nocode_wanted;
4363     nocode_wanted = 1;
4364     gexpr();
4365     *type = vtop->type;
4366     vpop();
4367     nocode_wanted = saved_nocode_wanted;
4368 }
4369
4370 /* parse a unary expression and return its type without any side
4371    effect. */
4372 static void unary_type(CType *type)
4373 {
4374     int a;
4375
4376     a = nocode_wanted;
4377     nocode_wanted = 1;
4378     unary();
4379     *type = vtop->type;
4380     vpop();
4381     nocode_wanted = a;
4382 }
4383
4384 /* parse a constant expression and return value in vtop.  */
4385 static void expr_const1(void)
4386 {
4387     int a;
4388     a = const_wanted;
4389     const_wanted = 1;
4390     expr_cond();
4391     const_wanted = a;
4392 }
4393
4394 /* parse an integer constant and return its value. */
4395 ST_FUNC int expr_const(void)
4396 {
4397     int c;
4398     expr_const1();
4399     if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4400         expect("constant expression");
4401     c = vtop->c.i;
4402     vpop();
4403     return c;
4404 }
4405
4406 /* return the label token if current token is a label, otherwise
4407    return zero */
4408 static int is_label(void)
4409 {
4410     int last_tok;
4411
4412     /* fast test first */
4413     if (tok < TOK_UIDENT)
4414         return 0;
4415     /* no need to save tokc because tok is an identifier */
4416     last_tok = tok;
4417     next();
4418     if (tok == ':') {
4419         next();
4420         return last_tok;
4421     } else {
4422         unget_tok(last_tok);
4423         return 0;
4424     }
4425 }
4426
4427 static void label_or_decl(int l)
4428 {
4429     int last_tok;
4430
4431     /* fast test first */
4432     if (tok >= TOK_UIDENT)
4433       {
4434         /* no need to save tokc because tok is an identifier */
4435         last_tok = tok;
4436         next();
4437         if (tok == ':') {
4438             unget_tok(last_tok);
4439             return;
4440         }
4441         unget_tok(last_tok);
4442       }
4443     decl(l);
4444 }
4445
4446 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, 
4447                   int case_reg, int is_expr)
4448 {
4449     int a, b, c, d;
4450     Sym *s, *frame_bottom;
4451
4452     /* generate line number info */
4453     if (tcc_state->do_debug &&
4454         (last_line_num != file->line_num || last_ind != ind)) {
4455         put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4456         last_ind = ind;
4457         last_line_num = file->line_num;
4458     }
4459
4460     if (is_expr) {
4461         /* default return value is (void) */
4462         vpushi(0);
4463         vtop->type.t = VT_VOID;
4464     }
4465
4466     if (tok == TOK_IF) {
4467         /* if test */
4468         next();
4469         skip('(');
4470         gexpr();
4471         skip(')');
4472         a = gtst(1, 0);
4473         block(bsym, csym, case_sym, def_sym, case_reg, 0);
4474         c = tok;
4475         if (c == TOK_ELSE) {
4476             next();
4477             d = gjmp(0);
4478             gsym(a);
4479             block(bsym, csym, case_sym, def_sym, case_reg, 0);
4480             gsym(d); /* patch else jmp */
4481         } else
4482             gsym(a);
4483     } else if (tok == TOK_WHILE) {
4484         next();
4485         d = ind;
4486         skip('(');
4487         gexpr();
4488         skip(')');
4489         a = gtst(1, 0);
4490         b = 0;
4491         block(&a, &b, case_sym, def_sym, case_reg, 0);
4492         gjmp_addr(d);
4493         gsym(a);
4494         gsym_addr(b, d);
4495     } else if (tok == '{') {
4496         Sym *llabel;
4497         int block_vla_sp_loc, *saved_vla_sp_loc, saved_vla_flags;
4498
4499         next();
4500         /* record local declaration stack position */
4501         s = local_stack;
4502         frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4503         frame_bottom->next = scope_stack_bottom;
4504         scope_stack_bottom = frame_bottom;
4505         llabel = local_label_stack;
4506         
4507         /* save VLA state */
4508         block_vla_sp_loc = *(saved_vla_sp_loc = vla_sp_loc);
4509         if (saved_vla_sp_loc != &vla_sp_root_loc)
4510           vla_sp_loc = &block_vla_sp_loc;
4511
4512         saved_vla_flags = vla_flags;
4513         vla_flags |= VLA_NEED_NEW_FRAME;
4514         
4515         /* handle local labels declarations */
4516         if (tok == TOK_LABEL) {
4517             next();
4518             for(;;) {
4519                 if (tok < TOK_UIDENT)
4520                     expect("label identifier");
4521                 label_push(&local_label_stack, tok, LABEL_DECLARED);
4522                 next();
4523                 if (tok == ',') {
4524                     next();
4525                 } else {
4526                     skip(';');
4527                     break;
4528                 }
4529             }
4530         }
4531         while (tok != '}') {
4532             label_or_decl(VT_LOCAL);
4533             if (tok != '}') {
4534                 if (is_expr)
4535                     vpop();
4536                 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4537             }
4538         }
4539         /* pop locally defined labels */
4540         label_pop(&local_label_stack, llabel);
4541         if(is_expr) {
4542             /* XXX: this solution makes only valgrind happy...
4543                triggered by gcc.c-torture/execute/20000917-1.c */
4544             Sym *p;
4545             switch(vtop->type.t & VT_BTYPE) {
4546             case VT_PTR:
4547             case VT_STRUCT:
4548             case VT_ENUM:
4549             case VT_FUNC:
4550                 for(p=vtop->type.ref;p;p=p->prev)
4551                     if(p->prev==s)
4552                         tcc_error("unsupported expression type");
4553             }
4554         }
4555         /* pop locally defined symbols */
4556         scope_stack_bottom = scope_stack_bottom->next;
4557         sym_pop(&local_stack, s);
4558         
4559         /* Pop VLA frames and restore stack pointer if required */
4560         if (saved_vla_sp_loc != &vla_sp_root_loc)
4561             *saved_vla_sp_loc = block_vla_sp_loc;
4562         if (vla_sp_loc != (saved_vla_sp_loc == &vla_sp_root_loc ? &vla_sp_root_loc : &block_vla_sp_loc)) {
4563             vla_sp_loc = saved_vla_sp_loc;
4564             gen_vla_sp_restore(*vla_sp_loc);
4565         }
4566         vla_flags = (vla_flags & ~VLA_SCOPE_FLAGS) | (saved_vla_flags & VLA_SCOPE_FLAGS);
4567         
4568         next();
4569     } else if (tok == TOK_RETURN) {
4570         next();
4571         if (tok != ';') {
4572             gexpr();
4573             gen_assign_cast(&func_vt);
4574             if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4575                 CType type, ret_type;
4576                 int ret_align;
4577                 if (gfunc_sret(&func_vt, &ret_type, &ret_align)) {
4578                     /* if returning structure, must copy it to implicit
4579                        first pointer arg location */
4580                     type = func_vt;
4581                     mk_pointer(&type);
4582                     vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4583                     indir();
4584                     vswap();
4585                     /* copy structure value to pointer */
4586                     vstore();
4587                 } else {
4588                     /* returning structure packed into registers */
4589                     int size, addr, align;
4590                     size = type_size(&func_vt,&align);
4591                     if ((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & (ret_align-1)))
4592                         && (align & (ret_align-1))) {
4593                         loc = (loc - size) & -align;
4594                         addr = loc;
4595                         type = func_vt;
4596                         vset(&type, VT_LOCAL | VT_LVAL, addr);
4597                         vswap();
4598                         vstore();
4599                         vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
4600                     }
4601                     vtop->type = ret_type;
4602                     if (is_float(ret_type.t))
4603                         gv(rc_fret(ret_type.t));
4604                     else
4605                         gv(RC_IRET);
4606                 }
4607             } else if (is_float(func_vt.t)) {
4608                 gv(rc_fret(func_vt.t));
4609             } else {
4610                 gv(RC_IRET);
4611             }
4612             vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4613         }
4614         skip(';');
4615         rsym = gjmp(rsym); /* jmp */
4616     } else if (tok == TOK_BREAK) {
4617         /* compute jump */
4618         if (!bsym)
4619             tcc_error("cannot break");
4620         *bsym = gjmp(*bsym);
4621         next();
4622         skip(';');
4623     } else if (tok == TOK_CONTINUE) {
4624         /* compute jump */
4625         if (!csym)
4626             tcc_error("cannot continue");
4627         *csym = gjmp(*csym);
4628         next();
4629         skip(';');
4630     } else if (tok == TOK_FOR) {
4631         int e;
4632         next();
4633         skip('(');
4634         s = local_stack;
4635         frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4636         frame_bottom->next = scope_stack_bottom;
4637         scope_stack_bottom = frame_bottom;
4638         if (tok != ';') {
4639             /* c99 for-loop init decl? */
4640             if (!decl0(VT_LOCAL, 1)) {
4641                 /* no, regular for-loop init expr */
4642                 gexpr();
4643                 vpop();
4644             }
4645         }
4646         skip(';');
4647         d = ind;
4648         c = ind;
4649         a = 0;
4650         b = 0;
4651         if (tok != ';') {
4652             gexpr();
4653             a = gtst(1, 0);
4654         }
4655         skip(';');
4656         if (tok != ')') {
4657             e = gjmp(0);
4658             c = ind;
4659             gexpr();
4660             vpop();
4661             gjmp_addr(d);
4662             gsym(e);
4663         }
4664         skip(')');
4665         block(&a, &b, case_sym, def_sym, case_reg, 0);
4666         gjmp_addr(c);
4667         gsym(a);
4668         gsym_addr(b, c);
4669         scope_stack_bottom = scope_stack_bottom->next;
4670         sym_pop(&local_stack, s);
4671     } else 
4672     if (tok == TOK_DO) {
4673         next();
4674         a = 0;
4675         b = 0;
4676         d = ind;
4677         block(&a, &b, case_sym, def_sym, case_reg, 0);
4678         skip(TOK_WHILE);
4679         skip('(');
4680         gsym(b);
4681         gexpr();
4682         c = gtst(0, 0);
4683         gsym_addr(c, d);
4684         skip(')');
4685         gsym(a);
4686         skip(';');
4687     } else
4688     if (tok == TOK_SWITCH) {
4689         next();
4690         skip('(');
4691         gexpr();
4692         /* XXX: other types than integer */
4693         case_reg = gv(RC_INT);
4694         vpop();
4695         skip(')');
4696         a = 0;
4697         b = gjmp(0); /* jump to first case */
4698         c = 0;
4699         block(&a, csym, &b, &c, case_reg, 0);
4700         /* if no default, jmp after switch */
4701         if (c == 0)
4702             c = ind;
4703         /* default label */
4704         gsym_addr(b, c);
4705         /* break label */
4706         gsym(a);
4707     } else
4708     if (tok == TOK_CASE) {
4709         int v1, v2;
4710         if (!case_sym)
4711             expect("switch");
4712         next();
4713         v1 = expr_const();
4714         v2 = v1;
4715         if (gnu_ext && tok == TOK_DOTS) {
4716             next();
4717             v2 = expr_const();
4718             if (v2 < v1)
4719                 tcc_warning("empty case range");
4720         }
4721         /* since a case is like a label, we must skip it with a jmp */
4722         b = gjmp(0);
4723         gsym(*case_sym);
4724         vseti(case_reg, 0);
4725         vpushi(v1);
4726         if (v1 == v2) {
4727             gen_op(TOK_EQ);
4728             *case_sym = gtst(1, 0);
4729         } else {
4730             gen_op(TOK_GE);
4731             *case_sym = gtst(1, 0);
4732             vseti(case_reg, 0);
4733             vpushi(v2);
4734             gen_op(TOK_LE);
4735             *case_sym = gtst(1, *case_sym);
4736         }
4737         gsym(b);
4738         skip(':');
4739         is_expr = 0;
4740         goto block_after_label;
4741     } else 
4742     if (tok == TOK_DEFAULT) {
4743         next();
4744         skip(':');
4745         if (!def_sym)
4746             expect("switch");
4747         if (*def_sym)
4748             tcc_error("too many 'default'");
4749         *def_sym = ind;
4750         is_expr = 0;
4751         goto block_after_label;
4752     } else
4753     if (tok == TOK_GOTO) {
4754         next();
4755         if (tok == '*' && gnu_ext) {
4756             /* computed goto */
4757             next();
4758             gexpr();
4759             if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4760                 expect("pointer");
4761             ggoto();
4762         } else if (tok >= TOK_UIDENT) {
4763             s = label_find(tok);
4764             /* put forward definition if needed */
4765             if (!s) {
4766                 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4767             } else {
4768                 if (s->r == LABEL_DECLARED)
4769                     s->r = LABEL_FORWARD;
4770             }
4771             /* label already defined */
4772             if (vla_flags & VLA_IN_SCOPE) {
4773                 /* If VLAs are in use, save the current stack pointer and
4774                    reset the stack pointer to what it was at function entry
4775                    (label will restore stack pointer in inner scopes) */
4776                 vla_sp_save();
4777                 gen_vla_sp_restore(vla_sp_root_loc);
4778             }
4779             if (s->r & LABEL_FORWARD) 
4780                 s->jnext = gjmp(s->jnext);
4781             else
4782                 gjmp_addr(s->jnext);
4783             next();
4784         } else {
4785             expect("label identifier");
4786         }
4787         skip(';');
4788     } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4789         asm_instr();
4790     } else {
4791         b = is_label();
4792         if (b) {
4793             /* label case */
4794             if (vla_flags & VLA_IN_SCOPE) {
4795                 /* save/restore stack pointer across label
4796                    this is a no-op when combined with the load immediately
4797                    after the label unless we arrive via goto */
4798                 vla_sp_save();
4799             }
4800             s = label_find(b);
4801             if (s) {
4802                 if (s->r == LABEL_DEFINED)
4803                     tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
4804                 gsym(s->jnext);
4805                 s->r = LABEL_DEFINED;
4806             } else {
4807                 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4808             }
4809             s->jnext = ind;
4810             if (vla_flags & VLA_IN_SCOPE) {
4811                 gen_vla_sp_restore(*vla_sp_loc);
4812                 vla_flags |= VLA_NEED_NEW_FRAME;
4813             }
4814             /* we accept this, but it is a mistake */
4815         block_after_label:
4816             if (tok == '}') {
4817                 tcc_warning("deprecated use of label at end of compound statement");
4818             } else {
4819                 if (is_expr)
4820                     vpop();
4821                 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4822             }
4823         } else {
4824             /* expression case */
4825             if (tok != ';') {
4826                 if (is_expr) {
4827                     vpop();
4828                     gexpr();
4829                 } else {
4830                     gexpr();
4831                     vpop();
4832                 }
4833             }
4834             skip(';');
4835         }
4836     }
4837 }
4838
4839 /* t is the array or struct type. c is the array or struct
4840    address. cur_index/cur_field is the pointer to the current
4841    value. 'size_only' is true if only size info is needed (only used
4842    in arrays) */
4843 static void decl_designator(CType *type, Section *sec, unsigned long c, 
4844                             int *cur_index, Sym **cur_field, 
4845                             int size_only)
4846 {
4847     Sym *s, *f;
4848     int notfirst, index, index_last, align, l, nb_elems, elem_size;
4849     CType type1;
4850
4851     notfirst = 0;
4852     elem_size = 0;
4853     nb_elems = 1;
4854     if (gnu_ext && (l = is_label()) != 0)
4855         goto struct_field;
4856     while (tok == '[' || tok == '.') {
4857         if (tok == '[') {
4858             if (!(type->t & VT_ARRAY))
4859                 expect("array type");
4860             s = type->ref;
4861             next();
4862             index = expr_const();
4863             if (index < 0 || (s->c >= 0 && index >= s->c))
4864                 expect("invalid index");
4865             if (tok == TOK_DOTS && gnu_ext) {
4866                 next();
4867                 index_last = expr_const();
4868                 if (index_last < 0 || 
4869                     (s->c >= 0 && index_last >= s->c) ||
4870                     index_last < index)
4871                     expect("invalid index");
4872             } else {
4873                 index_last = index;
4874             }
4875             skip(']');
4876             if (!notfirst)
4877                 *cur_index = index_last;
4878             type = pointed_type(type);
4879             elem_size = type_size(type, &align);
4880             c += index * elem_size;
4881             /* NOTE: we only support ranges for last designator */
4882             nb_elems = index_last - index + 1;
4883             if (nb_elems != 1) {
4884                 notfirst = 1;
4885                 break;
4886             }
4887         } else {
4888             next();
4889             l = tok;
4890             next();
4891         struct_field:
4892             if ((type->t & VT_BTYPE) != VT_STRUCT)
4893                 expect("struct/union type");
4894             s = type->ref;
4895             l |= SYM_FIELD;
4896             f = s->next;
4897             while (f) {
4898                 if (f->v == l)
4899                     break;
4900                 f = f->next;
4901             }
4902             if (!f)
4903                 expect("field");
4904             if (!notfirst)
4905                 *cur_field = f;
4906             /* XXX: fix this mess by using explicit storage field */
4907             type1 = f->type;
4908             type1.t |= (type->t & ~VT_TYPE);
4909             type = &type1;
4910             c += f->c;
4911         }
4912         notfirst = 1;
4913     }
4914     if (notfirst) {
4915         if (tok == '=') {
4916             next();
4917         } else {
4918             if (!gnu_ext)
4919                 expect("=");
4920         }
4921     } else {
4922         if (type->t & VT_ARRAY) {
4923             index = *cur_index;
4924             type = pointed_type(type);
4925             c += index * type_size(type, &align);
4926         } else {
4927             f = *cur_field;
4928             if (!f)
4929                 tcc_error("too many field init");
4930             /* XXX: fix this mess by using explicit storage field */
4931             type1 = f->type;
4932             type1.t |= (type->t & ~VT_TYPE);
4933             type = &type1;
4934             c += f->c;
4935         }
4936     }
4937     decl_initializer(type, sec, c, 0, size_only);
4938
4939     /* XXX: make it more general */
4940     if (!size_only && nb_elems > 1) {
4941         unsigned long c_end;
4942         uint8_t *src, *dst;
4943         int i;
4944
4945         if (!sec)
4946             tcc_error("range init not supported yet for dynamic storage");
4947         c_end = c + nb_elems * elem_size;
4948