Fixed x86-64 long double passing.
[tinycc.git] / tccgen.c
blob0d1e21b4265ff18d0afe184c39954d8e02d76c12
1 /*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001-2004 Fabrice Bellard
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.
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.
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
21 #include "tcc.h"
23 /********************************************************/
24 /* global variables */
26 /* loc : local variable index
27 ind : output code index
28 rsym: return symbol
29 anon_sym: anonymous symbol index
31 ST_DATA int rsym, anon_sym, ind, loc;
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;
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;
58 ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop;
60 ST_DATA int const_wanted; /* true if constant wanted */
61 ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
62 ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
63 ST_DATA CType func_vt; /* current function return type (used by return instruction) */
64 ST_DATA int func_vc;
65 ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
66 ST_DATA char *funcname;
68 ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
70 /* ------------------------------------------------------------------------- */
71 static void gen_cast(CType *type);
72 static inline CType *pointed_type(CType *type);
73 static int is_compatible_types(CType *type1, CType *type2);
74 static int parse_btype(CType *type, AttributeDef *ad);
75 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
76 static void parse_expr_type(CType *type);
77 static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
78 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr);
79 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, char *asm_label, int scope);
80 static int decl0(int l, int is_for_loop_init);
81 static void expr_eq(void);
82 static void unary_type(CType *type);
83 static void vla_runtime_type_size(CType *type, int *a);
84 static int is_compatible_parameter_types(CType *type1, CType *type2);
85 static void expr_type(CType *type);
87 ST_INLN int is_float(int t)
89 int bt;
90 bt = t & VT_BTYPE;
91 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT;
94 /* we use our own 'finite' function to avoid potential problems with
95 non standard math libs */
96 /* XXX: endianness dependent */
97 ST_FUNC int ieee_finite(double d)
99 int *p = (int *)&d;
100 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
103 ST_FUNC void test_lvalue(void)
105 if (!(vtop->r & VT_LVAL))
106 expect("lvalue");
109 /* ------------------------------------------------------------------------- */
110 /* symbol allocator */
111 static Sym *__sym_malloc(void)
113 Sym *sym_pool, *sym, *last_sym;
114 int i;
116 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
117 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
119 last_sym = sym_free_first;
120 sym = sym_pool;
121 for(i = 0; i < SYM_POOL_NB; i++) {
122 sym->next = last_sym;
123 last_sym = sym;
124 sym++;
126 sym_free_first = last_sym;
127 return last_sym;
130 static inline Sym *sym_malloc(void)
132 Sym *sym;
133 sym = sym_free_first;
134 if (!sym)
135 sym = __sym_malloc();
136 sym_free_first = sym->next;
137 return sym;
140 ST_INLN void sym_free(Sym *sym)
142 sym->next = sym_free_first;
143 tcc_free(sym->asm_label);
144 sym_free_first = sym;
147 /* push, without hashing */
148 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
150 Sym *s;
151 if (ps == &local_stack) {
152 for (s = *ps; s && s != scope_stack_bottom; s = s->prev)
153 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM && s->v == v)
154 tcc_error("incompatible types for redefinition of '%s'",
155 get_tok_str(v, NULL));
157 s = *ps;
158 s = sym_malloc();
159 s->asm_label = NULL;
160 s->v = v;
161 s->type.t = t;
162 s->type.ref = NULL;
163 #ifdef _WIN64
164 s->d = NULL;
165 #endif
166 s->c = c;
167 s->next = NULL;
168 /* add in stack */
169 s->prev = *ps;
170 *ps = s;
171 return s;
174 /* find a symbol and return its associated structure. 's' is the top
175 of the symbol stack */
176 ST_FUNC Sym *sym_find2(Sym *s, int v)
178 while (s) {
179 if (s->v == v)
180 return s;
181 s = s->prev;
183 return NULL;
186 /* structure lookup */
187 ST_INLN Sym *struct_find(int v)
189 v -= TOK_IDENT;
190 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
191 return NULL;
192 return table_ident[v]->sym_struct;
195 /* find an identifier */
196 ST_INLN Sym *sym_find(int v)
198 v -= TOK_IDENT;
199 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
200 return NULL;
201 return table_ident[v]->sym_identifier;
204 /* push a given symbol on the symbol stack */
205 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
207 Sym *s, **ps;
208 TokenSym *ts;
210 if (local_stack)
211 ps = &local_stack;
212 else
213 ps = &global_stack;
214 s = sym_push2(ps, v, type->t, c);
215 s->type.ref = type->ref;
216 s->r = r;
217 /* don't record fields or anonymous symbols */
218 /* XXX: simplify */
219 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
220 /* record symbol in token array */
221 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
222 if (v & SYM_STRUCT)
223 ps = &ts->sym_struct;
224 else
225 ps = &ts->sym_identifier;
226 s->prev_tok = *ps;
227 *ps = s;
229 return s;
232 /* push a global identifier */
233 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
235 Sym *s, **ps;
236 s = sym_push2(&global_stack, v, t, c);
237 /* don't record anonymous symbol */
238 if (v < SYM_FIRST_ANOM) {
239 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
240 /* modify the top most local identifier, so that
241 sym_identifier will point to 's' when popped */
242 while (*ps != NULL)
243 ps = &(*ps)->prev_tok;
244 s->prev_tok = NULL;
245 *ps = s;
247 return s;
250 /* pop symbols until top reaches 'b' */
251 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
253 Sym *s, *ss, **ps;
254 TokenSym *ts;
255 int v;
257 s = *ptop;
258 while(s != b) {
259 ss = s->prev;
260 v = s->v;
261 /* remove symbol in token array */
262 /* XXX: simplify */
263 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
264 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
265 if (v & SYM_STRUCT)
266 ps = &ts->sym_struct;
267 else
268 ps = &ts->sym_identifier;
269 *ps = s->prev_tok;
271 sym_free(s);
272 s = ss;
274 *ptop = b;
277 static void weaken_symbol(Sym *sym)
279 sym->type.t |= VT_WEAK;
280 if (sym->c > 0) {
281 int esym_type;
282 ElfW(Sym) *esym;
284 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
285 esym_type = ELFW(ST_TYPE)(esym->st_info);
286 esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
290 /* ------------------------------------------------------------------------- */
292 ST_FUNC void swap(int *p, int *q)
294 int t;
295 t = *p;
296 *p = *q;
297 *q = t;
300 static void vsetc(CType *type, int r, CValue *vc)
302 int v;
304 if (vtop >= vstack + (VSTACK_SIZE - 1))
305 tcc_error("memory full");
306 /* cannot let cpu flags if other instruction are generated. Also
307 avoid leaving VT_JMP anywhere except on the top of the stack
308 because it would complicate the code generator. */
309 if (vtop >= vstack) {
310 v = vtop->r & VT_VALMASK;
311 if (v == VT_CMP || (v & ~1) == VT_JMP)
312 gv(RC_INT);
314 vtop++;
315 vtop->type = *type;
316 vtop->r = r;
317 vtop->r2 = VT_CONST;
318 vtop->c = *vc;
321 /* push constant of type "type" with useless value */
322 void vpush(CType *type)
324 CValue cval;
325 vsetc(type, VT_CONST, &cval);
328 /* push integer constant */
329 ST_FUNC void vpushi(int v)
331 CValue cval;
332 cval.i = v;
333 vsetc(&int_type, VT_CONST, &cval);
336 /* push a pointer sized constant */
337 static void vpushs(long long v)
339 CValue cval;
340 if (PTR_SIZE == 4)
341 cval.i = (int)v;
342 else
343 cval.ull = v;
344 vsetc(&size_type, VT_CONST, &cval);
347 /* push arbitrary 64bit constant */
348 void vpush64(int ty, unsigned long long v)
350 CValue cval;
351 CType ctype;
352 ctype.t = ty;
353 ctype.ref = NULL;
354 cval.ull = v;
355 vsetc(&ctype, VT_CONST, &cval);
358 /* push long long constant */
359 static inline void vpushll(long long v)
361 vpush64(VT_LLONG, v);
364 /* Return a static symbol pointing to a section */
365 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
367 int v;
368 Sym *sym;
370 v = anon_sym++;
371 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
372 sym->type.ref = type->ref;
373 sym->r = VT_CONST | VT_SYM;
374 put_extern_sym(sym, sec, offset, size);
375 return sym;
378 /* push a reference to a section offset by adding a dummy symbol */
379 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
381 CValue cval;
383 cval.ul = 0;
384 vsetc(type, VT_CONST | VT_SYM, &cval);
385 vtop->sym = get_sym_ref(type, sec, offset, size);
388 /* define a new external reference to a symbol 'v' of type 'u' */
389 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
391 Sym *s;
393 s = sym_find(v);
394 if (!s) {
395 /* push forward reference */
396 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
397 s->type.ref = type->ref;
398 s->r = r | VT_CONST | VT_SYM;
400 return s;
403 /* define a new external reference to a symbol 'v' with alternate asm
404 name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
405 is no alternate name (most cases) */
406 static Sym *external_sym(int v, CType *type, int r, char *asm_label)
408 Sym *s;
410 s = sym_find(v);
411 if (!s) {
412 /* push forward reference */
413 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
414 s->asm_label = asm_label;
415 s->type.t |= VT_EXTERN;
416 } else if (s->type.ref == func_old_type.ref) {
417 s->type.ref = type->ref;
418 s->r = r | VT_CONST | VT_SYM;
419 s->type.t |= VT_EXTERN;
420 } else if (!is_compatible_types(&s->type, type)) {
421 tcc_error("incompatible types for redefinition of '%s'",
422 get_tok_str(v, NULL));
424 return s;
427 /* push a reference to global symbol v */
428 ST_FUNC void vpush_global_sym(CType *type, int v)
430 Sym *sym;
431 CValue cval;
433 sym = external_global_sym(v, type, 0);
434 cval.ul = 0;
435 vsetc(type, VT_CONST | VT_SYM, &cval);
436 vtop->sym = sym;
439 ST_FUNC void vset(CType *type, int r, int v)
441 CValue cval;
443 cval.i = v;
444 vsetc(type, r, &cval);
447 static void vseti(int r, int v)
449 CType type;
450 type.t = VT_INT;
451 type.ref = 0;
452 vset(&type, r, v);
455 ST_FUNC void vswap(void)
457 SValue tmp;
458 /* cannot let cpu flags if other instruction are generated. Also
459 avoid leaving VT_JMP anywhere except on the top of the stack
460 because it would complicate the code generator. */
461 if (vtop >= vstack) {
462 int v = vtop->r & VT_VALMASK;
463 if (v == VT_CMP || (v & ~1) == VT_JMP)
464 gv(RC_INT);
466 tmp = vtop[0];
467 vtop[0] = vtop[-1];
468 vtop[-1] = tmp;
470 /* XXX: +2% overall speed possible with optimized memswap
472 * memswap(&vtop[0], &vtop[1], sizeof *vtop);
476 ST_FUNC void vpushv(SValue *v)
478 if (vtop >= vstack + (VSTACK_SIZE - 1))
479 tcc_error("memory full");
480 vtop++;
481 *vtop = *v;
484 static void vdup(void)
486 vpushv(vtop);
489 /* save r to the memory stack, and mark it as being free */
490 ST_FUNC void save_reg(int r)
492 int l, saved, size, align;
493 SValue *p, sv;
494 CType *type;
496 /* modify all stack values */
497 saved = 0;
498 l = 0;
499 for(p=vstack;p<=vtop;p++) {
500 if ((p->r & VT_VALMASK) == r ||
501 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
502 /* must save value on stack if not already done */
503 if (!saved) {
504 /* NOTE: must reload 'r' because r might be equal to r2 */
505 r = p->r & VT_VALMASK;
506 /* store register in the stack */
507 type = &p->type;
508 if ((p->r & VT_LVAL) ||
509 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
510 #ifdef TCC_TARGET_X86_64
511 type = &char_pointer_type;
512 #else
513 type = &int_type;
514 #endif
515 size = type_size(type, &align);
516 loc = (loc - size) & -align;
517 sv.type.t = type->t;
518 sv.r = VT_LOCAL | VT_LVAL;
519 sv.c.ul = loc;
520 store(r, &sv);
521 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
522 /* x86 specific: need to pop fp register ST0 if saved */
523 if (r == TREG_ST0) {
524 o(0xd8dd); /* fstp %st(0) */
526 #endif
527 #ifndef TCC_TARGET_X86_64
528 /* special long long case */
529 if ((type->t & VT_BTYPE) == VT_LLONG) {
530 sv.c.ul += 4;
531 store(p->r2, &sv);
533 #endif
534 l = loc;
535 saved = 1;
537 /* mark that stack entry as being saved on the stack */
538 if (p->r & VT_LVAL) {
539 /* also clear the bounded flag because the
540 relocation address of the function was stored in
541 p->c.ul */
542 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
543 } else {
544 p->r = lvalue_type(p->type.t) | VT_LOCAL;
546 p->r2 = VT_CONST;
547 p->c.ul = l;
552 #ifdef TCC_TARGET_ARM
553 /* find a register of class 'rc2' with at most one reference on stack.
554 * If none, call get_reg(rc) */
555 ST_FUNC int get_reg_ex(int rc, int rc2)
557 int r;
558 SValue *p;
560 for(r=0;r<NB_REGS;r++) {
561 if (reg_classes[r] & rc2) {
562 int n;
563 n=0;
564 for(p = vstack; p <= vtop; p++) {
565 if ((p->r & VT_VALMASK) == r ||
566 (p->r2 & VT_VALMASK) == r)
567 n++;
569 if (n <= 1)
570 return r;
573 return get_reg(rc);
575 #endif
577 /* find a free register of class 'rc'. If none, save one register */
578 ST_FUNC int get_reg(int rc)
580 int r;
581 SValue *p;
583 /* find a free register */
584 for(r=0;r<NB_REGS;r++) {
585 if (reg_classes[r] & rc) {
586 for(p=vstack;p<=vtop;p++) {
587 if ((p->r & VT_VALMASK) == r ||
588 (p->r2 & VT_VALMASK) == r)
589 goto notfound;
591 return r;
593 notfound: ;
596 /* no register left : free the first one on the stack (VERY
597 IMPORTANT to start from the bottom to ensure that we don't
598 spill registers used in gen_opi()) */
599 for(p=vstack;p<=vtop;p++) {
600 /* look at second register (if long long) */
601 r = p->r2 & VT_VALMASK;
602 if (r < VT_CONST && (reg_classes[r] & rc))
603 goto save_found;
604 r = p->r & VT_VALMASK;
605 if (r < VT_CONST && (reg_classes[r] & rc)) {
606 save_found:
607 save_reg(r);
608 return r;
611 /* Should never comes here */
612 return -1;
615 /* save registers up to (vtop - n) stack entry */
616 ST_FUNC void save_regs(int n)
618 int r;
619 SValue *p, *p1;
620 p1 = vtop - n;
621 for(p = vstack;p <= p1; p++) {
622 r = p->r & VT_VALMASK;
623 if (r < VT_CONST) {
624 save_reg(r);
629 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
630 if needed */
631 static void move_reg(int r, int s, int t)
633 SValue sv;
635 if (r != s) {
636 save_reg(r);
637 sv.type.t = t;
638 sv.type.ref = NULL;
639 sv.r = s;
640 sv.c.ul = 0;
641 load(r, &sv);
645 /* get address of vtop (vtop MUST BE an lvalue) */
646 static void gaddrof(void)
648 if (vtop->r & VT_REF)
649 gv(RC_INT);
650 vtop->r &= ~VT_LVAL;
651 /* tricky: if saved lvalue, then we can go back to lvalue */
652 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
653 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
658 #ifdef CONFIG_TCC_BCHECK
659 /* generate lvalue bound code */
660 static void gbound(void)
662 int lval_type;
663 CType type1;
665 vtop->r &= ~VT_MUSTBOUND;
666 /* if lvalue, then use checking code before dereferencing */
667 if (vtop->r & VT_LVAL) {
668 /* if not VT_BOUNDED value, then make one */
669 if (!(vtop->r & VT_BOUNDED)) {
670 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
671 /* must save type because we must set it to int to get pointer */
672 type1 = vtop->type;
673 vtop->type.t = VT_INT;
674 gaddrof();
675 vpushi(0);
676 gen_bounded_ptr_add();
677 vtop->r |= lval_type;
678 vtop->type = type1;
680 /* then check for dereferencing */
681 gen_bounded_ptr_deref();
684 #endif
686 /* store vtop a register belonging to class 'rc'. lvalues are
687 converted to values. Cannot be used if cannot be converted to
688 register value (such as structures). */
689 ST_FUNC int gv(int rc)
691 int r, bit_pos, bit_size, size, align, i;
692 int rc2;
694 /* NOTE: get_reg can modify vstack[] */
695 if (vtop->type.t & VT_BITFIELD) {
696 CType type;
697 int bits = 32;
698 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
699 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
700 /* remove bit field info to avoid loops */
701 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
702 /* cast to int to propagate signedness in following ops */
703 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
704 type.t = VT_LLONG;
705 bits = 64;
706 } else
707 type.t = VT_INT;
708 if((vtop->type.t & VT_UNSIGNED) ||
709 (vtop->type.t & VT_BTYPE) == VT_BOOL)
710 type.t |= VT_UNSIGNED;
711 gen_cast(&type);
712 /* generate shifts */
713 vpushi(bits - (bit_pos + bit_size));
714 gen_op(TOK_SHL);
715 vpushi(bits - bit_size);
716 /* NOTE: transformed to SHR if unsigned */
717 gen_op(TOK_SAR);
718 r = gv(rc);
719 } else {
720 if (is_float(vtop->type.t) &&
721 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
722 Sym *sym;
723 int *ptr;
724 unsigned long offset;
725 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
726 CValue check;
727 #endif
729 /* XXX: unify with initializers handling ? */
730 /* CPUs usually cannot use float constants, so we store them
731 generically in data segment */
732 size = type_size(&vtop->type, &align);
733 offset = (data_section->data_offset + align - 1) & -align;
734 data_section->data_offset = offset;
735 /* XXX: not portable yet */
736 #if defined(__i386__) || defined(__x86_64__)
737 /* Zero pad x87 tenbyte long doubles */
738 if (size == LDOUBLE_SIZE) {
739 vtop->c.tab[2] &= 0xffff;
740 #if LDOUBLE_SIZE == 16
741 vtop->c.tab[3] = 0;
742 #endif
744 #endif
745 ptr = section_ptr_add(data_section, size);
746 size = size >> 2;
747 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
748 check.d = 1;
749 if(check.tab[0])
750 for(i=0;i<size;i++)
751 ptr[i] = vtop->c.tab[size-1-i];
752 else
753 #endif
754 for(i=0;i<size;i++)
755 ptr[i] = vtop->c.tab[i];
756 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
757 vtop->r |= VT_LVAL | VT_SYM;
758 vtop->sym = sym;
759 vtop->c.ul = 0;
761 #ifdef CONFIG_TCC_BCHECK
762 if (vtop->r & VT_MUSTBOUND)
763 gbound();
764 #endif
766 r = vtop->r & VT_VALMASK;
767 rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
768 if (rc == RC_IRET)
769 rc2 = RC_LRET;
770 #ifdef TCC_TARGET_X86_64
771 else if (rc == RC_FRET)
772 rc2 = RC_QRET;
773 #endif
775 /* need to reload if:
776 - constant
777 - lvalue (need to dereference pointer)
778 - already a register, but not in the right class */
779 if (r >= VT_CONST
780 || (vtop->r & VT_LVAL)
781 || !(reg_classes[r] & rc)
782 #ifdef TCC_TARGET_X86_64
783 || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
784 || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
785 #else
786 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
787 #endif
790 r = get_reg(rc);
791 #ifdef TCC_TARGET_X86_64
792 if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
793 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
794 #else
795 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
796 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
797 #endif
798 int r2, original_type;
799 unsigned long long ll;
800 original_type = vtop->type.t;
801 /* two register type load : expand to two words
802 temporarily */
803 #ifndef TCC_TARGET_X86_64
804 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
805 /* load constant */
806 ll = vtop->c.ull;
807 vtop->c.ui = ll; /* first word */
808 load(r, vtop);
809 vtop->r = r; /* save register value */
810 vpushi(ll >> 32); /* second word */
811 } else
812 #endif
813 if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
814 (vtop->r & VT_LVAL)) {
815 /* We do not want to modifier the long long
816 pointer here, so the safest (and less
817 efficient) is to save all the other registers
818 in the stack. XXX: totally inefficient. */
819 save_regs(1);
820 /* load from memory */
821 vtop->type.t = load_type;
822 load(r, vtop);
823 vdup();
824 vtop[-1].r = r; /* save register value */
825 /* increment pointer to get second word */
826 vtop->type.t = addr_type;
827 gaddrof();
828 vpushi(load_size);
829 gen_op('+');
830 vtop->r |= VT_LVAL;
831 vtop->type.t = load_type;
832 } else {
833 /* move registers */
834 load(r, vtop);
835 vdup();
836 vtop[-1].r = r; /* save register value */
837 vtop->r = vtop[-1].r2;
839 /* Allocate second register. Here we rely on the fact that
840 get_reg() tries first to free r2 of an SValue. */
841 r2 = get_reg(rc2);
842 load(r2, vtop);
843 vpop();
844 /* write second register */
845 vtop->r2 = r2;
846 vtop->type.t = original_type;
847 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
848 int t1, t;
849 /* lvalue of scalar type : need to use lvalue type
850 because of possible cast */
851 t = vtop->type.t;
852 t1 = t;
853 /* compute memory access type */
854 if (vtop->r & VT_REF)
855 #ifdef TCC_TARGET_X86_64
856 t = VT_PTR;
857 #else
858 t = VT_INT;
859 #endif
860 else if (vtop->r & VT_LVAL_BYTE)
861 t = VT_BYTE;
862 else if (vtop->r & VT_LVAL_SHORT)
863 t = VT_SHORT;
864 if (vtop->r & VT_LVAL_UNSIGNED)
865 t |= VT_UNSIGNED;
866 vtop->type.t = t;
867 load(r, vtop);
868 /* restore wanted type */
869 vtop->type.t = t1;
870 } else {
871 /* one register type load */
872 load(r, vtop);
875 vtop->r = r;
876 #ifdef TCC_TARGET_C67
877 /* uses register pairs for doubles */
878 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
879 vtop->r2 = r+1;
880 #endif
882 return r;
885 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
886 ST_FUNC void gv2(int rc1, int rc2)
888 int v;
890 /* generate more generic register first. But VT_JMP or VT_CMP
891 values must be generated first in all cases to avoid possible
892 reload errors */
893 v = vtop[0].r & VT_VALMASK;
894 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
895 vswap();
896 gv(rc1);
897 vswap();
898 gv(rc2);
899 /* test if reload is needed for first register */
900 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
901 vswap();
902 gv(rc1);
903 vswap();
905 } else {
906 gv(rc2);
907 vswap();
908 gv(rc1);
909 vswap();
910 /* test if reload is needed for first register */
911 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
912 gv(rc2);
917 /* wrapper around RC_FRET to return a register by type */
918 static int rc_fret(int t)
920 #ifdef TCC_TARGET_X86_64
921 if (t == VT_LDOUBLE) {
922 return RC_ST0;
924 #endif
925 return RC_FRET;
928 /* wrapper around REG_FRET to return a register by type */
929 static int reg_fret(int t)
931 #ifdef TCC_TARGET_X86_64
932 if (t == VT_LDOUBLE) {
933 return TREG_ST0;
935 #endif
936 return REG_FRET;
939 /* expand long long on stack in two int registers */
940 static void lexpand(void)
942 int u;
944 u = vtop->type.t & VT_UNSIGNED;
945 gv(RC_INT);
946 vdup();
947 vtop[0].r = vtop[-1].r2;
948 vtop[0].r2 = VT_CONST;
949 vtop[-1].r2 = VT_CONST;
950 vtop[0].type.t = VT_INT | u;
951 vtop[-1].type.t = VT_INT | u;
954 #ifdef TCC_TARGET_ARM
955 /* expand long long on stack */
956 ST_FUNC void lexpand_nr(void)
958 int u,v;
960 u = vtop->type.t & VT_UNSIGNED;
961 vdup();
962 vtop->r2 = VT_CONST;
963 vtop->type.t = VT_INT | u;
964 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
965 if (v == VT_CONST) {
966 vtop[-1].c.ui = vtop->c.ull;
967 vtop->c.ui = vtop->c.ull >> 32;
968 vtop->r = VT_CONST;
969 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
970 vtop->c.ui += 4;
971 vtop->r = vtop[-1].r;
972 } else if (v > VT_CONST) {
973 vtop--;
974 lexpand();
975 } else
976 vtop->r = vtop[-1].r2;
977 vtop[-1].r2 = VT_CONST;
978 vtop[-1].type.t = VT_INT | u;
980 #endif
982 /* build a long long from two ints */
983 static void lbuild(int t)
985 gv2(RC_INT, RC_INT);
986 vtop[-1].r2 = vtop[0].r;
987 vtop[-1].type.t = t;
988 vpop();
991 /* rotate n first stack elements to the bottom
992 I1 ... In -> I2 ... In I1 [top is right]
994 ST_FUNC void vrotb(int n)
996 int i;
997 SValue tmp;
999 tmp = vtop[-n + 1];
1000 for(i=-n+1;i!=0;i++)
1001 vtop[i] = vtop[i+1];
1002 vtop[0] = tmp;
1005 /* rotate the n elements before entry e towards the top
1006 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1008 ST_FUNC void vrote(SValue *e, int n)
1010 int i;
1011 SValue tmp;
1013 tmp = *e;
1014 for(i = 0;i < n - 1; i++)
1015 e[-i] = e[-i - 1];
1016 e[-n + 1] = tmp;
1019 /* rotate n first stack elements to the top
1020 I1 ... In -> In I1 ... I(n-1) [top is right]
1022 ST_FUNC void vrott(int n)
1024 vrote(vtop, n);
1027 /* pop stack value */
1028 ST_FUNC void vpop(void)
1030 int v;
1031 v = vtop->r & VT_VALMASK;
1032 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1033 /* for x86, we need to pop the FP stack */
1034 if (v == TREG_ST0 && !nocode_wanted) {
1035 o(0xd8dd); /* fstp %st(0) */
1036 } else
1037 #endif
1038 if (v == VT_JMP || v == VT_JMPI) {
1039 /* need to put correct jump if && or || without test */
1040 gsym(vtop->c.ul);
1042 vtop--;
1045 /* convert stack entry to register and duplicate its value in another
1046 register */
1047 static void gv_dup(void)
1049 int rc, t, r, r1;
1050 SValue sv;
1052 t = vtop->type.t;
1053 if ((t & VT_BTYPE) == VT_LLONG) {
1054 lexpand();
1055 gv_dup();
1056 vswap();
1057 vrotb(3);
1058 gv_dup();
1059 vrotb(4);
1060 /* stack: H L L1 H1 */
1061 lbuild(t);
1062 vrotb(3);
1063 vrotb(3);
1064 vswap();
1065 lbuild(t);
1066 vswap();
1067 } else {
1068 /* duplicate value */
1069 rc = RC_INT;
1070 sv.type.t = VT_INT;
1071 if (is_float(t)) {
1072 rc = RC_FLOAT;
1073 #ifdef TCC_TARGET_X86_64
1074 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1075 rc = RC_ST0;
1077 #endif
1078 sv.type.t = t;
1080 r = gv(rc);
1081 r1 = get_reg(rc);
1082 sv.r = r;
1083 sv.c.ul = 0;
1084 load(r1, &sv); /* move r to r1 */
1085 vdup();
1086 /* duplicates value */
1087 if (r != r1)
1088 vtop->r = r1;
1092 #ifndef TCC_TARGET_X86_64
1093 /* generate CPU independent (unsigned) long long operations */
1094 static void gen_opl(int op)
1096 int t, a, b, op1, c, i;
1097 int func;
1098 unsigned short reg_iret = REG_IRET;
1099 unsigned short reg_lret = REG_LRET;
1100 SValue tmp;
1102 switch(op) {
1103 case '/':
1104 case TOK_PDIV:
1105 func = TOK___divdi3;
1106 goto gen_func;
1107 case TOK_UDIV:
1108 func = TOK___udivdi3;
1109 goto gen_func;
1110 case '%':
1111 func = TOK___moddi3;
1112 goto gen_mod_func;
1113 case TOK_UMOD:
1114 func = TOK___umoddi3;
1115 gen_mod_func:
1116 #ifdef TCC_ARM_EABI
1117 reg_iret = TREG_R2;
1118 reg_lret = TREG_R3;
1119 #endif
1120 gen_func:
1121 /* call generic long long function */
1122 vpush_global_sym(&func_old_type, func);
1123 vrott(3);
1124 gfunc_call(2);
1125 vpushi(0);
1126 vtop->r = reg_iret;
1127 vtop->r2 = reg_lret;
1128 break;
1129 case '^':
1130 case '&':
1131 case '|':
1132 case '*':
1133 case '+':
1134 case '-':
1135 t = vtop->type.t;
1136 vswap();
1137 lexpand();
1138 vrotb(3);
1139 lexpand();
1140 /* stack: L1 H1 L2 H2 */
1141 tmp = vtop[0];
1142 vtop[0] = vtop[-3];
1143 vtop[-3] = tmp;
1144 tmp = vtop[-2];
1145 vtop[-2] = vtop[-3];
1146 vtop[-3] = tmp;
1147 vswap();
1148 /* stack: H1 H2 L1 L2 */
1149 if (op == '*') {
1150 vpushv(vtop - 1);
1151 vpushv(vtop - 1);
1152 gen_op(TOK_UMULL);
1153 lexpand();
1154 /* stack: H1 H2 L1 L2 ML MH */
1155 for(i=0;i<4;i++)
1156 vrotb(6);
1157 /* stack: ML MH H1 H2 L1 L2 */
1158 tmp = vtop[0];
1159 vtop[0] = vtop[-2];
1160 vtop[-2] = tmp;
1161 /* stack: ML MH H1 L2 H2 L1 */
1162 gen_op('*');
1163 vrotb(3);
1164 vrotb(3);
1165 gen_op('*');
1166 /* stack: ML MH M1 M2 */
1167 gen_op('+');
1168 gen_op('+');
1169 } else if (op == '+' || op == '-') {
1170 /* XXX: add non carry method too (for MIPS or alpha) */
1171 if (op == '+')
1172 op1 = TOK_ADDC1;
1173 else
1174 op1 = TOK_SUBC1;
1175 gen_op(op1);
1176 /* stack: H1 H2 (L1 op L2) */
1177 vrotb(3);
1178 vrotb(3);
1179 gen_op(op1 + 1); /* TOK_xxxC2 */
1180 } else {
1181 gen_op(op);
1182 /* stack: H1 H2 (L1 op L2) */
1183 vrotb(3);
1184 vrotb(3);
1185 /* stack: (L1 op L2) H1 H2 */
1186 gen_op(op);
1187 /* stack: (L1 op L2) (H1 op H2) */
1189 /* stack: L H */
1190 lbuild(t);
1191 break;
1192 case TOK_SAR:
1193 case TOK_SHR:
1194 case TOK_SHL:
1195 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1196 t = vtop[-1].type.t;
1197 vswap();
1198 lexpand();
1199 vrotb(3);
1200 /* stack: L H shift */
1201 c = (int)vtop->c.i;
1202 /* constant: simpler */
1203 /* NOTE: all comments are for SHL. the other cases are
1204 done by swaping words */
1205 vpop();
1206 if (op != TOK_SHL)
1207 vswap();
1208 if (c >= 32) {
1209 /* stack: L H */
1210 vpop();
1211 if (c > 32) {
1212 vpushi(c - 32);
1213 gen_op(op);
1215 if (op != TOK_SAR) {
1216 vpushi(0);
1217 } else {
1218 gv_dup();
1219 vpushi(31);
1220 gen_op(TOK_SAR);
1222 vswap();
1223 } else {
1224 vswap();
1225 gv_dup();
1226 /* stack: H L L */
1227 vpushi(c);
1228 gen_op(op);
1229 vswap();
1230 vpushi(32 - c);
1231 if (op == TOK_SHL)
1232 gen_op(TOK_SHR);
1233 else
1234 gen_op(TOK_SHL);
1235 vrotb(3);
1236 /* stack: L L H */
1237 vpushi(c);
1238 if (op == TOK_SHL)
1239 gen_op(TOK_SHL);
1240 else
1241 gen_op(TOK_SHR);
1242 gen_op('|');
1244 if (op != TOK_SHL)
1245 vswap();
1246 lbuild(t);
1247 } else {
1248 /* XXX: should provide a faster fallback on x86 ? */
1249 switch(op) {
1250 case TOK_SAR:
1251 func = TOK___ashrdi3;
1252 goto gen_func;
1253 case TOK_SHR:
1254 func = TOK___lshrdi3;
1255 goto gen_func;
1256 case TOK_SHL:
1257 func = TOK___ashldi3;
1258 goto gen_func;
1261 break;
1262 default:
1263 /* compare operations */
1264 t = vtop->type.t;
1265 vswap();
1266 lexpand();
1267 vrotb(3);
1268 lexpand();
1269 /* stack: L1 H1 L2 H2 */
1270 tmp = vtop[-1];
1271 vtop[-1] = vtop[-2];
1272 vtop[-2] = tmp;
1273 /* stack: L1 L2 H1 H2 */
1274 /* compare high */
1275 op1 = op;
1276 /* when values are equal, we need to compare low words. since
1277 the jump is inverted, we invert the test too. */
1278 if (op1 == TOK_LT)
1279 op1 = TOK_LE;
1280 else if (op1 == TOK_GT)
1281 op1 = TOK_GE;
1282 else if (op1 == TOK_ULT)
1283 op1 = TOK_ULE;
1284 else if (op1 == TOK_UGT)
1285 op1 = TOK_UGE;
1286 a = 0;
1287 b = 0;
1288 gen_op(op1);
1289 if (op1 != TOK_NE) {
1290 a = gtst(1, 0);
1292 if (op != TOK_EQ) {
1293 /* generate non equal test */
1294 /* XXX: NOT PORTABLE yet */
1295 if (a == 0) {
1296 b = gtst(0, 0);
1297 } else {
1298 #if defined(TCC_TARGET_I386)
1299 b = psym(0x850f, 0);
1300 #elif defined(TCC_TARGET_ARM)
1301 b = ind;
1302 o(0x1A000000 | encbranch(ind, 0, 1));
1303 #elif defined(TCC_TARGET_C67)
1304 tcc_error("not implemented");
1305 #else
1306 #error not supported
1307 #endif
1310 /* compare low. Always unsigned */
1311 op1 = op;
1312 if (op1 == TOK_LT)
1313 op1 = TOK_ULT;
1314 else if (op1 == TOK_LE)
1315 op1 = TOK_ULE;
1316 else if (op1 == TOK_GT)
1317 op1 = TOK_UGT;
1318 else if (op1 == TOK_GE)
1319 op1 = TOK_UGE;
1320 gen_op(op1);
1321 a = gtst(1, a);
1322 gsym(b);
1323 vseti(VT_JMPI, a);
1324 break;
1327 #endif
1329 /* handle integer constant optimizations and various machine
1330 independent opt */
1331 static void gen_opic(int op)
1333 int c1, c2, t1, t2, n;
1334 SValue *v1, *v2;
1335 long long l1, l2;
1336 typedef unsigned long long U;
1338 v1 = vtop - 1;
1339 v2 = vtop;
1340 t1 = v1->type.t & VT_BTYPE;
1341 t2 = v2->type.t & VT_BTYPE;
1343 if (t1 == VT_LLONG)
1344 l1 = v1->c.ll;
1345 else if (v1->type.t & VT_UNSIGNED)
1346 l1 = v1->c.ui;
1347 else
1348 l1 = v1->c.i;
1350 if (t2 == VT_LLONG)
1351 l2 = v2->c.ll;
1352 else if (v2->type.t & VT_UNSIGNED)
1353 l2 = v2->c.ui;
1354 else
1355 l2 = v2->c.i;
1357 /* currently, we cannot do computations with forward symbols */
1358 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1359 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1360 if (c1 && c2) {
1361 switch(op) {
1362 case '+': l1 += l2; break;
1363 case '-': l1 -= l2; break;
1364 case '&': l1 &= l2; break;
1365 case '^': l1 ^= l2; break;
1366 case '|': l1 |= l2; break;
1367 case '*': l1 *= l2; break;
1369 case TOK_PDIV:
1370 case '/':
1371 case '%':
1372 case TOK_UDIV:
1373 case TOK_UMOD:
1374 /* if division by zero, generate explicit division */
1375 if (l2 == 0) {
1376 if (const_wanted)
1377 tcc_error("division by zero in constant");
1378 goto general_case;
1380 switch(op) {
1381 default: l1 /= l2; break;
1382 case '%': l1 %= l2; break;
1383 case TOK_UDIV: l1 = (U)l1 / l2; break;
1384 case TOK_UMOD: l1 = (U)l1 % l2; break;
1386 break;
1387 case TOK_SHL: l1 <<= l2; break;
1388 case TOK_SHR: l1 = (U)l1 >> l2; break;
1389 case TOK_SAR: l1 >>= l2; break;
1390 /* tests */
1391 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1392 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1393 case TOK_EQ: l1 = l1 == l2; break;
1394 case TOK_NE: l1 = l1 != l2; break;
1395 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1396 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1397 case TOK_LT: l1 = l1 < l2; break;
1398 case TOK_GE: l1 = l1 >= l2; break;
1399 case TOK_LE: l1 = l1 <= l2; break;
1400 case TOK_GT: l1 = l1 > l2; break;
1401 /* logical */
1402 case TOK_LAND: l1 = l1 && l2; break;
1403 case TOK_LOR: l1 = l1 || l2; break;
1404 default:
1405 goto general_case;
1407 v1->c.ll = l1;
1408 vtop--;
1409 } else {
1410 /* if commutative ops, put c2 as constant */
1411 if (c1 && (op == '+' || op == '&' || op == '^' ||
1412 op == '|' || op == '*')) {
1413 vswap();
1414 c2 = c1; //c = c1, c1 = c2, c2 = c;
1415 l2 = l1; //l = l1, l1 = l2, l2 = l;
1417 /* Filter out NOP operations like x*1, x-0, x&-1... */
1418 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1419 op == TOK_PDIV) &&
1420 l2 == 1) ||
1421 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1422 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1423 l2 == 0) ||
1424 (op == '&' &&
1425 l2 == -1))) {
1426 /* nothing to do */
1427 vtop--;
1428 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1429 /* try to use shifts instead of muls or divs */
1430 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1431 n = -1;
1432 while (l2) {
1433 l2 >>= 1;
1434 n++;
1436 vtop->c.ll = n;
1437 if (op == '*')
1438 op = TOK_SHL;
1439 else if (op == TOK_PDIV)
1440 op = TOK_SAR;
1441 else
1442 op = TOK_SHR;
1444 goto general_case;
1445 } else if (c2 && (op == '+' || op == '-') &&
1446 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1447 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1448 /* symbol + constant case */
1449 if (op == '-')
1450 l2 = -l2;
1451 vtop--;
1452 vtop->c.ll += l2;
1453 } else {
1454 general_case:
1455 if (!nocode_wanted) {
1456 /* call low level op generator */
1457 if (t1 == VT_LLONG || t2 == VT_LLONG)
1458 gen_opl(op);
1459 else
1460 gen_opi(op);
1461 } else {
1462 vtop--;
1468 /* generate a floating point operation with constant propagation */
1469 static void gen_opif(int op)
1471 int c1, c2;
1472 SValue *v1, *v2;
1473 long double f1, f2;
1475 v1 = vtop - 1;
1476 v2 = vtop;
1477 /* currently, we cannot do computations with forward symbols */
1478 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1479 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1480 if (c1 && c2) {
1481 if (v1->type.t == VT_FLOAT) {
1482 f1 = v1->c.f;
1483 f2 = v2->c.f;
1484 } else if (v1->type.t == VT_DOUBLE) {
1485 f1 = v1->c.d;
1486 f2 = v2->c.d;
1487 } else {
1488 f1 = v1->c.ld;
1489 f2 = v2->c.ld;
1492 /* NOTE: we only do constant propagation if finite number (not
1493 NaN or infinity) (ANSI spec) */
1494 if (!ieee_finite(f1) || !ieee_finite(f2))
1495 goto general_case;
1497 switch(op) {
1498 case '+': f1 += f2; break;
1499 case '-': f1 -= f2; break;
1500 case '*': f1 *= f2; break;
1501 case '/':
1502 if (f2 == 0.0) {
1503 if (const_wanted)
1504 tcc_error("division by zero in constant");
1505 goto general_case;
1507 f1 /= f2;
1508 break;
1509 /* XXX: also handles tests ? */
1510 default:
1511 goto general_case;
1513 /* XXX: overflow test ? */
1514 if (v1->type.t == VT_FLOAT) {
1515 v1->c.f = f1;
1516 } else if (v1->type.t == VT_DOUBLE) {
1517 v1->c.d = f1;
1518 } else {
1519 v1->c.ld = f1;
1521 vtop--;
1522 } else {
1523 general_case:
1524 if (!nocode_wanted) {
1525 gen_opf(op);
1526 } else {
1527 vtop--;
1532 static int pointed_size(CType *type)
1534 int align;
1535 return type_size(pointed_type(type), &align);
1538 static void vla_runtime_pointed_size(CType *type)
1540 int align;
1541 vla_runtime_type_size(pointed_type(type), &align);
1544 static inline int is_null_pointer(SValue *p)
1546 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1547 return 0;
1548 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1549 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||
1550 ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr == 0);
1553 static inline int is_integer_btype(int bt)
1555 return (bt == VT_BYTE || bt == VT_SHORT ||
1556 bt == VT_INT || bt == VT_LLONG);
1559 /* check types for comparison or substraction of pointers */
1560 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1562 CType *type1, *type2, tmp_type1, tmp_type2;
1563 int bt1, bt2;
1565 /* null pointers are accepted for all comparisons as gcc */
1566 if (is_null_pointer(p1) || is_null_pointer(p2))
1567 return;
1568 type1 = &p1->type;
1569 type2 = &p2->type;
1570 bt1 = type1->t & VT_BTYPE;
1571 bt2 = type2->t & VT_BTYPE;
1572 /* accept comparison between pointer and integer with a warning */
1573 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1574 if (op != TOK_LOR && op != TOK_LAND )
1575 tcc_warning("comparison between pointer and integer");
1576 return;
1579 /* both must be pointers or implicit function pointers */
1580 if (bt1 == VT_PTR) {
1581 type1 = pointed_type(type1);
1582 } else if (bt1 != VT_FUNC)
1583 goto invalid_operands;
1585 if (bt2 == VT_PTR) {
1586 type2 = pointed_type(type2);
1587 } else if (bt2 != VT_FUNC) {
1588 invalid_operands:
1589 tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
1591 if ((type1->t & VT_BTYPE) == VT_VOID ||
1592 (type2->t & VT_BTYPE) == VT_VOID)
1593 return;
1594 tmp_type1 = *type1;
1595 tmp_type2 = *type2;
1596 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1597 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1598 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1599 /* gcc-like error if '-' is used */
1600 if (op == '-')
1601 goto invalid_operands;
1602 else
1603 tcc_warning("comparison of distinct pointer types lacks a cast");
1607 /* generic gen_op: handles types problems */
1608 ST_FUNC void gen_op(int op)
1610 int u, t1, t2, bt1, bt2, t;
1611 CType type1;
1613 t1 = vtop[-1].type.t;
1614 t2 = vtop[0].type.t;
1615 bt1 = t1 & VT_BTYPE;
1616 bt2 = t2 & VT_BTYPE;
1618 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1619 /* at least one operand is a pointer */
1620 /* relationnal op: must be both pointers */
1621 if (op >= TOK_ULT && op <= TOK_LOR) {
1622 check_comparison_pointer_types(vtop - 1, vtop, op);
1623 /* pointers are handled are unsigned */
1624 #ifdef TCC_TARGET_X86_64
1625 t = VT_LLONG | VT_UNSIGNED;
1626 #else
1627 t = VT_INT | VT_UNSIGNED;
1628 #endif
1629 goto std_op;
1631 /* if both pointers, then it must be the '-' op */
1632 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1633 if (op != '-')
1634 tcc_error("cannot use pointers here");
1635 check_comparison_pointer_types(vtop - 1, vtop, op);
1636 /* XXX: check that types are compatible */
1637 if (vtop[-1].type.t & VT_VLA) {
1638 vla_runtime_pointed_size(&vtop[-1].type);
1639 } else {
1640 vpushi(pointed_size(&vtop[-1].type));
1642 vrott(3);
1643 gen_opic(op);
1644 /* set to integer type */
1645 #ifdef TCC_TARGET_X86_64
1646 vtop->type.t = VT_LLONG;
1647 #else
1648 vtop->type.t = VT_INT;
1649 #endif
1650 vswap();
1651 gen_op(TOK_PDIV);
1652 } else {
1653 /* exactly one pointer : must be '+' or '-'. */
1654 if (op != '-' && op != '+')
1655 tcc_error("cannot use pointers here");
1656 /* Put pointer as first operand */
1657 if (bt2 == VT_PTR) {
1658 vswap();
1659 swap(&t1, &t2);
1661 type1 = vtop[-1].type;
1662 type1.t &= ~VT_ARRAY;
1663 if (vtop[-1].type.t & VT_VLA)
1664 vla_runtime_pointed_size(&vtop[-1].type);
1665 else {
1666 u = pointed_size(&vtop[-1].type);
1667 if (u < 0)
1668 tcc_error("unknown array element size");
1669 #ifdef TCC_TARGET_X86_64
1670 vpushll(u);
1671 #else
1672 /* XXX: cast to int ? (long long case) */
1673 vpushi(u);
1674 #endif
1676 gen_op('*');
1677 #ifdef CONFIG_TCC_BCHECK
1678 /* if evaluating constant expression, no code should be
1679 generated, so no bound check */
1680 if (tcc_state->do_bounds_check && !const_wanted) {
1681 /* if bounded pointers, we generate a special code to
1682 test bounds */
1683 if (op == '-') {
1684 vpushi(0);
1685 vswap();
1686 gen_op('-');
1688 gen_bounded_ptr_add();
1689 } else
1690 #endif
1692 gen_opic(op);
1694 /* put again type if gen_opic() swaped operands */
1695 vtop->type = type1;
1697 } else if (is_float(bt1) || is_float(bt2)) {
1698 /* compute bigger type and do implicit casts */
1699 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1700 t = VT_LDOUBLE;
1701 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1702 t = VT_DOUBLE;
1703 } else {
1704 t = VT_FLOAT;
1706 /* floats can only be used for a few operations */
1707 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1708 (op < TOK_ULT || op > TOK_GT))
1709 tcc_error("invalid operands for binary operation");
1710 goto std_op;
1711 } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
1712 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
1713 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (t | VT_UNSIGNED))
1714 t |= VT_UNSIGNED;
1715 goto std_op;
1716 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1717 /* cast to biggest op */
1718 t = VT_LLONG;
1719 /* convert to unsigned if it does not fit in a long long */
1720 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1721 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1722 t |= VT_UNSIGNED;
1723 goto std_op;
1724 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
1725 tcc_error("comparison of struct");
1726 } else {
1727 /* integer operations */
1728 t = VT_INT;
1729 /* convert to unsigned if it does not fit in an integer */
1730 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1731 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1732 t |= VT_UNSIGNED;
1733 std_op:
1734 /* XXX: currently, some unsigned operations are explicit, so
1735 we modify them here */
1736 if (t & VT_UNSIGNED) {
1737 if (op == TOK_SAR)
1738 op = TOK_SHR;
1739 else if (op == '/')
1740 op = TOK_UDIV;
1741 else if (op == '%')
1742 op = TOK_UMOD;
1743 else if (op == TOK_LT)
1744 op = TOK_ULT;
1745 else if (op == TOK_GT)
1746 op = TOK_UGT;
1747 else if (op == TOK_LE)
1748 op = TOK_ULE;
1749 else if (op == TOK_GE)
1750 op = TOK_UGE;
1752 vswap();
1753 type1.t = t;
1754 gen_cast(&type1);
1755 vswap();
1756 /* special case for shifts and long long: we keep the shift as
1757 an integer */
1758 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1759 type1.t = VT_INT;
1760 gen_cast(&type1);
1761 if (is_float(t))
1762 gen_opif(op);
1763 else
1764 gen_opic(op);
1765 if (op >= TOK_ULT && op <= TOK_GT) {
1766 /* relationnal op: the result is an int */
1767 vtop->type.t = VT_INT;
1768 } else {
1769 vtop->type.t = t;
1774 #ifndef TCC_TARGET_ARM
1775 /* generic itof for unsigned long long case */
1776 static void gen_cvt_itof1(int t)
1778 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1779 (VT_LLONG | VT_UNSIGNED)) {
1781 if (t == VT_FLOAT)
1782 vpush_global_sym(&func_old_type, TOK___floatundisf);
1783 #if LDOUBLE_SIZE != 8
1784 else if (t == VT_LDOUBLE)
1785 vpush_global_sym(&func_old_type, TOK___floatundixf);
1786 #endif
1787 else
1788 vpush_global_sym(&func_old_type, TOK___floatundidf);
1789 vrott(2);
1790 gfunc_call(1);
1791 vpushi(0);
1792 vtop->r = reg_fret(t);
1793 } else {
1794 gen_cvt_itof(t);
1797 #endif
1799 /* generic ftoi for unsigned long long case */
1800 static void gen_cvt_ftoi1(int t)
1802 int st;
1804 if (t == (VT_LLONG | VT_UNSIGNED)) {
1805 /* not handled natively */
1806 st = vtop->type.t & VT_BTYPE;
1807 if (st == VT_FLOAT)
1808 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1809 #if LDOUBLE_SIZE != 8
1810 else if (st == VT_LDOUBLE)
1811 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1812 #endif
1813 else
1814 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1815 vrott(2);
1816 gfunc_call(1);
1817 vpushi(0);
1818 vtop->r = REG_IRET;
1819 vtop->r2 = REG_LRET;
1820 } else {
1821 gen_cvt_ftoi(t);
1825 /* force char or short cast */
1826 static void force_charshort_cast(int t)
1828 int bits, dbt;
1829 dbt = t & VT_BTYPE;
1830 /* XXX: add optimization if lvalue : just change type and offset */
1831 if (dbt == VT_BYTE)
1832 bits = 8;
1833 else
1834 bits = 16;
1835 if (t & VT_UNSIGNED) {
1836 vpushi((1 << bits) - 1);
1837 gen_op('&');
1838 } else {
1839 bits = 32 - bits;
1840 vpushi(bits);
1841 gen_op(TOK_SHL);
1842 /* result must be signed or the SAR is converted to an SHL
1843 This was not the case when "t" was a signed short
1844 and the last value on the stack was an unsigned int */
1845 vtop->type.t &= ~VT_UNSIGNED;
1846 vpushi(bits);
1847 gen_op(TOK_SAR);
1851 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1852 static void gen_cast(CType *type)
1854 int sbt, dbt, sf, df, c, p;
1856 /* special delayed cast for char/short */
1857 /* XXX: in some cases (multiple cascaded casts), it may still
1858 be incorrect */
1859 if (vtop->r & VT_MUSTCAST) {
1860 vtop->r &= ~VT_MUSTCAST;
1861 force_charshort_cast(vtop->type.t);
1864 /* bitfields first get cast to ints */
1865 if (vtop->type.t & VT_BITFIELD) {
1866 gv(RC_INT);
1869 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1870 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1872 if (sbt != dbt) {
1873 sf = is_float(sbt);
1874 df = is_float(dbt);
1875 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1876 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1877 if (c) {
1878 /* constant case: we can do it now */
1879 /* XXX: in ISOC, cannot do it if error in convert */
1880 if (sbt == VT_FLOAT)
1881 vtop->c.ld = vtop->c.f;
1882 else if (sbt == VT_DOUBLE)
1883 vtop->c.ld = vtop->c.d;
1885 if (df) {
1886 if ((sbt & VT_BTYPE) == VT_LLONG) {
1887 if (sbt & VT_UNSIGNED)
1888 vtop->c.ld = vtop->c.ull;
1889 else
1890 vtop->c.ld = vtop->c.ll;
1891 } else if(!sf) {
1892 if (sbt & VT_UNSIGNED)
1893 vtop->c.ld = vtop->c.ui;
1894 else
1895 vtop->c.ld = vtop->c.i;
1898 if (dbt == VT_FLOAT)
1899 vtop->c.f = (float)vtop->c.ld;
1900 else if (dbt == VT_DOUBLE)
1901 vtop->c.d = (double)vtop->c.ld;
1902 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1903 vtop->c.ull = (unsigned long long)vtop->c.ld;
1904 } else if (sf && dbt == VT_BOOL) {
1905 vtop->c.i = (vtop->c.ld != 0);
1906 } else {
1907 if(sf)
1908 vtop->c.ll = (long long)vtop->c.ld;
1909 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1910 vtop->c.ll = vtop->c.ull;
1911 else if (sbt & VT_UNSIGNED)
1912 vtop->c.ll = vtop->c.ui;
1913 #ifdef TCC_TARGET_X86_64
1914 else if (sbt == VT_PTR)
1916 #endif
1917 else if (sbt != VT_LLONG)
1918 vtop->c.ll = vtop->c.i;
1920 if (dbt == (VT_LLONG|VT_UNSIGNED))
1921 vtop->c.ull = vtop->c.ll;
1922 else if (dbt == VT_BOOL)
1923 vtop->c.i = (vtop->c.ll != 0);
1924 else if (dbt != VT_LLONG) {
1925 int s = 0;
1926 if ((dbt & VT_BTYPE) == VT_BYTE)
1927 s = 24;
1928 else if ((dbt & VT_BTYPE) == VT_SHORT)
1929 s = 16;
1931 if(dbt & VT_UNSIGNED)
1932 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
1933 else
1934 vtop->c.i = ((int)vtop->c.ll << s) >> s;
1937 } else if (p && dbt == VT_BOOL) {
1938 vtop->r = VT_CONST;
1939 vtop->c.i = 1;
1940 } else if (!nocode_wanted) {
1941 /* non constant case: generate code */
1942 if (sf && df) {
1943 /* convert from fp to fp */
1944 gen_cvt_ftof(dbt);
1945 } else if (df) {
1946 /* convert int to fp */
1947 gen_cvt_itof1(dbt);
1948 } else if (sf) {
1949 /* convert fp to int */
1950 if (dbt == VT_BOOL) {
1951 vpushi(0);
1952 gen_op(TOK_NE);
1953 } else {
1954 /* we handle char/short/etc... with generic code */
1955 if (dbt != (VT_INT | VT_UNSIGNED) &&
1956 dbt != (VT_LLONG | VT_UNSIGNED) &&
1957 dbt != VT_LLONG)
1958 dbt = VT_INT;
1959 gen_cvt_ftoi1(dbt);
1960 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
1961 /* additional cast for char/short... */
1962 vtop->type.t = dbt;
1963 gen_cast(type);
1966 #ifndef TCC_TARGET_X86_64
1967 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
1968 if ((sbt & VT_BTYPE) != VT_LLONG) {
1969 /* scalar to long long */
1970 /* machine independent conversion */
1971 gv(RC_INT);
1972 /* generate high word */
1973 if (sbt == (VT_INT | VT_UNSIGNED)) {
1974 vpushi(0);
1975 gv(RC_INT);
1976 } else {
1977 if (sbt == VT_PTR) {
1978 /* cast from pointer to int before we apply
1979 shift operation, which pointers don't support*/
1980 gen_cast(&int_type);
1982 gv_dup();
1983 vpushi(31);
1984 gen_op(TOK_SAR);
1986 /* patch second register */
1987 vtop[-1].r2 = vtop->r;
1988 vpop();
1990 #else
1991 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
1992 (dbt & VT_BTYPE) == VT_PTR ||
1993 (dbt & VT_BTYPE) == VT_FUNC) {
1994 if ((sbt & VT_BTYPE) != VT_LLONG &&
1995 (sbt & VT_BTYPE) != VT_PTR &&
1996 (sbt & VT_BTYPE) != VT_FUNC) {
1997 /* need to convert from 32bit to 64bit */
1998 int r = gv(RC_INT);
1999 if (sbt != (VT_INT | VT_UNSIGNED)) {
2000 /* x86_64 specific: movslq */
2001 o(0x6348);
2002 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
2005 #endif
2006 } else if (dbt == VT_BOOL) {
2007 /* scalar to bool */
2008 vpushi(0);
2009 gen_op(TOK_NE);
2010 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
2011 (dbt & VT_BTYPE) == VT_SHORT) {
2012 if (sbt == VT_PTR) {
2013 vtop->type.t = VT_INT;
2014 tcc_warning("nonportable conversion from pointer to char/short");
2016 force_charshort_cast(dbt);
2017 } else if ((dbt & VT_BTYPE) == VT_INT) {
2018 /* scalar to int */
2019 if (sbt == VT_LLONG) {
2020 /* from long long: just take low order word */
2021 lexpand();
2022 vpop();
2024 /* if lvalue and single word type, nothing to do because
2025 the lvalue already contains the real type size (see
2026 VT_LVAL_xxx constants) */
2029 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
2030 /* if we are casting between pointer types,
2031 we must update the VT_LVAL_xxx size */
2032 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
2033 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
2035 vtop->type = *type;
2038 /* return type size as known at compile time. Put alignment at 'a' */
2039 ST_FUNC int type_size(CType *type, int *a)
2041 Sym *s;
2042 int bt;
2044 bt = type->t & VT_BTYPE;
2045 if (bt == VT_STRUCT) {
2046 /* struct/union */
2047 s = type->ref;
2048 *a = s->r;
2049 return s->c;
2050 } else if (bt == VT_PTR) {
2051 if (type->t & VT_ARRAY) {
2052 int ts;
2054 s = type->ref;
2055 ts = type_size(&s->type, a);
2057 if (ts < 0 && s->c < 0)
2058 ts = -ts;
2060 return ts * s->c;
2061 } else {
2062 *a = PTR_SIZE;
2063 return PTR_SIZE;
2065 } else if (bt == VT_LDOUBLE) {
2066 *a = LDOUBLE_ALIGN;
2067 return LDOUBLE_SIZE;
2068 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2069 #ifdef TCC_TARGET_I386
2070 #ifdef TCC_TARGET_PE
2071 *a = 8;
2072 #else
2073 *a = 4;
2074 #endif
2075 #elif defined(TCC_TARGET_ARM)
2076 #ifdef TCC_ARM_EABI
2077 *a = 8;
2078 #else
2079 *a = 4;
2080 #endif
2081 #else
2082 *a = 8;
2083 #endif
2084 return 8;
2085 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
2086 *a = 4;
2087 return 4;
2088 } else if (bt == VT_SHORT) {
2089 *a = 2;
2090 return 2;
2091 } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
2092 *a = 8;
2093 return 16;
2094 } else {
2095 /* char, void, function, _Bool */
2096 *a = 1;
2097 return 1;
2101 /* push type size as known at runtime time on top of value stack. Put
2102 alignment at 'a' */
2103 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2105 if (type->t & VT_VLA) {
2106 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2107 } else {
2108 vpushi(type_size(type, a));
2112 /* return the pointed type of t */
2113 static inline CType *pointed_type(CType *type)
2115 return &type->ref->type;
2118 /* modify type so that its it is a pointer to type. */
2119 ST_FUNC void mk_pointer(CType *type)
2121 Sym *s;
2122 s = sym_push(SYM_FIELD, type, 0, -1);
2123 type->t = VT_PTR | (type->t & ~VT_TYPE);
2124 type->ref = s;
2127 /* compare function types. OLD functions match any new functions */
2128 static int is_compatible_func(CType *type1, CType *type2)
2130 Sym *s1, *s2;
2132 s1 = type1->ref;
2133 s2 = type2->ref;
2134 if (!is_compatible_types(&s1->type, &s2->type))
2135 return 0;
2136 /* check func_call */
2137 if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
2138 return 0;
2139 /* XXX: not complete */
2140 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2141 return 1;
2142 if (s1->c != s2->c)
2143 return 0;
2144 while (s1 != NULL) {
2145 if (s2 == NULL)
2146 return 0;
2147 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2148 return 0;
2149 s1 = s1->next;
2150 s2 = s2->next;
2152 if (s2)
2153 return 0;
2154 return 1;
2157 /* return true if type1 and type2 are the same. If unqualified is
2158 true, qualifiers on the types are ignored.
2160 - enums are not checked as gcc __builtin_types_compatible_p ()
2162 static int compare_types(CType *type1, CType *type2, int unqualified)
2164 int bt1, t1, t2;
2166 t1 = type1->t & VT_TYPE;
2167 t2 = type2->t & VT_TYPE;
2168 if (unqualified) {
2169 /* strip qualifiers before comparing */
2170 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2171 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2173 /* XXX: bitfields ? */
2174 if (t1 != t2)
2175 return 0;
2176 /* test more complicated cases */
2177 bt1 = t1 & VT_BTYPE;
2178 if (bt1 == VT_PTR) {
2179 type1 = pointed_type(type1);
2180 type2 = pointed_type(type2);
2181 return is_compatible_types(type1, type2);
2182 } else if (bt1 == VT_STRUCT) {
2183 return (type1->ref == type2->ref);
2184 } else if (bt1 == VT_FUNC) {
2185 return is_compatible_func(type1, type2);
2186 } else {
2187 return 1;
2191 /* return true if type1 and type2 are exactly the same (including
2192 qualifiers).
2194 static int is_compatible_types(CType *type1, CType *type2)
2196 return compare_types(type1,type2,0);
2199 /* return true if type1 and type2 are the same (ignoring qualifiers).
2201 static int is_compatible_parameter_types(CType *type1, CType *type2)
2203 return compare_types(type1,type2,1);
2206 /* print a type. If 'varstr' is not NULL, then the variable is also
2207 printed in the type */
2208 /* XXX: union */
2209 /* XXX: add array and function pointers */
2210 static void type_to_str(char *buf, int buf_size,
2211 CType *type, const char *varstr)
2213 int bt, v, t;
2214 Sym *s, *sa;
2215 char buf1[256];
2216 const char *tstr;
2218 t = type->t & VT_TYPE;
2219 bt = t & VT_BTYPE;
2220 buf[0] = '\0';
2221 if (t & VT_CONSTANT)
2222 pstrcat(buf, buf_size, "const ");
2223 if (t & VT_VOLATILE)
2224 pstrcat(buf, buf_size, "volatile ");
2225 if (t & VT_UNSIGNED)
2226 pstrcat(buf, buf_size, "unsigned ");
2227 switch(bt) {
2228 case VT_VOID:
2229 tstr = "void";
2230 goto add_tstr;
2231 case VT_BOOL:
2232 tstr = "_Bool";
2233 goto add_tstr;
2234 case VT_BYTE:
2235 tstr = "char";
2236 goto add_tstr;
2237 case VT_SHORT:
2238 tstr = "short";
2239 goto add_tstr;
2240 case VT_INT:
2241 tstr = "int";
2242 goto add_tstr;
2243 case VT_LONG:
2244 tstr = "long";
2245 goto add_tstr;
2246 case VT_LLONG:
2247 tstr = "long long";
2248 goto add_tstr;
2249 case VT_FLOAT:
2250 tstr = "float";
2251 goto add_tstr;
2252 case VT_DOUBLE:
2253 tstr = "double";
2254 goto add_tstr;
2255 case VT_LDOUBLE:
2256 tstr = "long double";
2257 add_tstr:
2258 pstrcat(buf, buf_size, tstr);
2259 break;
2260 case VT_ENUM:
2261 case VT_STRUCT:
2262 if (bt == VT_STRUCT)
2263 tstr = "struct ";
2264 else
2265 tstr = "enum ";
2266 pstrcat(buf, buf_size, tstr);
2267 v = type->ref->v & ~SYM_STRUCT;
2268 if (v >= SYM_FIRST_ANOM)
2269 pstrcat(buf, buf_size, "<anonymous>");
2270 else
2271 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2272 break;
2273 case VT_FUNC:
2274 s = type->ref;
2275 type_to_str(buf, buf_size, &s->type, varstr);
2276 pstrcat(buf, buf_size, "(");
2277 sa = s->next;
2278 while (sa != NULL) {
2279 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2280 pstrcat(buf, buf_size, buf1);
2281 sa = sa->next;
2282 if (sa)
2283 pstrcat(buf, buf_size, ", ");
2285 pstrcat(buf, buf_size, ")");
2286 goto no_var;
2287 case VT_PTR:
2288 s = type->ref;
2289 pstrcpy(buf1, sizeof(buf1), "*");
2290 if (varstr)
2291 pstrcat(buf1, sizeof(buf1), varstr);
2292 type_to_str(buf, buf_size, &s->type, buf1);
2293 goto no_var;
2295 if (varstr) {
2296 pstrcat(buf, buf_size, " ");
2297 pstrcat(buf, buf_size, varstr);
2299 no_var: ;
2302 /* verify type compatibility to store vtop in 'dt' type, and generate
2303 casts if needed. */
2304 static void gen_assign_cast(CType *dt)
2306 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2307 char buf1[256], buf2[256];
2308 int dbt, sbt;
2310 st = &vtop->type; /* source type */
2311 dbt = dt->t & VT_BTYPE;
2312 sbt = st->t & VT_BTYPE;
2313 if (sbt == VT_VOID)
2314 tcc_error("Cannot assign void value");
2315 if (dt->t & VT_CONSTANT)
2316 tcc_warning("assignment of read-only location");
2317 switch(dbt) {
2318 case VT_PTR:
2319 /* special cases for pointers */
2320 /* '0' can also be a pointer */
2321 if (is_null_pointer(vtop))
2322 goto type_ok;
2323 /* accept implicit pointer to integer cast with warning */
2324 if (is_integer_btype(sbt)) {
2325 tcc_warning("assignment makes pointer from integer without a cast");
2326 goto type_ok;
2328 type1 = pointed_type(dt);
2329 /* a function is implicitely a function pointer */
2330 if (sbt == VT_FUNC) {
2331 if ((type1->t & VT_BTYPE) != VT_VOID &&
2332 !is_compatible_types(pointed_type(dt), st))
2333 tcc_warning("assignment from incompatible pointer type");
2334 goto type_ok;
2336 if (sbt != VT_PTR)
2337 goto error;
2338 type2 = pointed_type(st);
2339 if ((type1->t & VT_BTYPE) == VT_VOID ||
2340 (type2->t & VT_BTYPE) == VT_VOID) {
2341 /* void * can match anything */
2342 } else {
2343 /* exact type match, except for unsigned */
2344 tmp_type1 = *type1;
2345 tmp_type2 = *type2;
2346 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2347 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2348 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2349 tcc_warning("assignment from incompatible pointer type");
2351 /* check const and volatile */
2352 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2353 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2354 tcc_warning("assignment discards qualifiers from pointer target type");
2355 break;
2356 case VT_BYTE:
2357 case VT_SHORT:
2358 case VT_INT:
2359 case VT_LLONG:
2360 if (sbt == VT_PTR || sbt == VT_FUNC) {
2361 tcc_warning("assignment makes integer from pointer without a cast");
2363 /* XXX: more tests */
2364 break;
2365 case VT_STRUCT:
2366 tmp_type1 = *dt;
2367 tmp_type2 = *st;
2368 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2369 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2370 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2371 error:
2372 type_to_str(buf1, sizeof(buf1), st, NULL);
2373 type_to_str(buf2, sizeof(buf2), dt, NULL);
2374 tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
2376 break;
2378 type_ok:
2379 gen_cast(dt);
2382 /* store vtop in lvalue pushed on stack */
2383 ST_FUNC void vstore(void)
2385 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2387 ft = vtop[-1].type.t;
2388 sbt = vtop->type.t & VT_BTYPE;
2389 dbt = ft & VT_BTYPE;
2390 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2391 (sbt == VT_INT && dbt == VT_SHORT))
2392 && !(vtop->type.t & VT_BITFIELD)) {
2393 /* optimize char/short casts */
2394 delayed_cast = VT_MUSTCAST;
2395 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2396 /* XXX: factorize */
2397 if (ft & VT_CONSTANT)
2398 tcc_warning("assignment of read-only location");
2399 } else {
2400 delayed_cast = 0;
2401 if (!(ft & VT_BITFIELD))
2402 gen_assign_cast(&vtop[-1].type);
2405 if (sbt == VT_STRUCT) {
2406 /* if structure, only generate pointer */
2407 /* structure assignment : generate memcpy */
2408 /* XXX: optimize if small size */
2409 if (!nocode_wanted) {
2410 size = type_size(&vtop->type, &align);
2412 /* destination */
2413 vswap();
2414 vtop->type.t = VT_PTR;
2415 gaddrof();
2417 /* address of memcpy() */
2418 #ifdef TCC_ARM_EABI
2419 if(!(align & 7))
2420 vpush_global_sym(&func_old_type, TOK_memcpy8);
2421 else if(!(align & 3))
2422 vpush_global_sym(&func_old_type, TOK_memcpy4);
2423 else
2424 #endif
2425 vpush_global_sym(&func_old_type, TOK_memcpy);
2427 vswap();
2428 /* source */
2429 vpushv(vtop - 2);
2430 vtop->type.t = VT_PTR;
2431 gaddrof();
2432 /* type size */
2433 vpushi(size);
2434 gfunc_call(3);
2435 } else {
2436 vswap();
2437 vpop();
2439 /* leave source on stack */
2440 } else if (ft & VT_BITFIELD) {
2441 /* bitfield store handling */
2442 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2443 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2444 /* remove bit field info to avoid loops */
2445 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2447 /* duplicate source into other register */
2448 gv_dup();
2449 vswap();
2450 vrott(3);
2452 if((ft & VT_BTYPE) == VT_BOOL) {
2453 gen_cast(&vtop[-1].type);
2454 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2457 /* duplicate destination */
2458 vdup();
2459 vtop[-1] = vtop[-2];
2461 /* mask and shift source */
2462 if((ft & VT_BTYPE) != VT_BOOL) {
2463 if((ft & VT_BTYPE) == VT_LLONG) {
2464 vpushll((1ULL << bit_size) - 1ULL);
2465 } else {
2466 vpushi((1 << bit_size) - 1);
2468 gen_op('&');
2470 vpushi(bit_pos);
2471 gen_op(TOK_SHL);
2472 /* load destination, mask and or with source */
2473 vswap();
2474 if((ft & VT_BTYPE) == VT_LLONG) {
2475 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2476 } else {
2477 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2479 gen_op('&');
2480 gen_op('|');
2481 /* store result */
2482 vstore();
2484 /* pop off shifted source from "duplicate source..." above */
2485 vpop();
2487 } else {
2488 #ifdef CONFIG_TCC_BCHECK
2489 /* bound check case */
2490 if (vtop[-1].r & VT_MUSTBOUND) {
2491 vswap();
2492 gbound();
2493 vswap();
2495 #endif
2496 if (!nocode_wanted) {
2497 rc = RC_INT;
2498 if (is_float(ft)) {
2499 rc = RC_FLOAT;
2500 #ifdef TCC_TARGET_X86_64
2501 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2502 rc = RC_ST0;
2503 } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
2504 rc = RC_FRET;
2506 #endif
2508 r = gv(rc); /* generate value */
2509 /* if lvalue was saved on stack, must read it */
2510 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2511 SValue sv;
2512 t = get_reg(RC_INT);
2513 #ifdef TCC_TARGET_X86_64
2514 sv.type.t = VT_PTR;
2515 #else
2516 sv.type.t = VT_INT;
2517 #endif
2518 sv.r = VT_LOCAL | VT_LVAL;
2519 sv.c.ul = vtop[-1].c.ul;
2520 load(t, &sv);
2521 vtop[-1].r = t | VT_LVAL;
2523 /* two word case handling : store second register at word + 4 (or +8 for x86-64) */
2524 #ifdef TCC_TARGET_X86_64
2525 if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
2526 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
2527 #else
2528 if ((ft & VT_BTYPE) == VT_LLONG) {
2529 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
2530 #endif
2531 vtop[-1].type.t = load_type;
2532 store(r, vtop - 1);
2533 vswap();
2534 /* convert to int to increment easily */
2535 vtop->type.t = addr_type;
2536 gaddrof();
2537 vpushi(load_size);
2538 gen_op('+');
2539 vtop->r |= VT_LVAL;
2540 vswap();
2541 vtop[-1].type.t = load_type;
2542 /* XXX: it works because r2 is spilled last ! */
2543 store(vtop->r2, vtop - 1);
2544 } else {
2545 store(r, vtop - 1);
2548 vswap();
2549 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2550 vtop->r |= delayed_cast;
2554 /* post defines POST/PRE add. c is the token ++ or -- */
2555 ST_FUNC void inc(int post, int c)
2557 test_lvalue();
2558 vdup(); /* save lvalue */
2559 if (post) {
2560 gv_dup(); /* duplicate value */
2561 vrotb(3);
2562 vrotb(3);
2564 /* add constant */
2565 vpushi(c - TOK_MID);
2566 gen_op('+');
2567 vstore(); /* store value */
2568 if (post)
2569 vpop(); /* if post op, return saved value */
2572 /* Parse GNUC __attribute__ extension. Currently, the following
2573 extensions are recognized:
2574 - aligned(n) : set data/function alignment.
2575 - packed : force data alignment to 1
2576 - section(x) : generate data/code in this section.
2577 - unused : currently ignored, but may be used someday.
2578 - regparm(n) : pass function parameters in registers (i386 only)
2580 static void parse_attribute(AttributeDef *ad)
2582 int t, n;
2584 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2585 next();
2586 skip('(');
2587 skip('(');
2588 while (tok != ')') {
2589 if (tok < TOK_IDENT)
2590 expect("attribute name");
2591 t = tok;
2592 next();
2593 switch(t) {
2594 case TOK_SECTION1:
2595 case TOK_SECTION2:
2596 skip('(');
2597 if (tok != TOK_STR)
2598 expect("section name");
2599 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2600 next();
2601 skip(')');
2602 break;
2603 case TOK_ALIAS1:
2604 case TOK_ALIAS2:
2605 skip('(');
2606 if (tok != TOK_STR)
2607 expect("alias(\"target\")");
2608 ad->alias_target = /* save string as token, for later */
2609 tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
2610 next();
2611 skip(')');
2612 break;
2613 case TOK_ALIGNED1:
2614 case TOK_ALIGNED2:
2615 if (tok == '(') {
2616 next();
2617 n = expr_const();
2618 if (n <= 0 || (n & (n - 1)) != 0)
2619 tcc_error("alignment must be a positive power of two");
2620 skip(')');
2621 } else {
2622 n = MAX_ALIGN;
2624 ad->aligned = n;
2625 break;
2626 case TOK_PACKED1:
2627 case TOK_PACKED2:
2628 ad->packed = 1;
2629 break;
2630 case TOK_WEAK1:
2631 case TOK_WEAK2:
2632 ad->weak = 1;
2633 break;
2634 case TOK_UNUSED1:
2635 case TOK_UNUSED2:
2636 /* currently, no need to handle it because tcc does not
2637 track unused objects */
2638 break;
2639 case TOK_NORETURN1:
2640 case TOK_NORETURN2:
2641 /* currently, no need to handle it because tcc does not
2642 track unused objects */
2643 break;
2644 case TOK_CDECL1:
2645 case TOK_CDECL2:
2646 case TOK_CDECL3:
2647 ad->func_call = FUNC_CDECL;
2648 break;
2649 case TOK_STDCALL1:
2650 case TOK_STDCALL2:
2651 case TOK_STDCALL3:
2652 ad->func_call = FUNC_STDCALL;
2653 break;
2654 #ifdef TCC_TARGET_I386
2655 case TOK_REGPARM1:
2656 case TOK_REGPARM2:
2657 skip('(');
2658 n = expr_const();
2659 if (n > 3)
2660 n = 3;
2661 else if (n < 0)
2662 n = 0;
2663 if (n > 0)
2664 ad->func_call = FUNC_FASTCALL1 + n - 1;
2665 skip(')');
2666 break;
2667 case TOK_FASTCALL1:
2668 case TOK_FASTCALL2:
2669 case TOK_FASTCALL3:
2670 ad->func_call = FUNC_FASTCALLW;
2671 break;
2672 #endif
2673 case TOK_MODE:
2674 skip('(');
2675 switch(tok) {
2676 case TOK_MODE_DI:
2677 ad->mode = VT_LLONG + 1;
2678 break;
2679 case TOK_MODE_HI:
2680 ad->mode = VT_SHORT + 1;
2681 break;
2682 case TOK_MODE_SI:
2683 ad->mode = VT_INT + 1;
2684 break;
2685 default:
2686 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2687 break;
2689 next();
2690 skip(')');
2691 break;
2692 case TOK_DLLEXPORT:
2693 ad->func_export = 1;
2694 break;
2695 case TOK_DLLIMPORT:
2696 ad->func_import = 1;
2697 break;
2698 default:
2699 if (tcc_state->warn_unsupported)
2700 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
2701 /* skip parameters */
2702 if (tok == '(') {
2703 int parenthesis = 0;
2704 do {
2705 if (tok == '(')
2706 parenthesis++;
2707 else if (tok == ')')
2708 parenthesis--;
2709 next();
2710 } while (parenthesis && tok != -1);
2712 break;
2714 if (tok != ',')
2715 break;
2716 next();
2718 skip(')');
2719 skip(')');
2723 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2724 static void struct_decl(CType *type, int u)
2726 int a, v, size, align, maxalign, c, offset;
2727 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2728 Sym *s, *ss, *ass, **ps;
2729 AttributeDef ad;
2730 CType type1, btype;
2732 a = tok; /* save decl type */
2733 next();
2734 if (tok != '{') {
2735 v = tok;
2736 next();
2737 /* struct already defined ? return it */
2738 if (v < TOK_IDENT)
2739 expect("struct/union/enum name");
2740 s = struct_find(v);
2741 if (s) {
2742 if (s->type.t != a)
2743 tcc_error("invalid type");
2744 goto do_decl;
2746 } else {
2747 v = anon_sym++;
2749 type1.t = a;
2750 /* we put an undefined size for struct/union */
2751 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2752 s->r = 0; /* default alignment is zero as gcc */
2753 /* put struct/union/enum name in type */
2754 do_decl:
2755 type->t = u;
2756 type->ref = s;
2758 if (tok == '{') {
2759 next();
2760 if (s->c != -1)
2761 tcc_error("struct/union/enum already defined");
2762 /* cannot be empty */
2763 c = 0;
2764 /* non empty enums are not allowed */
2765 if (a == TOK_ENUM) {
2766 for(;;) {
2767 v = tok;
2768 if (v < TOK_UIDENT)
2769 expect("identifier");
2770 next();
2771 if (tok == '=') {
2772 next();
2773 c = expr_const();
2775 /* enum symbols have static storage */
2776 ss = sym_push(v, &int_type, VT_CONST, c);
2777 ss->type.t |= VT_STATIC;
2778 if (tok != ',')
2779 break;
2780 next();
2781 c++;
2782 /* NOTE: we accept a trailing comma */
2783 if (tok == '}')
2784 break;
2786 skip('}');
2787 } else {
2788 maxalign = 1;
2789 ps = &s->next;
2790 prevbt = VT_INT;
2791 bit_pos = 0;
2792 offset = 0;
2793 while (tok != '}') {
2794 parse_btype(&btype, &ad);
2795 while (1) {
2796 bit_size = -1;
2797 v = 0;
2798 type1 = btype;
2799 if (tok != ':') {
2800 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2801 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2802 expect("identifier");
2803 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2804 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2805 tcc_error("invalid type for '%s'",
2806 get_tok_str(v, NULL));
2808 if (tok == ':') {
2809 next();
2810 bit_size = expr_const();
2811 /* XXX: handle v = 0 case for messages */
2812 if (bit_size < 0)
2813 tcc_error("negative width in bit-field '%s'",
2814 get_tok_str(v, NULL));
2815 if (v && bit_size == 0)
2816 tcc_error("zero width for bit-field '%s'",
2817 get_tok_str(v, NULL));
2819 size = type_size(&type1, &align);
2820 if (ad.aligned) {
2821 if (align < ad.aligned)
2822 align = ad.aligned;
2823 } else if (ad.packed) {
2824 align = 1;
2825 } else if (*tcc_state->pack_stack_ptr) {
2826 if (align > *tcc_state->pack_stack_ptr)
2827 align = *tcc_state->pack_stack_ptr;
2829 lbit_pos = 0;
2830 if (bit_size >= 0) {
2831 bt = type1.t & VT_BTYPE;
2832 if (bt != VT_INT &&
2833 bt != VT_BYTE &&
2834 bt != VT_SHORT &&
2835 bt != VT_BOOL &&
2836 bt != VT_ENUM &&
2837 bt != VT_LLONG)
2838 tcc_error("bitfields must have scalar type");
2839 bsize = size * 8;
2840 if (bit_size > bsize) {
2841 tcc_error("width of '%s' exceeds its type",
2842 get_tok_str(v, NULL));
2843 } else if (bit_size == bsize) {
2844 /* no need for bit fields */
2845 bit_pos = 0;
2846 } else if (bit_size == 0) {
2847 /* XXX: what to do if only padding in a
2848 structure ? */
2849 /* zero size: means to pad */
2850 bit_pos = 0;
2851 } else {
2852 /* we do not have enough room ?
2853 did the type change?
2854 is it a union? */
2855 if ((bit_pos + bit_size) > bsize ||
2856 bt != prevbt || a == TOK_UNION)
2857 bit_pos = 0;
2858 lbit_pos = bit_pos;
2859 /* XXX: handle LSB first */
2860 type1.t |= VT_BITFIELD |
2861 (bit_pos << VT_STRUCT_SHIFT) |
2862 (bit_size << (VT_STRUCT_SHIFT + 6));
2863 bit_pos += bit_size;
2865 prevbt = bt;
2866 } else {
2867 bit_pos = 0;
2869 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
2870 /* add new memory data only if starting
2871 bit field */
2872 if (lbit_pos == 0) {
2873 if (a == TOK_STRUCT) {
2874 c = (c + align - 1) & -align;
2875 offset = c;
2876 if (size > 0)
2877 c += size;
2878 } else {
2879 offset = 0;
2880 if (size > c)
2881 c = size;
2883 if (align > maxalign)
2884 maxalign = align;
2886 #if 0
2887 printf("add field %s offset=%d",
2888 get_tok_str(v, NULL), offset);
2889 if (type1.t & VT_BITFIELD) {
2890 printf(" pos=%d size=%d",
2891 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
2892 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2894 printf("\n");
2895 #endif
2897 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
2898 ass = type1.ref;
2899 while ((ass = ass->next) != NULL) {
2900 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
2901 *ps = ss;
2902 ps = &ss->next;
2904 } else if (v) {
2905 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
2906 *ps = ss;
2907 ps = &ss->next;
2909 if (tok == ';' || tok == TOK_EOF)
2910 break;
2911 skip(',');
2913 skip(';');
2915 skip('}');
2916 /* store size and alignment */
2917 s->c = (c + maxalign - 1) & -maxalign;
2918 s->r = maxalign;
2923 /* return 0 if no type declaration. otherwise, return the basic type
2924 and skip it.
2926 static int parse_btype(CType *type, AttributeDef *ad)
2928 int t, u, type_found, typespec_found, typedef_found;
2929 Sym *s;
2930 CType type1;
2932 memset(ad, 0, sizeof(AttributeDef));
2933 type_found = 0;
2934 typespec_found = 0;
2935 typedef_found = 0;
2936 t = 0;
2937 while(1) {
2938 switch(tok) {
2939 case TOK_EXTENSION:
2940 /* currently, we really ignore extension */
2941 next();
2942 continue;
2944 /* basic types */
2945 case TOK_CHAR:
2946 u = VT_BYTE;
2947 basic_type:
2948 next();
2949 basic_type1:
2950 if ((t & VT_BTYPE) != 0)
2951 tcc_error("too many basic types");
2952 t |= u;
2953 typespec_found = 1;
2954 break;
2955 case TOK_VOID:
2956 u = VT_VOID;
2957 goto basic_type;
2958 case TOK_SHORT:
2959 u = VT_SHORT;
2960 goto basic_type;
2961 case TOK_INT:
2962 next();
2963 typespec_found = 1;
2964 break;
2965 case TOK_LONG:
2966 next();
2967 if ((t & VT_BTYPE) == VT_DOUBLE) {
2968 #ifndef TCC_TARGET_PE
2969 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2970 #endif
2971 } else if ((t & VT_BTYPE) == VT_LONG) {
2972 t = (t & ~VT_BTYPE) | VT_LLONG;
2973 } else {
2974 u = VT_LONG;
2975 goto basic_type1;
2977 break;
2978 case TOK_BOOL:
2979 u = VT_BOOL;
2980 goto basic_type;
2981 case TOK_FLOAT:
2982 u = VT_FLOAT;
2983 goto basic_type;
2984 case TOK_DOUBLE:
2985 next();
2986 if ((t & VT_BTYPE) == VT_LONG) {
2987 #ifdef TCC_TARGET_PE
2988 t = (t & ~VT_BTYPE) | VT_DOUBLE;
2989 #else
2990 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2991 #endif
2992 } else {
2993 u = VT_DOUBLE;
2994 goto basic_type1;
2996 break;
2997 case TOK_ENUM:
2998 struct_decl(&type1, VT_ENUM);
2999 basic_type2:
3000 u = type1.t;
3001 type->ref = type1.ref;
3002 goto basic_type1;
3003 case TOK_STRUCT:
3004 case TOK_UNION:
3005 struct_decl(&type1, VT_STRUCT);
3006 goto basic_type2;
3008 /* type modifiers */
3009 case TOK_CONST1:
3010 case TOK_CONST2:
3011 case TOK_CONST3:
3012 t |= VT_CONSTANT;
3013 next();
3014 break;
3015 case TOK_VOLATILE1:
3016 case TOK_VOLATILE2:
3017 case TOK_VOLATILE3:
3018 t |= VT_VOLATILE;
3019 next();
3020 break;
3021 case TOK_SIGNED1:
3022 case TOK_SIGNED2:
3023 case TOK_SIGNED3:
3024 typespec_found = 1;
3025 t |= VT_SIGNED;
3026 next();
3027 break;
3028 case TOK_REGISTER:
3029 case TOK_AUTO:
3030 case TOK_RESTRICT1:
3031 case TOK_RESTRICT2:
3032 case TOK_RESTRICT3:
3033 next();
3034 break;
3035 case TOK_UNSIGNED:
3036 t |= VT_UNSIGNED;
3037 next();
3038 typespec_found = 1;
3039 break;
3041 /* storage */
3042 case TOK_EXTERN:
3043 t |= VT_EXTERN;
3044 next();
3045 break;
3046 case TOK_STATIC:
3047 t |= VT_STATIC;
3048 next();
3049 break;
3050 case TOK_TYPEDEF:
3051 t |= VT_TYPEDEF;
3052 next();
3053 break;
3054 case TOK_INLINE1:
3055 case TOK_INLINE2:
3056 case TOK_INLINE3:
3057 t |= VT_INLINE;
3058 next();
3059 break;
3061 /* GNUC attribute */
3062 case TOK_ATTRIBUTE1:
3063 case TOK_ATTRIBUTE2:
3064 parse_attribute(ad);
3065 if (ad->mode) {
3066 u = ad->mode -1;
3067 t = (t & ~VT_BTYPE) | u;
3069 break;
3070 /* GNUC typeof */
3071 case TOK_TYPEOF1:
3072 case TOK_TYPEOF2:
3073 case TOK_TYPEOF3:
3074 next();
3075 parse_expr_type(&type1);
3076 /* remove all storage modifiers except typedef */
3077 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
3078 goto basic_type2;
3079 default:
3080 if (typespec_found || typedef_found)
3081 goto the_end;
3082 s = sym_find(tok);
3083 if (!s || !(s->type.t & VT_TYPEDEF))
3084 goto the_end;
3085 typedef_found = 1;
3086 t |= (s->type.t & ~VT_TYPEDEF);
3087 type->ref = s->type.ref;
3088 if (s->r) {
3089 /* get attributes from typedef */
3090 if (0 == ad->aligned)
3091 ad->aligned = FUNC_ALIGN(s->r);
3092 if (0 == ad->func_call)
3093 ad->func_call = FUNC_CALL(s->r);
3094 ad->packed |= FUNC_PACKED(s->r);
3096 next();
3097 typespec_found = 1;
3098 break;
3100 type_found = 1;
3102 the_end:
3103 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
3104 tcc_error("signed and unsigned modifier");
3105 if (tcc_state->char_is_unsigned) {
3106 if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
3107 t |= VT_UNSIGNED;
3109 t &= ~VT_SIGNED;
3111 /* long is never used as type */
3112 if ((t & VT_BTYPE) == VT_LONG)
3113 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
3114 t = (t & ~VT_BTYPE) | VT_INT;
3115 #else
3116 t = (t & ~VT_BTYPE) | VT_LLONG;
3117 #endif
3118 type->t = t;
3119 return type_found;
3122 /* convert a function parameter type (array to pointer and function to
3123 function pointer) */
3124 static inline void convert_parameter_type(CType *pt)
3126 /* remove const and volatile qualifiers (XXX: const could be used
3127 to indicate a const function parameter */
3128 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3129 /* array must be transformed to pointer according to ANSI C */
3130 pt->t &= ~VT_ARRAY;
3131 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3132 mk_pointer(pt);
3136 ST_FUNC void parse_asm_str(CString *astr)
3138 skip('(');
3139 /* read the string */
3140 if (tok != TOK_STR)
3141 expect("string constant");
3142 cstr_new(astr);
3143 while (tok == TOK_STR) {
3144 /* XXX: add \0 handling too ? */
3145 cstr_cat(astr, tokc.cstr->data);
3146 next();
3148 cstr_ccat(astr, '\0');
3151 /* Parse an asm label and return the label
3152 * Don't forget to free the CString in the caller! */
3153 static void asm_label_instr(CString *astr)
3155 next();
3156 parse_asm_str(astr);
3157 skip(')');
3158 #ifdef ASM_DEBUG
3159 printf("asm_alias: \"%s\"\n", (char *)astr->data);
3160 #endif
3163 static void post_type(CType *type, AttributeDef *ad)
3165 int n, l, t1, arg_size, align;
3166 Sym **plast, *s, *first;
3167 AttributeDef ad1;
3168 CType pt;
3170 if (tok == '(') {
3171 /* function declaration */
3172 next();
3173 l = 0;
3174 first = NULL;
3175 plast = &first;
3176 arg_size = 0;
3177 if (tok != ')') {
3178 for(;;) {
3179 /* read param name and compute offset */
3180 if (l != FUNC_OLD) {
3181 if (!parse_btype(&pt, &ad1)) {
3182 if (l) {
3183 tcc_error("invalid type");
3184 } else {
3185 l = FUNC_OLD;
3186 goto old_proto;
3189 l = FUNC_NEW;
3190 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3191 break;
3192 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3193 if ((pt.t & VT_BTYPE) == VT_VOID)
3194 tcc_error("parameter declared as void");
3195 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3196 } else {
3197 old_proto:
3198 n = tok;
3199 if (n < TOK_UIDENT)
3200 expect("identifier");
3201 pt.t = VT_INT;
3202 next();
3204 convert_parameter_type(&pt);
3205 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3206 *plast = s;
3207 plast = &s->next;
3208 if (tok == ')')
3209 break;
3210 skip(',');
3211 if (l == FUNC_NEW && tok == TOK_DOTS) {
3212 l = FUNC_ELLIPSIS;
3213 next();
3214 break;
3218 /* if no parameters, then old type prototype */
3219 if (l == 0)
3220 l = FUNC_OLD;
3221 skip(')');
3222 /* NOTE: const is ignored in returned type as it has a special
3223 meaning in gcc / C++ */
3224 type->t &= ~VT_CONSTANT;
3225 /* some ancient pre-K&R C allows a function to return an array
3226 and the array brackets to be put after the arguments, such
3227 that "int c()[]" means something like "int[] c()" */
3228 if (tok == '[') {
3229 next();
3230 skip(']'); /* only handle simple "[]" */
3231 type->t |= VT_PTR;
3233 /* we push a anonymous symbol which will contain the function prototype */
3234 ad->func_args = arg_size;
3235 s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
3236 s->next = first;
3237 type->t = VT_FUNC;
3238 type->ref = s;
3239 } else if (tok == '[') {
3240 /* array definition */
3241 next();
3242 if (tok == TOK_RESTRICT1)
3243 next();
3244 n = -1;
3245 t1 = 0;
3246 if (tok != ']') {
3247 if (!local_stack || nocode_wanted)
3248 vpushi(expr_const());
3249 else gexpr();
3250 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3251 n = vtop->c.i;
3252 if (n < 0)
3253 tcc_error("invalid array size");
3254 } else {
3255 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3256 tcc_error("size of variable length array should be an integer");
3257 t1 = VT_VLA;
3260 skip(']');
3261 /* parse next post type */
3262 post_type(type, ad);
3263 t1 |= type->t & VT_VLA;
3265 if (t1 & VT_VLA) {
3266 loc -= type_size(&int_type, &align);
3267 loc &= -align;
3268 n = loc;
3270 vla_runtime_type_size(type, &align);
3271 gen_op('*');
3272 vset(&int_type, VT_LOCAL|VT_LVAL, loc);
3273 vswap();
3274 vstore();
3276 if (n != -1)
3277 vpop();
3279 /* we push an anonymous symbol which will contain the array
3280 element type */
3281 s = sym_push(SYM_FIELD, type, 0, n);
3282 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3283 type->ref = s;
3287 /* Parse a type declaration (except basic type), and return the type
3288 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3289 expected. 'type' should contain the basic type. 'ad' is the
3290 attribute definition of the basic type. It can be modified by
3291 type_decl().
3293 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3295 Sym *s;
3296 CType type1, *type2;
3297 int qualifiers, storage;
3299 while (tok == '*') {
3300 qualifiers = 0;
3301 redo:
3302 next();
3303 switch(tok) {
3304 case TOK_CONST1:
3305 case TOK_CONST2:
3306 case TOK_CONST3:
3307 qualifiers |= VT_CONSTANT;
3308 goto redo;
3309 case TOK_VOLATILE1:
3310 case TOK_VOLATILE2:
3311 case TOK_VOLATILE3:
3312 qualifiers |= VT_VOLATILE;
3313 goto redo;
3314 case TOK_RESTRICT1:
3315 case TOK_RESTRICT2:
3316 case TOK_RESTRICT3:
3317 goto redo;
3319 mk_pointer(type);
3320 type->t |= qualifiers;
3323 /* XXX: clarify attribute handling */
3324 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3325 parse_attribute(ad);
3327 /* recursive type */
3328 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3329 type1.t = 0; /* XXX: same as int */
3330 if (tok == '(') {
3331 next();
3332 /* XXX: this is not correct to modify 'ad' at this point, but
3333 the syntax is not clear */
3334 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3335 parse_attribute(ad);
3336 type_decl(&type1, ad, v, td);
3337 skip(')');
3338 } else {
3339 /* type identifier */
3340 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3341 *v = tok;
3342 next();
3343 } else {
3344 if (!(td & TYPE_ABSTRACT))
3345 expect("identifier");
3346 *v = 0;
3349 storage = type->t & VT_STORAGE;
3350 type->t &= ~VT_STORAGE;
3351 if (storage & VT_STATIC) {
3352 int saved_nocode_wanted = nocode_wanted;
3353 nocode_wanted = 1;
3354 post_type(type, ad);
3355 nocode_wanted = saved_nocode_wanted;
3356 } else
3357 post_type(type, ad);
3358 type->t |= storage;
3359 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3360 parse_attribute(ad);
3362 if (!type1.t)
3363 return;
3364 /* append type at the end of type1 */
3365 type2 = &type1;
3366 for(;;) {
3367 s = type2->ref;
3368 type2 = &s->type;
3369 if (!type2->t) {
3370 *type2 = *type;
3371 break;
3374 *type = type1;
3377 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3378 ST_FUNC int lvalue_type(int t)
3380 int bt, r;
3381 r = VT_LVAL;
3382 bt = t & VT_BTYPE;
3383 if (bt == VT_BYTE || bt == VT_BOOL)
3384 r |= VT_LVAL_BYTE;
3385 else if (bt == VT_SHORT)
3386 r |= VT_LVAL_SHORT;
3387 else
3388 return r;
3389 if (t & VT_UNSIGNED)
3390 r |= VT_LVAL_UNSIGNED;
3391 return r;
3394 /* indirection with full error checking and bound check */
3395 ST_FUNC void indir(void)
3397 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3398 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3399 return;
3400 expect("pointer");
3402 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3403 gv(RC_INT);
3404 vtop->type = *pointed_type(&vtop->type);
3405 /* Arrays and functions are never lvalues */
3406 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3407 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3408 vtop->r |= lvalue_type(vtop->type.t);
3409 /* if bound checking, the referenced pointer must be checked */
3410 #ifdef CONFIG_TCC_BCHECK
3411 if (tcc_state->do_bounds_check)
3412 vtop->r |= VT_MUSTBOUND;
3413 #endif
3417 /* pass a parameter to a function and do type checking and casting */
3418 static void gfunc_param_typed(Sym *func, Sym *arg)
3420 int func_type;
3421 CType type;
3423 func_type = func->c;
3424 if (func_type == FUNC_OLD ||
3425 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3426 /* default casting : only need to convert float to double */
3427 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3428 type.t = VT_DOUBLE;
3429 gen_cast(&type);
3431 } else if (arg == NULL) {
3432 tcc_error("too many arguments to function");
3433 } else {
3434 type = arg->type;
3435 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3436 gen_assign_cast(&type);
3440 /* parse an expression of the form '(type)' or '(expr)' and return its
3441 type */
3442 static void parse_expr_type(CType *type)
3444 int n;
3445 AttributeDef ad;
3447 skip('(');
3448 if (parse_btype(type, &ad)) {
3449 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3450 } else {
3451 expr_type(type);
3453 skip(')');
3456 static void parse_type(CType *type)
3458 AttributeDef ad;
3459 int n;
3461 if (!parse_btype(type, &ad)) {
3462 expect("type");
3464 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3467 static void vpush_tokc(int t)
3469 CType type;
3470 type.t = t;
3471 type.ref = 0;
3472 vsetc(&type, VT_CONST, &tokc);
3475 ST_FUNC void unary(void)
3477 int n, t, align, size, r, sizeof_caller;
3478 CType type;
3479 Sym *s;
3480 AttributeDef ad;
3481 static int in_sizeof = 0;
3483 sizeof_caller = in_sizeof;
3484 in_sizeof = 0;
3485 /* XXX: GCC 2.95.3 does not generate a table although it should be
3486 better here */
3487 tok_next:
3488 switch(tok) {
3489 case TOK_EXTENSION:
3490 next();
3491 goto tok_next;
3492 case TOK_CINT:
3493 case TOK_CCHAR:
3494 case TOK_LCHAR:
3495 vpushi(tokc.i);
3496 next();
3497 break;
3498 case TOK_CUINT:
3499 vpush_tokc(VT_INT | VT_UNSIGNED);
3500 next();
3501 break;
3502 case TOK_CLLONG:
3503 vpush_tokc(VT_LLONG);
3504 next();
3505 break;
3506 case TOK_CULLONG:
3507 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3508 next();
3509 break;
3510 case TOK_CFLOAT:
3511 vpush_tokc(VT_FLOAT);
3512 next();
3513 break;
3514 case TOK_CDOUBLE:
3515 vpush_tokc(VT_DOUBLE);
3516 next();
3517 break;
3518 case TOK_CLDOUBLE:
3519 vpush_tokc(VT_LDOUBLE);
3520 next();
3521 break;
3522 case TOK___FUNCTION__:
3523 if (!gnu_ext)
3524 goto tok_identifier;
3525 /* fall thru */
3526 case TOK___FUNC__:
3528 void *ptr;
3529 int len;
3530 /* special function name identifier */
3531 len = strlen(funcname) + 1;
3532 /* generate char[len] type */
3533 type.t = VT_BYTE;
3534 mk_pointer(&type);
3535 type.t |= VT_ARRAY;
3536 type.ref->c = len;
3537 vpush_ref(&type, data_section, data_section->data_offset, len);
3538 ptr = section_ptr_add(data_section, len);
3539 memcpy(ptr, funcname, len);
3540 next();
3542 break;
3543 case TOK_LSTR:
3544 #ifdef TCC_TARGET_PE
3545 t = VT_SHORT | VT_UNSIGNED;
3546 #else
3547 t = VT_INT;
3548 #endif
3549 goto str_init;
3550 case TOK_STR:
3551 /* string parsing */
3552 t = VT_BYTE;
3553 str_init:
3554 if (tcc_state->warn_write_strings)
3555 t |= VT_CONSTANT;
3556 type.t = t;
3557 mk_pointer(&type);
3558 type.t |= VT_ARRAY;
3559 memset(&ad, 0, sizeof(AttributeDef));
3560 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
3561 break;
3562 case '(':
3563 next();
3564 /* cast ? */
3565 if (parse_btype(&type, &ad)) {
3566 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3567 skip(')');
3568 /* check ISOC99 compound literal */
3569 if (tok == '{') {
3570 /* data is allocated locally by default */
3571 if (global_expr)
3572 r = VT_CONST;
3573 else
3574 r = VT_LOCAL;
3575 /* all except arrays are lvalues */
3576 if (!(type.t & VT_ARRAY))
3577 r |= lvalue_type(type.t);
3578 memset(&ad, 0, sizeof(AttributeDef));
3579 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
3580 } else {
3581 if (sizeof_caller) {
3582 vpush(&type);
3583 return;
3585 unary();
3586 gen_cast(&type);
3588 } else if (tok == '{') {
3589 /* save all registers */
3590 save_regs(0);
3591 /* statement expression : we do not accept break/continue
3592 inside as GCC does */
3593 block(NULL, NULL, NULL, NULL, 0, 1);
3594 skip(')');
3595 } else {
3596 gexpr();
3597 skip(')');
3599 break;
3600 case '*':
3601 next();
3602 unary();
3603 indir();
3604 break;
3605 case '&':
3606 next();
3607 unary();
3608 /* functions names must be treated as function pointers,
3609 except for unary '&' and sizeof. Since we consider that
3610 functions are not lvalues, we only have to handle it
3611 there and in function calls. */
3612 /* arrays can also be used although they are not lvalues */
3613 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3614 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3615 test_lvalue();
3616 mk_pointer(&vtop->type);
3617 gaddrof();
3618 break;
3619 case '!':
3620 next();
3621 unary();
3622 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3623 CType boolean;
3624 boolean.t = VT_BOOL;
3625 gen_cast(&boolean);
3626 vtop->c.i = !vtop->c.i;
3627 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3628 vtop->c.i = vtop->c.i ^ 1;
3629 else {
3630 save_regs(1);
3631 vseti(VT_JMP, gtst(1, 0));
3633 break;
3634 case '~':
3635 next();
3636 unary();
3637 vpushi(-1);
3638 gen_op('^');
3639 break;
3640 case '+':
3641 next();
3642 /* in order to force cast, we add zero */
3643 unary();
3644 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3645 tcc_error("pointer not accepted for unary plus");
3646 vpushi(0);
3647 gen_op('+');
3648 break;
3649 case TOK_SIZEOF:
3650 case TOK_ALIGNOF1:
3651 case TOK_ALIGNOF2:
3652 t = tok;
3653 next();
3654 in_sizeof++;
3655 unary_type(&type); // Perform a in_sizeof = 0;
3656 size = type_size(&type, &align);
3657 if (t == TOK_SIZEOF) {
3658 if (!(type.t & VT_VLA)) {
3659 if (size < 0)
3660 tcc_error("sizeof applied to an incomplete type");
3661 vpushs(size);
3662 } else {
3663 vla_runtime_type_size(&type, &align);
3665 } else {
3666 vpushs(align);
3668 vtop->type.t |= VT_UNSIGNED;
3669 break;
3671 case TOK_builtin_types_compatible_p:
3673 CType type1, type2;
3674 next();
3675 skip('(');
3676 parse_type(&type1);
3677 skip(',');
3678 parse_type(&type2);
3679 skip(')');
3680 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3681 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3682 vpushi(is_compatible_types(&type1, &type2));
3684 break;
3685 case TOK_builtin_constant_p:
3687 int saved_nocode_wanted, res;
3688 next();
3689 skip('(');
3690 saved_nocode_wanted = nocode_wanted;
3691 nocode_wanted = 1;
3692 gexpr();
3693 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3694 vpop();
3695 nocode_wanted = saved_nocode_wanted;
3696 skip(')');
3697 vpushi(res);
3699 break;
3700 case TOK_builtin_frame_address:
3702 int level;
3703 CType type;
3704 next();
3705 skip('(');
3706 if (tok != TOK_CINT || tokc.i < 0) {
3707 tcc_error("__builtin_frame_address only takes positive integers");
3709 level = tokc.i;
3710 next();
3711 skip(')');
3712 type.t = VT_VOID;
3713 mk_pointer(&type);
3714 vset(&type, VT_LOCAL, 0); /* local frame */
3715 while (level--) {
3716 mk_pointer(&vtop->type);
3717 indir(); /* -> parent frame */
3720 break;
3721 #ifdef TCC_TARGET_X86_64
3722 #ifdef TCC_TARGET_PE
3723 case TOK_builtin_va_start:
3725 next();
3726 skip('(');
3727 expr_eq();
3728 skip(',');
3729 expr_eq();
3730 skip(')');
3731 if ((vtop->r & VT_VALMASK) != VT_LOCAL)
3732 tcc_error("__builtin_va_start expects a local variable");
3733 vtop->r &= ~(VT_LVAL | VT_REF);
3734 vtop->type = char_pointer_type;
3735 vstore();
3737 break;
3738 #else
3739 case TOK_builtin_va_arg_types:
3741 CType type;
3742 int bt;
3743 next();
3744 skip('(');
3745 parse_type(&type);
3746 skip(')');
3747 vpushi(classify_x86_64_va_arg(&type));
3749 break;
3750 #endif
3751 #endif
3752 case TOK_INC:
3753 case TOK_DEC:
3754 t = tok;
3755 next();
3756 unary();
3757 inc(0, t);
3758 break;
3759 case '-':
3760 next();
3761 vpushi(0);
3762 unary();
3763 gen_op('-');
3764 break;
3765 case TOK_LAND:
3766 if (!gnu_ext)
3767 goto tok_identifier;
3768 next();
3769 /* allow to take the address of a label */
3770 if (tok < TOK_UIDENT)
3771 expect("label identifier");
3772 s = label_find(tok);
3773 if (!s) {
3774 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3775 } else {
3776 if (s->r == LABEL_DECLARED)
3777 s->r = LABEL_FORWARD;
3779 if (!s->type.t) {
3780 s->type.t = VT_VOID;
3781 mk_pointer(&s->type);
3782 s->type.t |= VT_STATIC;
3784 vset(&s->type, VT_CONST | VT_SYM, 0);
3785 vtop->sym = s;
3786 next();
3787 break;
3789 // special qnan , snan and infinity values
3790 case TOK___NAN__:
3791 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
3792 next();
3793 break;
3794 case TOK___SNAN__:
3795 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
3796 next();
3797 break;
3798 case TOK___INF__:
3799 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
3800 next();
3801 break;
3803 default:
3804 tok_identifier:
3805 t = tok;
3806 next();
3807 if (t < TOK_UIDENT)
3808 expect("identifier");
3809 s = sym_find(t);
3810 if (!s) {
3811 if (tok != '(')
3812 tcc_error("'%s' undeclared", get_tok_str(t, NULL));
3813 /* for simple function calls, we tolerate undeclared
3814 external reference to int() function */
3815 if (tcc_state->warn_implicit_function_declaration)
3816 tcc_warning("implicit declaration of function '%s'",
3817 get_tok_str(t, NULL));
3818 s = external_global_sym(t, &func_old_type, 0);
3820 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3821 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3822 /* if referencing an inline function, then we generate a
3823 symbol to it if not already done. It will have the
3824 effect to generate code for it at the end of the
3825 compilation unit. Inline function as always
3826 generated in the text section. */
3827 if (!s->c)
3828 put_extern_sym(s, text_section, 0, 0);
3829 r = VT_SYM | VT_CONST;
3830 } else {
3831 r = s->r;
3833 vset(&s->type, r, s->c);
3834 /* if forward reference, we must point to s */
3835 if (vtop->r & VT_SYM) {
3836 vtop->sym = s;
3837 vtop->c.ul = 0;
3839 break;
3842 /* post operations */
3843 while (1) {
3844 if (tok == TOK_INC || tok == TOK_DEC) {
3845 inc(1, tok);
3846 next();
3847 } else if (tok == '.' || tok == TOK_ARROW) {
3848 int qualifiers;
3849 /* field */
3850 if (tok == TOK_ARROW)
3851 indir();
3852 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3853 test_lvalue();
3854 gaddrof();
3855 next();
3856 /* expect pointer on structure */
3857 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3858 expect("struct or union");
3859 s = vtop->type.ref;
3860 /* find field */
3861 tok |= SYM_FIELD;
3862 while ((s = s->next) != NULL) {
3863 if (s->v == tok)
3864 break;
3866 if (!s)
3867 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
3868 /* add field offset to pointer */
3869 vtop->type = char_pointer_type; /* change type to 'char *' */
3870 vpushi(s->c);
3871 gen_op('+');
3872 /* change type to field type, and set to lvalue */
3873 vtop->type = s->type;
3874 vtop->type.t |= qualifiers;
3875 /* an array is never an lvalue */
3876 if (!(vtop->type.t & VT_ARRAY)) {
3877 vtop->r |= lvalue_type(vtop->type.t);
3878 #ifdef CONFIG_TCC_BCHECK
3879 /* if bound checking, the referenced pointer must be checked */
3880 if (tcc_state->do_bounds_check)
3881 vtop->r |= VT_MUSTBOUND;
3882 #endif
3884 next();
3885 } else if (tok == '[') {
3886 next();
3887 gexpr();
3888 gen_op('+');
3889 indir();
3890 skip(']');
3891 } else if (tok == '(') {
3892 SValue ret;
3893 Sym *sa;
3894 int nb_args, sret;
3896 /* function call */
3897 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3898 /* pointer test (no array accepted) */
3899 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3900 vtop->type = *pointed_type(&vtop->type);
3901 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3902 goto error_func;
3903 } else {
3904 error_func:
3905 expect("function pointer");
3907 } else {
3908 vtop->r &= ~VT_LVAL; /* no lvalue */
3910 /* get return type */
3911 s = vtop->type.ref;
3912 next();
3913 sa = s->next; /* first parameter */
3914 nb_args = 0;
3915 ret.r2 = VT_CONST;
3916 /* compute first implicit argument if a structure is returned */
3917 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3918 int ret_align;
3919 sret = gfunc_sret(&s->type, &ret.type, &ret_align);
3920 if (sret) {
3921 /* get some space for the returned structure */
3922 size = type_size(&s->type, &align);
3923 loc = (loc - size) & -align;
3924 ret.type = s->type;
3925 ret.r = VT_LOCAL | VT_LVAL;
3926 /* pass it as 'int' to avoid structure arg passing
3927 problems */
3928 vseti(VT_LOCAL, loc);
3929 ret.c = vtop->c;
3930 nb_args++;
3932 } else {
3933 sret = 0;
3934 ret.type = s->type;
3937 if (!sret) {
3938 /* return in register */
3939 if (is_float(ret.type.t)) {
3940 ret.r = reg_fret(ret.type.t);
3941 #ifdef TCC_TARGET_X86_64
3942 if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
3943 ret.r2 = REG_QRET;
3944 #endif
3945 } else {
3946 #ifdef TCC_TARGET_X86_64
3947 if ((ret.type.t & VT_BTYPE) == VT_QLONG)
3948 #else
3949 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
3950 #endif
3951 ret.r2 = REG_LRET;
3952 ret.r = REG_IRET;
3954 ret.c.i = 0;
3956 if (tok != ')') {
3957 for(;;) {
3958 expr_eq();
3959 gfunc_param_typed(s, sa);
3960 nb_args++;
3961 if (sa)
3962 sa = sa->next;
3963 if (tok == ')')
3964 break;
3965 skip(',');
3968 if (sa)
3969 tcc_error("too few arguments to function");
3970 skip(')');
3971 if (!nocode_wanted) {
3972 gfunc_call(nb_args);
3973 } else {
3974 vtop -= (nb_args + 1);
3976 /* return value */
3977 vsetc(&ret.type, ret.r, &ret.c);
3978 vtop->r2 = ret.r2;
3979 /* handle packed struct return */
3980 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && !sret) {
3981 size = type_size(&s->type, &align);
3982 loc = (loc - size) & -align;
3983 int addr = loc;
3984 vset(&ret.type, VT_LOCAL | VT_LVAL, addr);
3985 vswap();
3986 vstore();
3987 vtop--;
3988 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
3990 } else {
3991 break;
3996 ST_FUNC void expr_prod(void)
3998 int t;
4000 unary();
4001 while (tok == '*' || tok == '/' || tok == '%') {
4002 t = tok;
4003 next();
4004 unary();
4005 gen_op(t);
4009 ST_FUNC void expr_sum(void)
4011 int t;
4013 expr_prod();
4014 while (tok == '+' || tok == '-') {
4015 t = tok;
4016 next();
4017 expr_prod();
4018 gen_op(t);
4022 static void expr_shift(void)
4024 int t;
4026 expr_sum();
4027 while (tok == TOK_SHL || tok == TOK_SAR) {
4028 t = tok;
4029 next();
4030 expr_sum();
4031 gen_op(t);
4035 static void expr_cmp(void)
4037 int t;
4039 expr_shift();
4040 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
4041 tok == TOK_ULT || tok == TOK_UGE) {
4042 t = tok;
4043 next();
4044 expr_shift();
4045 gen_op(t);
4049 static void expr_cmpeq(void)
4051 int t;
4053 expr_cmp();
4054 while (tok == TOK_EQ || tok == TOK_NE) {
4055 t = tok;
4056 next();
4057 expr_cmp();
4058 gen_op(t);
4062 static void expr_and(void)
4064 expr_cmpeq();
4065 while (tok == '&') {
4066 next();
4067 expr_cmpeq();
4068 gen_op('&');
4072 static void expr_xor(void)
4074 expr_and();
4075 while (tok == '^') {
4076 next();
4077 expr_and();
4078 gen_op('^');
4082 static void expr_or(void)
4084 expr_xor();
4085 while (tok == '|') {
4086 next();
4087 expr_xor();
4088 gen_op('|');
4092 /* XXX: fix this mess */
4093 static void expr_land_const(void)
4095 expr_or();
4096 while (tok == TOK_LAND) {
4097 next();
4098 expr_or();
4099 gen_op(TOK_LAND);
4103 /* XXX: fix this mess */
4104 static void expr_lor_const(void)
4106 expr_land_const();
4107 while (tok == TOK_LOR) {
4108 next();
4109 expr_land_const();
4110 gen_op(TOK_LOR);
4114 /* only used if non constant */
4115 static void expr_land(void)
4117 int t;
4119 expr_or();
4120 if (tok == TOK_LAND) {
4121 t = 0;
4122 save_regs(1);
4123 for(;;) {
4124 t = gtst(1, t);
4125 if (tok != TOK_LAND) {
4126 vseti(VT_JMPI, t);
4127 break;
4129 next();
4130 expr_or();
4135 static void expr_lor(void)
4137 int t;
4139 expr_land();
4140 if (tok == TOK_LOR) {
4141 t = 0;
4142 save_regs(1);
4143 for(;;) {
4144 t = gtst(0, t);
4145 if (tok != TOK_LOR) {
4146 vseti(VT_JMP, t);
4147 break;
4149 next();
4150 expr_land();
4155 /* XXX: better constant handling */
4156 static void expr_cond(void)
4158 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
4159 SValue sv;
4160 CType type, type1, type2;
4162 if (const_wanted) {
4163 expr_lor_const();
4164 if (tok == '?') {
4165 CType boolean;
4166 int c;
4167 boolean.t = VT_BOOL;
4168 vdup();
4169 gen_cast(&boolean);
4170 c = vtop->c.i;
4171 vpop();
4172 next();
4173 if (tok != ':' || !gnu_ext) {
4174 vpop();
4175 gexpr();
4177 if (!c)
4178 vpop();
4179 skip(':');
4180 expr_cond();
4181 if (c)
4182 vpop();
4184 } else {
4185 expr_lor();
4186 if (tok == '?') {
4187 next();
4188 if (vtop != vstack) {
4189 /* needed to avoid having different registers saved in
4190 each branch */
4191 if (is_float(vtop->type.t)) {
4192 rc = RC_FLOAT;
4193 #ifdef TCC_TARGET_X86_64
4194 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4195 rc = RC_ST0;
4197 #endif
4199 else
4200 rc = RC_INT;
4201 gv(rc);
4202 save_regs(1);
4204 if (tok == ':' && gnu_ext) {
4205 gv_dup();
4206 tt = gtst(1, 0);
4207 } else {
4208 tt = gtst(1, 0);
4209 gexpr();
4211 type1 = vtop->type;
4212 sv = *vtop; /* save value to handle it later */
4213 vtop--; /* no vpop so that FP stack is not flushed */
4214 skip(':');
4215 u = gjmp(0);
4216 gsym(tt);
4217 expr_cond();
4218 type2 = vtop->type;
4220 t1 = type1.t;
4221 bt1 = t1 & VT_BTYPE;
4222 t2 = type2.t;
4223 bt2 = t2 & VT_BTYPE;
4224 /* cast operands to correct type according to ISOC rules */
4225 if (is_float(bt1) || is_float(bt2)) {
4226 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4227 type.t = VT_LDOUBLE;
4228 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4229 type.t = VT_DOUBLE;
4230 } else {
4231 type.t = VT_FLOAT;
4233 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4234 /* cast to biggest op */
4235 type.t = VT_LLONG;
4236 /* convert to unsigned if it does not fit in a long long */
4237 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4238 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4239 type.t |= VT_UNSIGNED;
4240 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4241 /* If one is a null ptr constant the result type
4242 is the other. */
4243 if (is_null_pointer (vtop))
4244 type = type1;
4245 else if (is_null_pointer (&sv))
4246 type = type2;
4247 /* XXX: test pointer compatibility, C99 has more elaborate
4248 rules here. */
4249 else
4250 type = type1;
4251 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4252 /* XXX: test function pointer compatibility */
4253 type = bt1 == VT_FUNC ? type1 : type2;
4254 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4255 /* XXX: test structure compatibility */
4256 type = bt1 == VT_STRUCT ? type1 : type2;
4257 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4258 /* NOTE: as an extension, we accept void on only one side */
4259 type.t = VT_VOID;
4260 } else {
4261 /* integer operations */
4262 type.t = VT_INT;
4263 /* convert to unsigned if it does not fit in an integer */
4264 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4265 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4266 type.t |= VT_UNSIGNED;
4269 /* now we convert second operand */
4270 gen_cast(&type);
4271 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4272 gaddrof();
4273 rc = RC_INT;
4274 if (is_float(type.t)) {
4275 rc = RC_FLOAT;
4276 #ifdef TCC_TARGET_X86_64
4277 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4278 rc = RC_ST0;
4280 #endif
4281 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4282 /* for long longs, we use fixed registers to avoid having
4283 to handle a complicated move */
4284 rc = RC_IRET;
4287 r2 = gv(rc);
4288 /* this is horrible, but we must also convert first
4289 operand */
4290 tt = gjmp(0);
4291 gsym(u);
4292 /* put again first value and cast it */
4293 *vtop = sv;
4294 gen_cast(&type);
4295 if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4296 gaddrof();
4297 r1 = gv(rc);
4298 move_reg(r2, r1, type.t);
4299 vtop->r = r2;
4300 gsym(tt);
4305 static void expr_eq(void)
4307 int t;
4309 expr_cond();
4310 if (tok == '=' ||
4311 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4312 tok == TOK_A_XOR || tok == TOK_A_OR ||
4313 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4314 test_lvalue();
4315 t = tok;
4316 next();
4317 if (t == '=') {
4318 expr_eq();
4319 } else {
4320 vdup();
4321 expr_eq();
4322 gen_op(t & 0x7f);
4324 vstore();
4328 ST_FUNC void gexpr(void)
4330 while (1) {
4331 expr_eq();
4332 if (tok != ',')
4333 break;
4334 vpop();
4335 next();
4339 /* parse an expression and return its type without any side effect. */
4340 static void expr_type(CType *type)
4342 int saved_nocode_wanted;
4344 saved_nocode_wanted = nocode_wanted;
4345 nocode_wanted = 1;
4346 gexpr();
4347 *type = vtop->type;
4348 vpop();
4349 nocode_wanted = saved_nocode_wanted;
4352 /* parse a unary expression and return its type without any side
4353 effect. */
4354 static void unary_type(CType *type)
4356 int a;
4358 a = nocode_wanted;
4359 nocode_wanted = 1;
4360 unary();
4361 *type = vtop->type;
4362 vpop();
4363 nocode_wanted = a;
4366 /* parse a constant expression and return value in vtop. */
4367 static void expr_const1(void)
4369 int a;
4370 a = const_wanted;
4371 const_wanted = 1;
4372 expr_cond();
4373 const_wanted = a;
4376 /* parse an integer constant and return its value. */
4377 ST_FUNC int expr_const(void)
4379 int c;
4380 expr_const1();
4381 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4382 expect("constant expression");
4383 c = vtop->c.i;
4384 vpop();
4385 return c;
4388 /* return the label token if current token is a label, otherwise
4389 return zero */
4390 static int is_label(void)
4392 int last_tok;
4394 /* fast test first */
4395 if (tok < TOK_UIDENT)
4396 return 0;
4397 /* no need to save tokc because tok is an identifier */
4398 last_tok = tok;
4399 next();
4400 if (tok == ':') {
4401 next();
4402 return last_tok;
4403 } else {
4404 unget_tok(last_tok);
4405 return 0;
4409 static void label_or_decl(int l)
4411 int last_tok;
4413 /* fast test first */
4414 if (tok >= TOK_UIDENT)
4416 /* no need to save tokc because tok is an identifier */
4417 last_tok = tok;
4418 next();
4419 if (tok == ':') {
4420 unget_tok(last_tok);
4421 return;
4423 unget_tok(last_tok);
4425 decl(l);
4428 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
4429 int case_reg, int is_expr)
4431 int a, b, c, d;
4432 Sym *s, *frame_bottom;
4434 /* generate line number info */
4435 if (tcc_state->do_debug &&
4436 (last_line_num != file->line_num || last_ind != ind)) {
4437 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4438 last_ind = ind;
4439 last_line_num = file->line_num;
4442 if (is_expr) {
4443 /* default return value is (void) */
4444 vpushi(0);
4445 vtop->type.t = VT_VOID;
4448 if (tok == TOK_IF) {
4449 /* if test */
4450 next();
4451 skip('(');
4452 gexpr();
4453 skip(')');
4454 a = gtst(1, 0);
4455 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4456 c = tok;
4457 if (c == TOK_ELSE) {
4458 next();
4459 d = gjmp(0);
4460 gsym(a);
4461 block(bsym, csym, case_sym, def_sym, case_reg, 0);
4462 gsym(d); /* patch else jmp */
4463 } else
4464 gsym(a);
4465 } else if (tok == TOK_WHILE) {
4466 next();
4467 d = ind;
4468 skip('(');
4469 gexpr();
4470 skip(')');
4471 a = gtst(1, 0);
4472 b = 0;
4473 block(&a, &b, case_sym, def_sym, case_reg, 0);
4474 gjmp_addr(d);
4475 gsym(a);
4476 gsym_addr(b, d);
4477 } else if (tok == '{') {
4478 Sym *llabel;
4480 next();
4481 /* record local declaration stack position */
4482 s = local_stack;
4483 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4484 frame_bottom->next = scope_stack_bottom;
4485 scope_stack_bottom = frame_bottom;
4486 llabel = local_label_stack;
4487 /* handle local labels declarations */
4488 if (tok == TOK_LABEL) {
4489 next();
4490 for(;;) {
4491 if (tok < TOK_UIDENT)
4492 expect("label identifier");
4493 label_push(&local_label_stack, tok, LABEL_DECLARED);
4494 next();
4495 if (tok == ',') {
4496 next();
4497 } else {
4498 skip(';');
4499 break;
4503 while (tok != '}') {
4504 label_or_decl(VT_LOCAL);
4505 if (tok != '}') {
4506 if (is_expr)
4507 vpop();
4508 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4511 /* pop locally defined labels */
4512 label_pop(&local_label_stack, llabel);
4513 if(is_expr) {
4514 /* XXX: this solution makes only valgrind happy...
4515 triggered by gcc.c-torture/execute/20000917-1.c */
4516 Sym *p;
4517 switch(vtop->type.t & VT_BTYPE) {
4518 case VT_PTR:
4519 case VT_STRUCT:
4520 case VT_ENUM:
4521 case VT_FUNC:
4522 for(p=vtop->type.ref;p;p=p->prev)
4523 if(p->prev==s)
4524 tcc_error("unsupported expression type");
4527 /* pop locally defined symbols */
4528 scope_stack_bottom = scope_stack_bottom->next;
4529 sym_pop(&local_stack, s);
4530 next();
4531 } else if (tok == TOK_RETURN) {
4532 next();
4533 if (tok != ';') {
4534 gexpr();
4535 gen_assign_cast(&func_vt);
4536 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
4537 CType type, ret_type;
4538 int ret_align;
4539 if (gfunc_sret(&func_vt, &ret_type, &ret_align)) {
4540 /* if returning structure, must copy it to implicit
4541 first pointer arg location */
4542 type = func_vt;
4543 mk_pointer(&type);
4544 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
4545 indir();
4546 vswap();
4547 /* copy structure value to pointer */
4548 vstore();
4549 } else {
4550 /* returning structure packed into registers */
4551 int size, addr, align;
4552 size = type_size(&func_vt,&align);
4553 if ((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & (ret_align-1)))
4554 && (align & (ret_align-1))) {
4555 loc = (loc - size) & -align;
4556 addr = loc;
4557 type = func_vt;
4558 vset(&type, VT_LOCAL | VT_LVAL, addr);
4559 vswap();
4560 vstore();
4561 vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
4563 vtop->type = ret_type;
4564 if (is_float(ret_type.t))
4565 gv(rc_fret(ret_type.t));
4566 else
4567 gv(RC_IRET);
4569 } else if (is_float(func_vt.t)) {
4570 gv(rc_fret(func_vt.t));
4571 } else {
4572 gv(RC_IRET);
4574 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4576 skip(';');
4577 rsym = gjmp(rsym); /* jmp */
4578 } else if (tok == TOK_BREAK) {
4579 /* compute jump */
4580 if (!bsym)
4581 tcc_error("cannot break");
4582 *bsym = gjmp(*bsym);
4583 next();
4584 skip(';');
4585 } else if (tok == TOK_CONTINUE) {
4586 /* compute jump */
4587 if (!csym)
4588 tcc_error("cannot continue");
4589 *csym = gjmp(*csym);
4590 next();
4591 skip(';');
4592 } else if (tok == TOK_FOR) {
4593 int e;
4594 next();
4595 skip('(');
4596 s = local_stack;
4597 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4598 frame_bottom->next = scope_stack_bottom;
4599 scope_stack_bottom = frame_bottom;
4600 if (tok != ';') {
4601 /* c99 for-loop init decl? */
4602 if (!decl0(VT_LOCAL, 1)) {
4603 /* no, regular for-loop init expr */
4604 gexpr();
4605 vpop();
4608 skip(';');
4609 d = ind;
4610 c = ind;
4611 a = 0;
4612 b = 0;
4613 if (tok != ';') {
4614 gexpr();
4615 a = gtst(1, 0);
4617 skip(';');
4618 if (tok != ')') {
4619 e = gjmp(0);
4620 c = ind;
4621 gexpr();
4622 vpop();
4623 gjmp_addr(d);
4624 gsym(e);
4626 skip(')');
4627 block(&a, &b, case_sym, def_sym, case_reg, 0);
4628 gjmp_addr(c);
4629 gsym(a);
4630 gsym_addr(b, c);
4631 scope_stack_bottom = scope_stack_bottom->next;
4632 sym_pop(&local_stack, s);
4633 } else
4634 if (tok == TOK_DO) {
4635 next();
4636 a = 0;
4637 b = 0;
4638 d = ind;
4639 block(&a, &b, case_sym, def_sym, case_reg, 0);
4640 skip(TOK_WHILE);
4641 skip('(');
4642 gsym(b);
4643 gexpr();
4644 c = gtst(0, 0);
4645 gsym_addr(c, d);
4646 skip(')');
4647 gsym(a);
4648 skip(';');
4649 } else
4650 if (tok == TOK_SWITCH) {
4651 next();
4652 skip('(');
4653 gexpr();
4654 /* XXX: other types than integer */
4655 case_reg = gv(RC_INT);
4656 vpop();
4657 skip(')');
4658 a = 0;
4659 b = gjmp(0); /* jump to first case */
4660 c = 0;
4661 block(&a, csym, &b, &c, case_reg, 0);
4662 /* if no default, jmp after switch */
4663 if (c == 0)
4664 c = ind;
4665 /* default label */
4666 gsym_addr(b, c);
4667 /* break label */
4668 gsym(a);
4669 } else
4670 if (tok == TOK_CASE) {
4671 int v1, v2;
4672 if (!case_sym)
4673 expect("switch");
4674 next();
4675 v1 = expr_const();
4676 v2 = v1;
4677 if (gnu_ext && tok == TOK_DOTS) {
4678 next();
4679 v2 = expr_const();
4680 if (v2 < v1)
4681 tcc_warning("empty case range");
4683 /* since a case is like a label, we must skip it with a jmp */
4684 b = gjmp(0);
4685 gsym(*case_sym);
4686 vseti(case_reg, 0);
4687 vpushi(v1);
4688 if (v1 == v2) {
4689 gen_op(TOK_EQ);
4690 *case_sym = gtst(1, 0);
4691 } else {
4692 gen_op(TOK_GE);
4693 *case_sym = gtst(1, 0);
4694 vseti(case_reg, 0);
4695 vpushi(v2);
4696 gen_op(TOK_LE);
4697 *case_sym = gtst(1, *case_sym);
4699 gsym(b);
4700 skip(':');
4701 is_expr = 0;
4702 goto block_after_label;
4703 } else
4704 if (tok == TOK_DEFAULT) {
4705 next();
4706 skip(':');
4707 if (!def_sym)
4708 expect("switch");
4709 if (*def_sym)
4710 tcc_error("too many 'default'");
4711 *def_sym = ind;
4712 is_expr = 0;
4713 goto block_after_label;
4714 } else
4715 if (tok == TOK_GOTO) {
4716 next();
4717 if (tok == '*' && gnu_ext) {
4718 /* computed goto */
4719 next();
4720 gexpr();
4721 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
4722 expect("pointer");
4723 ggoto();
4724 } else if (tok >= TOK_UIDENT) {
4725 s = label_find(tok);
4726 /* put forward definition if needed */
4727 if (!s) {
4728 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4729 } else {
4730 if (s->r == LABEL_DECLARED)
4731 s->r = LABEL_FORWARD;
4733 /* label already defined */
4734 if (s->r & LABEL_FORWARD)
4735 s->jnext = gjmp(s->jnext);
4736 else
4737 gjmp_addr(s->jnext);
4738 next();
4739 } else {
4740 expect("label identifier");
4742 skip(';');
4743 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
4744 asm_instr();
4745 } else {
4746 b = is_label();
4747 if (b) {
4748 /* label case */
4749 s = label_find(b);
4750 if (s) {
4751 if (s->r == LABEL_DEFINED)
4752 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
4753 gsym(s->jnext);
4754 s->r = LABEL_DEFINED;
4755 } else {
4756 s = label_push(&global_label_stack, b, LABEL_DEFINED);
4758 s->jnext = ind;
4759 /* we accept this, but it is a mistake */
4760 block_after_label:
4761 if (tok == '}') {
4762 tcc_warning("deprecated use of label at end of compound statement");
4763 } else {
4764 if (is_expr)
4765 vpop();
4766 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
4768 } else {
4769 /* expression case */
4770 if (tok != ';') {
4771 if (is_expr) {
4772 vpop();
4773 gexpr();
4774 } else {
4775 gexpr();
4776 vpop();
4779 skip(';');
4784 /* t is the array or struct type. c is the array or struct
4785 address. cur_index/cur_field is the pointer to the current
4786 value. 'size_only' is true if only size info is needed (only used
4787 in arrays) */
4788 static void decl_designator(CType *type, Section *sec, unsigned long c,
4789 int *cur_index, Sym **cur_field,
4790 int size_only)
4792 Sym *s, *f;
4793 int notfirst, index, index_last, align, l, nb_elems, elem_size;
4794 CType type1;
4796 notfirst = 0;
4797 elem_size = 0;
4798 nb_elems = 1;
4799 if (gnu_ext && (l = is_label()) != 0)
4800 goto struct_field;
4801 while (tok == '[' || tok == '.') {
4802 if (tok == '[') {
4803 if (!(type->t & VT_ARRAY))
4804 expect("array type");
4805 s = type->ref;
4806 next();
4807 index = expr_const();
4808 if (index < 0 || (s->c >= 0 && index >= s->c))
4809 expect("invalid index");
4810 if (tok == TOK_DOTS && gnu_ext) {
4811 next();
4812 index_last = expr_const();
4813 if (index_last < 0 ||
4814 (s->c >= 0 && index_last >= s->c) ||
4815 index_last < index)
4816 expect("invalid index");
4817 } else {
4818 index_last = index;
4820 skip(']');
4821 if (!notfirst)
4822 *cur_index = index_last;
4823 type = pointed_type(type);
4824 elem_size = type_size(type, &align);
4825 c += index * elem_size;
4826 /* NOTE: we only support ranges for last designator */
4827 nb_elems = index_last - index + 1;
4828 if (nb_elems != 1) {
4829 notfirst = 1;
4830 break;
4832 } else {
4833 next();
4834 l = tok;
4835 next();
4836 struct_field:
4837 if ((type->t & VT_BTYPE) != VT_STRUCT)
4838 expect("struct/union type");
4839 s = type->ref;
4840 l |= SYM_FIELD;
4841 f = s->next;
4842 while (f) {
4843 if (f->v == l)
4844 break;
4845 f = f->next;
4847 if (!f)
4848 expect("field");
4849 if (!notfirst)
4850 *cur_field = f;
4851 /* XXX: fix this mess by using explicit storage field */
4852 type1 = f->type;
4853 type1.t |= (type->t & ~VT_TYPE);
4854 type = &type1;
4855 c += f->c;
4857 notfirst = 1;
4859 if (notfirst) {
4860 if (tok == '=') {
4861 next();
4862 } else {
4863 if (!gnu_ext)
4864 expect("=");
4866 } else {
4867 if (type->t & VT_ARRAY) {
4868 index = *cur_index;
4869 type = pointed_type(type);
4870 c += index * type_size(type, &align);
4871 } else {
4872 f = *cur_field;
4873 if (!f)
4874 tcc_error("too many field init");
4875 /* XXX: fix this mess by using explicit storage field */
4876 type1 = f->type;
4877 type1.t |= (type->t & ~VT_TYPE);
4878 type = &type1;
4879 c += f->c;
4882 decl_initializer(type, sec, c, 0, size_only);
4884 /* XXX: make it more general */
4885 if (!size_only && nb_elems > 1) {
4886 unsigned long c_end;
4887 uint8_t *src, *dst;
4888 int i;
4890 if (!sec)
4891 tcc_error("range init not supported yet for dynamic storage");
4892 c_end = c + nb_elems * elem_size;
4893 if (c_end > sec->data_allocated)
4894 section_realloc(sec, c_end);
4895 src = sec->data + c;
4896 dst = src;
4897 for(i = 1; i < nb_elems; i++) {
4898 dst += elem_size;
4899 memcpy(dst, src, elem_size);
4904 #define EXPR_VAL 0
4905 #define EXPR_CONST 1
4906 #define EXPR_ANY 2
4908 /* store a value or an expression directly in global data or in local array */
4909 static void init_putv(CType *type, Section *sec, unsigned long c,
4910 int v, int expr_type)
4912 int saved_global_expr, bt, bit_pos, bit_size;
4913 void *ptr;
4914 unsigned long long bit_mask;
4915 CType dtype;
4917 switch(expr_type) {
4918 case EXPR_VAL:
4919 vpushi(v);
4920 break;
4921 case EXPR_CONST:
4922 /* compound literals must be allocated globally in this case */
4923 saved_global_expr = global_expr;
4924 global_expr = 1;
4925 expr_const1();
4926 global_expr = saved_global_expr;
4927 /* NOTE: symbols are accepted */
4928 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
4929 tcc_error("initializer element is not constant");
4930 break;
4931 case EXPR_ANY:
4932 expr_eq();
4933 break;
4936 dtype = *type;
4937 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
4939 if (sec) {
4940 /* XXX: not portable */
4941 /* XXX: generate error if incorrect relocation */
4942 gen_assign_cast(&dtype);
4943 bt = type->t & VT_BTYPE;
4944 /* we'll write at most 12 bytes */
4945 if (c + 12 > sec->data_allocated) {
4946 section_realloc(sec, c + 12);
4948 ptr = sec->data + c;
4949 /* XXX: make code faster ? */
4950 if (!(type->t & VT_BITFIELD)) {
4951 bit_pos = 0;
4952 bit_size = 32;
4953 bit_mask = -1LL;
4954 } else {
4955 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4956 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4957 bit_mask = (1LL << bit_size) - 1;
4959 if ((vtop->r & VT_SYM) &&
4960 (bt == VT_BYTE ||
4961 bt == VT_SHORT ||
4962 bt == VT_DOUBLE ||
4963 bt == VT_LDOUBLE ||
4964 bt == VT_LLONG ||
4965 (bt == VT_INT && bit_size != 32)))
4966 tcc_error("initializer element is not computable at load time");
4967 switch(bt) {
4968 case VT_BOOL:
4969 vtop->c.i = (vtop->c.i != 0);
4970 case VT_BYTE:
4971 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4972 break;
4973 case VT_SHORT:
4974 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4975 break;
4976 case VT_DOUBLE:
4977 *(double *)ptr = vtop->c.d;
4978 break;
4979 case VT_LDOUBLE:
4980 *(long double *)ptr = vtop->c.ld;
4981 break;
4982 case VT_LLONG:
4983 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
4984 break;
4985 default:
4986 if (vtop->r & VT_SYM) {
4987 greloc(sec, vtop->sym, c, R_DATA_PTR);
4989 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
4990 break;
4992 vtop--;
4993 } else {
4994 vset(&dtype, VT_LOCAL|VT_LVAL, c);
4995 vswap();
4996 vstore();
4997 vpop();
5001 /* put zeros for variable based init */
5002 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
5004 if (sec) {
5005 /* nothing to do because globals are already set to zero */
5006 } else {
5007 vpush_global_sym(&func_old_type, TOK_memset);
5008 vseti(VT_LOCAL, c);
5009 vpushi(0);
5010 vpushs(size);
5011 gfunc_call(3);
5015 /* 't' contains the type and storage info. 'c' is the offset of the
5016 object in section 'sec'. If 'sec' is NULL, it means stack based
5017 allocation. 'first' is true if array '{' must be read (multi
5018 dimension implicit array init handling). 'size_only' is true if
5019 size only evaluation is wanted (only for arrays). */
5020 static void decl_initializer(CType *type, Section *sec, unsigned long c,
5021 int first, int size_only)
5023 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
5024 int size1, align1, expr_type;
5025 Sym *s, *f;
5026 CType *t1;
5028 if (type->t & VT_VLA) {
5029 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
5030 int a;
5031 CValue retcval;
5033 vpush_global_sym(&func_old_type, TOK_alloca);
5034 vla_runtime_type_size(type, &a);
5035 gfunc_call(1);
5037 /* return value */
5038 retcval.i = 0;
5039 vsetc(type, REG_IRET, &retcval);
5040 vset(type, VT_LOCAL|VT_LVAL, c);
5041 vswap();
5042 vstore();
5043 vpop();
5044 #else
5045 tcc_error("variable length arrays unsupported for this target");
5046 #endif
5047 } else if (type->t & VT_ARRAY) {
5048 s = type->ref;
5049 n = s->c;
5050 array_length = 0;
5051 t1 = pointed_type(type);
5052 size1 = type_size(t1, &align1);
5054 no_oblock = 1;
5055 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
5056 tok == '{') {
5057 if (tok != '{')
5058 tcc_error("character array initializer must be a literal,"
5059 " optionally enclosed in braces");
5060 skip('{');
5061 no_oblock = 0;
5064 /* only parse strings here if correct type (otherwise: handle
5065 them as ((w)char *) expressions */
5066 if ((tok == TOK_LSTR &&
5067 #ifdef TCC_TARGET_PE
5068 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
5069 #else
5070 (t1->t & VT_BTYPE) == VT_INT
5071 #endif
5072 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
5073 while (tok == TOK_STR || tok == TOK_LSTR) {
5074 int cstr_len, ch;
5075 CString *cstr;
5077 cstr = tokc.cstr;
5078 /* compute maximum number of chars wanted */
5079 if (tok == TOK_STR)
5080 cstr_len = cstr->size;
5081 else
5082 cstr_len = cstr->size / sizeof(nwchar_t);
5083 cstr_len--;
5084 nb = cstr_len;
5085 if (n >= 0 && nb > (n - array_length))
5086 nb = n - array_length;
5087 if (!size_only) {
5088 if (cstr_len > nb)
5089 tcc_warning("initializer-string for array is too long");
5090 /* in order to go faster for common case (char
5091 string in global variable, we handle it
5092 specifically */
5093 if (sec && tok == TOK_STR && size1 == 1) {
5094 memcpy(sec->data + c + array_length, cstr->data, nb);
5095 } else {
5096 for(i=0;i<nb;i++) {
5097 if (tok == TOK_STR)
5098 ch = ((unsigned char *)cstr->data)[i];
5099 else
5100 ch = ((nwchar_t *)cstr->data)[i];
5101 init_putv(t1, sec, c + (array_length + i) * size1,
5102 ch, EXPR_VAL);
5106 array_length += nb;
5107 next();
5109 /* only add trailing zero if enough storage (no
5110 warning in this case since it is standard) */
5111 if (n < 0 || array_length < n) {
5112 if (!size_only) {
5113 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
5115 array_length++;
5117 } else {
5118 index = 0;
5119 while (tok != '}') {
5120 decl_designator(type, sec, c, &index, NULL, size_only);
5121 if (n >= 0 && index >= n)
5122 tcc_error("index too large");
5123 /* must put zero in holes (note that doing it that way
5124 ensures that it even works with designators) */
5125 if (!size_only && array_length < index) {
5126 init_putz(t1, sec, c + array_length * size1,
5127 (index - array_length) * size1);
5129 index++;
5130 if (index > array_length)
5131 array_length = index;
5132 /* special test for multi dimensional arrays (may not
5133 be strictly correct if designators are used at the
5134 same time) */
5135 if (index >= n && no_oblock)
5136 break;
5137 if (tok == '}')
5138 break;
5139 skip(',');
5142 if (!no_oblock)
5143 skip('}');
5144 /* put zeros at the end */
5145 if (!size_only && n >= 0 && array_length < n) {
5146 init_putz(t1, sec, c + array_length * size1,
5147 (n - array_length) * size1);
5149 /* patch type size if needed */
5150 if (n < 0)
5151 s->c = array_length;
5152 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
5153 (sec || !first || tok == '{')) {
5154 int par_count;
5156 /* NOTE: the previous test is a specific case for automatic
5157 struct/union init */
5158 /* XXX: union needs only one init */
5160 /* XXX: this test is incorrect for local initializers
5161 beginning with ( without {. It would be much more difficult
5162 to do it correctly (ideally, the expression parser should
5163 be used in all cases) */
5164 par_count = 0;
5165 if (tok == '(') {
5166 AttributeDef ad1;
5167 CType type1;
5168 next();
5169 while (tok == '(') {
5170 par_count++;
5171 next();
5173 if (!parse_btype(&type1, &ad1))
5174 expect("cast");
5175 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5176 #if 0
5177 if (!is_assignable_types(type, &type1))
5178 tcc_error("invalid type for cast");
5179 #endif
5180 skip(')');
5182 no_oblock = 1;
5183 if (first || tok == '{') {
5184 skip('{');
5185 no_oblock = 0;
5187 s = type->ref;
5188 f = s->next;
5189 array_length = 0;
5190 index = 0;
5191 n = s->c;
5192 while (tok != '}') {
5193 decl_designator(type, sec, c, NULL, &f, size_only);
5194 index = f->c;
5195 if (!size_only && array_length < index) {
5196 init_putz(type, sec, c + array_length,
5197 index - array_length);
5199 index = index + type_size(&f->type, &align1);
5200 if (index > array_length)
5201 array_length = index;
5203 /* gr: skip fields from same union - ugly. */
5204 while (f->next) {
5205 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5206 /* test for same offset */
5207 if (f->next->c != f->c)
5208 break;
5209 /* if yes, test for bitfield shift */
5210 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
5211 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5212 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5213 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5214 if (bit_pos_1 != bit_pos_2)
5215 break;
5217 f = f->next;
5220 f = f->next;
5221 if (no_oblock && f == NULL)
5222 break;
5223 if (tok == '}')
5224 break;
5225 skip(',');
5227 /* put zeros at the end */
5228 if (!size_only && array_length < n) {
5229 init_putz(type, sec, c + array_length,
5230 n - array_length);
5232 if (!no_oblock)
5233 skip('}');
5234 while (par_count) {
5235 skip(')');
5236 par_count--;
5238 } else if (tok == '{') {
5239 next();
5240 decl_initializer(type, sec, c, first, size_only);
5241 skip('}');
5242 } else if (size_only) {
5243 /* just skip expression */
5244 parlevel = parlevel1 = 0;
5245 while ((parlevel > 0 || parlevel1 > 0 ||
5246 (tok != '}' && tok != ',')) && tok != -1) {
5247 if (tok == '(')
5248 parlevel++;
5249 else if (tok == ')')
5250 parlevel--;
5251 else if (tok == '{')
5252 parlevel1++;
5253 else if (tok == '}')
5254 parlevel1--;
5255 next();
5257 } else {
5258 /* currently, we always use constant expression for globals
5259 (may change for scripting case) */
5260 expr_type = EXPR_CONST;
5261 if (!sec)
5262 expr_type = EXPR_ANY;
5263 init_putv(type, sec, c, 0, expr_type);
5267 /* parse an initializer for type 't' if 'has_init' is non zero, and
5268 allocate space in local or global data space ('r' is either
5269 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5270 variable 'v' with an associated name represented by 'asm_label' of
5271 scope 'scope' is declared before initializers are parsed. If 'v' is
5272 zero, then a reference to the new object is put in the value stack.
5273 If 'has_init' is 2, a special parsing is done to handle string
5274 constants. */
5275 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5276 int has_init, int v, char *asm_label,
5277 int scope)
5279 int size, align, addr, data_offset;
5280 int level;
5281 ParseState saved_parse_state = {0};
5282 TokenString init_str;
5283 Section *sec;
5284 Sym *flexible_array;
5286 flexible_array = NULL;
5287 if ((type->t & VT_BTYPE) == VT_STRUCT) {
5288 Sym *field;
5289 field = type->ref;
5290 while (field && field->next)
5291 field = field->next;
5292 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
5293 flexible_array = field;
5296 size = type_size(type, &align);
5297 /* If unknown size, we must evaluate it before
5298 evaluating initializers because
5299 initializers can generate global data too
5300 (e.g. string pointers or ISOC99 compound
5301 literals). It also simplifies local
5302 initializers handling */
5303 tok_str_new(&init_str);
5304 if (size < 0 || (flexible_array && has_init)) {
5305 if (!has_init)
5306 tcc_error("unknown type size");
5307 /* get all init string */
5308 if (has_init == 2) {
5309 /* only get strings */
5310 while (tok == TOK_STR || tok == TOK_LSTR) {
5311 tok_str_add_tok(&init_str);
5312 next();
5314 } else {
5315 level = 0;
5316 while (level > 0 || (tok != ',' && tok != ';')) {
5317 if (tok < 0)
5318 tcc_error("unexpected end of file in initializer");
5319 tok_str_add_tok(&init_str);
5320 if (tok == '{')
5321 level++;
5322 else if (tok == '}') {
5323 level--;
5324 if (level <= 0) {
5325 next();
5326 break;
5329 next();
5332 tok_str_add(&init_str, -1);
5333 tok_str_add(&init_str, 0);
5335 /* compute size */
5336 save_parse_state(&saved_parse_state);
5338 macro_ptr = init_str.str;
5339 next();
5340 decl_initializer(type, NULL, 0, 1, 1);
5341 /* prepare second initializer parsing */
5342 macro_ptr = init_str.str;
5343 next();
5345 /* if still unknown size, error */
5346 size = type_size(type, &align);
5347 if (size < 0)
5348 tcc_error("unknown type size");
5350 if (flexible_array)
5351 size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
5352 /* take into account specified alignment if bigger */
5353 if (ad->aligned) {
5354 if (ad->aligned > align)
5355 align = ad->aligned;
5356 } else if (ad->packed) {
5357 align = 1;
5359 if ((r & VT_VALMASK) == VT_LOCAL) {
5360 sec = NULL;
5361 #ifdef CONFIG_TCC_BCHECK
5362 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5363 loc--;
5365 #endif
5366 loc = (loc - size) & -align;
5367 addr = loc;
5368 #ifdef CONFIG_TCC_BCHECK
5369 /* handles bounds */
5370 /* XXX: currently, since we do only one pass, we cannot track
5371 '&' operators, so we add only arrays */
5372 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
5373 unsigned long *bounds_ptr;
5374 /* add padding between regions */
5375 loc--;
5376 /* then add local bound info */
5377 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
5378 bounds_ptr[0] = addr;
5379 bounds_ptr[1] = size;
5381 #endif
5382 if (v) {
5383 /* local variable */
5384 sym_push(v, type, r, addr);
5385 } else {
5386 /* push local reference */
5387 vset(type, r, addr);
5389 } else {
5390 Sym *sym;
5392 sym = NULL;
5393 if (v && scope == VT_CONST) {
5394 /* see if the symbol was already defined */
5395 sym = sym_find(v);
5396 if (sym) {
5397 if (!is_compatible_types(&sym->type, type))
5398 tcc_error("incompatible types for redefinition of '%s'",
5399 get_tok_str(v, NULL));
5400 if (sym->type.t & VT_EXTERN) {
5401 /* if the variable is extern, it was not allocated */
5402 sym->type.t &= ~VT_EXTERN;
5403 /* set array size if it was ommited in extern
5404 declaration */
5405 if ((sym->type.t & VT_ARRAY) &&
5406 sym->type.ref->c < 0 &&
5407 type->ref->c >= 0)
5408 sym->type.ref->c = type->ref->c;
5409 } else {
5410 /* we accept several definitions of the same
5411 global variable. this is tricky, because we
5412 must play with the SHN_COMMON type of the symbol */
5413 /* XXX: should check if the variable was already
5414 initialized. It is incorrect to initialized it
5415 twice */
5416 /* no init data, we won't add more to the symbol */
5417 if (!has_init)
5418 goto no_alloc;
5423 /* allocate symbol in corresponding section */
5424 sec = ad->section;
5425 if (!sec) {
5426 if (has_init)
5427 sec = data_section;
5428 else if (tcc_state->nocommon)
5429 sec = bss_section;
5431 if (sec) {
5432 data_offset = sec->data_offset;
5433 data_offset = (data_offset + align - 1) & -align;
5434 addr = data_offset;
5435 /* very important to increment global pointer at this time
5436 because initializers themselves can create new initializers */
5437 data_offset += size;
5438 #ifdef CONFIG_TCC_BCHECK
5439 /* add padding if bound check */
5440 if (tcc_state->do_bounds_check)
5441 data_offset++;
5442 #endif
5443 sec->data_offset = data_offset;
5444 /* allocate section space to put the data */
5445 if (sec->sh_type != SHT_NOBITS &&
5446 data_offset > sec->data_allocated)
5447 section_realloc(sec, data_offset);
5448 /* align section if needed */
5449 if (align > sec->sh_addralign)
5450 sec->sh_addralign = align;
5451 } else {
5452 addr = 0; /* avoid warning */
5455 if (v) {
5456 if (scope != VT_CONST || !sym) {
5457 sym = sym_push(v, type, r | VT_SYM, 0);
5458 sym->asm_label = asm_label;
5460 /* update symbol definition */
5461 if (sec) {
5462 put_extern_sym(sym, sec, addr, size);
5463 } else {
5464 ElfW(Sym) *esym;
5465 /* put a common area */
5466 put_extern_sym(sym, NULL, align, size);
5467 /* XXX: find a nicer way */
5468 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
5469 esym->st_shndx = SHN_COMMON;
5471 } else {
5472 CValue cval;
5474 /* push global reference */
5475 sym = get_sym_ref(type, sec, addr, size);
5476 cval.ul = 0;
5477 vsetc(type, VT_CONST | VT_SYM, &cval);
5478 vtop->sym = sym;
5480 /* patch symbol weakness */
5481 if (type->t & VT_WEAK)
5482 weaken_symbol(sym);
5483 #ifdef CONFIG_TCC_BCHECK
5484 /* handles bounds now because the symbol must be defined
5485 before for the relocation */
5486 if (tcc_state->do_bounds_check) {
5487 unsigned long *bounds_ptr;
5489 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
5490 /* then add global bound info */
5491 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
5492 bounds_ptr[0] = 0; /* relocated */
5493 bounds_ptr[1] = size;
5495 #endif
5497 if (has_init || (type->t & VT_VLA)) {
5498 decl_initializer(type, sec, addr, 1, 0);
5499 /* restore parse state if needed */
5500 if (init_str.str) {
5501 tok_str_free(init_str.str);
5502 restore_parse_state(&saved_parse_state);
5504 /* patch flexible array member size back to -1, */
5505 /* for possible subsequent similar declarations */
5506 if (flexible_array)
5507 flexible_array->type.ref->c = -1;
5509 no_alloc: ;
5512 static void put_func_debug(Sym *sym)
5514 char buf[512];
5516 /* stabs info */
5517 /* XXX: we put here a dummy type */
5518 snprintf(buf, sizeof(buf), "%s:%c1",
5519 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
5520 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
5521 cur_text_section, sym->c);
5522 /* //gr gdb wants a line at the function */
5523 put_stabn(N_SLINE, 0, file->line_num, 0);
5524 last_ind = 0;
5525 last_line_num = 0;
5528 /* parse an old style function declaration list */
5529 /* XXX: check multiple parameter */
5530 static void func_decl_list(Sym *func_sym)
5532 AttributeDef ad;
5533 int v;
5534 Sym *s;
5535 CType btype, type;
5537 /* parse each declaration */
5538 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
5539 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
5540 if (!parse_btype(&btype, &ad))
5541 expect("declaration list");
5542 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5543 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5544 tok == ';') {
5545 /* we accept no variable after */
5546 } else {
5547 for(;;) {
5548 type = btype;
5549 type_decl(&type, &ad, &v, TYPE_DIRECT);
5550 /* find parameter in function parameter list */
5551 s = func_sym->next;
5552 while (s != NULL) {
5553 if ((s->v & ~SYM_FIELD) == v)
5554 goto found;
5555 s = s->next;
5557 tcc_error("declaration for parameter '%s' but no such parameter",
5558 get_tok_str(v, NULL));
5559 found:
5560 /* check that no storage specifier except 'register' was given */
5561 if (type.t & VT_STORAGE)
5562 tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
5563 convert_parameter_type(&type);
5564 /* we can add the type (NOTE: it could be local to the function) */
5565 s->type = type;
5566 /* accept other parameters */
5567 if (tok == ',')
5568 next();
5569 else
5570 break;
5573 skip(';');
5577 /* parse a function defined by symbol 'sym' and generate its code in
5578 'cur_text_section' */
5579 static void gen_function(Sym *sym)
5581 int saved_nocode_wanted = nocode_wanted;
5582 nocode_wanted = 0;
5583 ind = cur_text_section->data_offset;
5584 /* NOTE: we patch the symbol size later */
5585 put_extern_sym(sym, cur_text_section, ind, 0);
5586 funcname = get_tok_str(sym->v, NULL);
5587 func_ind = ind;
5588 /* put debug symbol */
5589 if (tcc_state->do_debug)
5590 put_func_debug(sym);
5591 /* push a dummy symbol to enable local sym storage */
5592 sym_push2(&local_stack, SYM_FIELD, 0, 0);
5593 gfunc_prolog(&sym->type);
5594 rsym = 0;
5595 block(NULL, NULL, NULL, NULL, 0, 0);
5596 gsym(rsym);
5597 gfunc_epilog();
5598 cur_text_section->data_offset = ind;
5599 label_pop(&global_label_stack, NULL);
5600 /* reset local stack */
5601 scope_stack_bottom = NULL;
5602 sym_pop(&local_stack, NULL);
5603 /* end of function */
5604 /* patch symbol size */
5605 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
5606 ind - func_ind;
5607 /* patch symbol weakness (this definition overrules any prototype) */
5608 if (sym->type.t & VT_WEAK)
5609 weaken_symbol(sym);
5610 if (tcc_state->do_debug) {
5611 put_stabn(N_FUN, 0, 0, ind - func_ind);
5613 /* It's better to crash than to generate wrong code */
5614 cur_text_section = NULL;
5615 funcname = ""; /* for safety */
5616 func_vt.t = VT_VOID; /* for safety */
5617 ind = 0; /* for safety */
5618 nocode_wanted = saved_nocode_wanted;
5621 ST_FUNC void gen_inline_functions(void)
5623 Sym *sym;
5624 int *str, inline_generated, i;
5625 struct InlineFunc *fn;
5627 /* iterate while inline function are referenced */
5628 for(;;) {
5629 inline_generated = 0;
5630 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5631 fn = tcc_state->inline_fns[i];
5632 sym = fn->sym;
5633 if (sym && sym->c) {
5634 /* the function was used: generate its code and
5635 convert it to a normal function */
5636 str = fn->token_str;
5637 fn->sym = NULL;
5638 if (file)
5639 pstrcpy(file->filename, sizeof file->filename, fn->filename);
5640 sym->r = VT_SYM | VT_CONST;
5641 sym->type.t &= ~VT_INLINE;
5643 macro_ptr = str;
5644 next();
5645 cur_text_section = text_section;
5646 gen_function(sym);
5647 macro_ptr = NULL; /* fail safe */
5649 inline_generated = 1;
5652 if (!inline_generated)
5653 break;
5655 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
5656 fn = tcc_state->inline_fns[i];
5657 str = fn->token_str;
5658 tok_str_free(str);
5660 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
5663 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5664 static int decl0(int l, int is_for_loop_init)
5666 int v, has_init, r;
5667 CType type, btype;
5668 Sym *sym;
5669 AttributeDef ad;
5671 while (1) {
5672 if (!parse_btype(&btype, &ad)) {
5673 if (is_for_loop_init)
5674 return 0;
5675 /* skip redundant ';' */
5676 /* XXX: find more elegant solution */
5677 if (tok == ';') {
5678 next();
5679 continue;
5681 if (l == VT_CONST &&
5682 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5683 /* global asm block */
5684 asm_global_instr();
5685 continue;
5687 /* special test for old K&R protos without explicit int
5688 type. Only accepted when defining global data */
5689 if (l == VT_LOCAL || tok < TOK_DEFINE)
5690 break;
5691 btype.t = VT_INT;
5693 if (((btype.t & VT_BTYPE) == VT_ENUM ||
5694 (btype.t & VT_BTYPE) == VT_STRUCT) &&
5695 tok == ';') {
5696 /* we accept no variable after */
5697 next();
5698 continue;
5700 while (1) { /* iterate thru each declaration */
5701 char *asm_label; // associated asm label
5702 type = btype;
5703 type_decl(&type, &ad, &v, TYPE_DIRECT);
5704 #if 0
5706 char buf[500];
5707 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
5708 printf("type = '%s'\n", buf);
5710 #endif
5711 if ((type.t & VT_BTYPE) == VT_FUNC) {
5712 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
5713 tcc_error("function without file scope cannot be static");
5715 /* if old style function prototype, we accept a
5716 declaration list */
5717 sym = type.ref;
5718 if (sym->c == FUNC_OLD)
5719 func_decl_list(sym);
5722 asm_label = NULL;
5723 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
5724 CString astr;
5726 asm_label_instr(&astr);
5727 asm_label = tcc_strdup(astr.data);
5728 cstr_free(&astr);
5730 /* parse one last attribute list, after asm label */
5731 parse_attribute(&ad);
5734 if (ad.weak)
5735 type.t |= VT_WEAK;
5736 #ifdef TCC_TARGET_PE
5737 if (ad.func_import)
5738 type.t |= VT_IMPORT;
5739 if (ad.func_export)
5740 type.t |= VT_EXPORT;
5741 #endif
5742 if (tok == '{') {
5743 if (l == VT_LOCAL)
5744 tcc_error("cannot use local functions");
5745 if ((type.t & VT_BTYPE) != VT_FUNC)
5746 expect("function definition");
5748 /* reject abstract declarators in function definition */
5749 sym = type.ref;
5750 while ((sym = sym->next) != NULL)
5751 if (!(sym->v & ~SYM_FIELD))
5752 expect("identifier");
5754 /* XXX: cannot do better now: convert extern line to static inline */
5755 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
5756 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5758 sym = sym_find(v);
5759 if (sym) {
5760 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
5761 goto func_error1;
5763 r = sym->type.ref->r;
5764 /* use func_call from prototype if not defined */
5765 if (FUNC_CALL(r) != FUNC_CDECL
5766 && FUNC_CALL(type.ref->r) == FUNC_CDECL)
5767 FUNC_CALL(type.ref->r) = FUNC_CALL(r);
5769 /* use export from prototype */
5770 if (FUNC_EXPORT(r))
5771 FUNC_EXPORT(type.ref->r) = 1;
5773 /* use static from prototype */
5774 if (sym->type.t & VT_STATIC)
5775 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5777 if (!is_compatible_types(&sym->type, &type)) {
5778 func_error1:
5779 tcc_error("incompatible types for redefinition of '%s'",
5780 get_tok_str(v, NULL));
5782 /* if symbol is already defined, then put complete type */
5783 sym->type = type;
5784 } else {
5785 /* put function symbol */
5786 sym = global_identifier_push(v, type.t, 0);
5787 sym->type.ref = type.ref;
5790 /* static inline functions are just recorded as a kind
5791 of macro. Their code will be emitted at the end of
5792 the compilation unit only if they are used */
5793 if ((type.t & (VT_INLINE | VT_STATIC)) ==
5794 (VT_INLINE | VT_STATIC)) {
5795 TokenString func_str;
5796 int block_level;
5797 struct InlineFunc *fn;
5798 const char *filename;
5800 tok_str_new(&func_str);
5802 block_level = 0;
5803 for(;;) {
5804 int t;
5805 if (tok == TOK_EOF)
5806 tcc_error("unexpected end of file");
5807 tok_str_add_tok(&func_str);
5808 t = tok;
5809 next();
5810 if (t == '{') {
5811 block_level++;
5812 } else if (t == '}') {
5813 block_level--;
5814 if (block_level == 0)
5815 break;
5818 tok_str_add(&func_str, -1);
5819 tok_str_add(&func_str, 0);
5820 filename = file ? file->filename : "";
5821 fn = tcc_malloc(sizeof *fn + strlen(filename));
5822 strcpy(fn->filename, filename);
5823 fn->sym = sym;
5824 fn->token_str = func_str.str;
5825 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
5827 } else {
5828 /* compute text section */
5829 cur_text_section = ad.section;
5830 if (!cur_text_section)
5831 cur_text_section = text_section;
5832 sym->r = VT_SYM | VT_CONST;
5833 gen_function(sym);
5835 break;
5836 } else {
5837 if (btype.t & VT_TYPEDEF) {
5838 /* save typedefed type */
5839 /* XXX: test storage specifiers ? */
5840 sym = sym_push(v, &type, INT_ATTR(&ad), 0);
5841 sym->type.t |= VT_TYPEDEF;
5842 } else {
5843 r = 0;
5844 if ((type.t & VT_BTYPE) == VT_FUNC) {
5845 /* external function definition */
5846 /* specific case for func_call attribute */
5847 type.ref->r = INT_ATTR(&ad);
5848 } else if (!(type.t & VT_ARRAY)) {
5849 /* not lvalue if array */
5850 r |= lvalue_type(type.t);
5852 has_init = (tok == '=');
5853 if (has_init && (type.t & VT_VLA))
5854 tcc_error("Variable length array cannot be initialized");
5855 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
5856 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
5857 !has_init && l == VT_CONST && type.ref->c < 0)) {
5858 /* external variable or function */
5859 /* NOTE: as GCC, uninitialized global static
5860 arrays of null size are considered as
5861 extern */
5862 sym = external_sym(v, &type, r, asm_label);
5864 if (type.t & VT_WEAK)
5865 weaken_symbol(sym);
5867 if (ad.alias_target) {
5868 Section tsec;
5869 Elf32_Sym *esym;
5870 Sym *alias_target;
5872 alias_target = sym_find(ad.alias_target);
5873 if (!alias_target || !alias_target->c)
5874 tcc_error("unsupported forward __alias__ attribute");
5875 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
5876 tsec.sh_num = esym->st_shndx;
5877 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
5879 } else {
5880 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
5881 if (type.t & VT_STATIC)
5882 r |= VT_CONST;
5883 else
5884 r |= l;
5885 if (has_init)
5886 next();
5887 decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l);
5890 if (tok != ',') {
5891 if (is_for_loop_init)
5892 return 1;
5893 skip(';');
5894 break;
5896 next();
5898 ad.aligned = 0;
5901 return 0;
5904 ST_FUNC void decl(int l)
5906 decl0(l, 0);