gcase() clean up
[tinycc.git] / tccgen.c
blobba5c23e671d37ee68f11469dd95945a7df859731
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 *define_stack;
54 ST_DATA Sym *global_label_stack;
55 ST_DATA Sym *local_label_stack;
56 static int local_scope;
57 static int in_sizeof;
59 ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */
60 ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */
61 ST_DATA int vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */
63 ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop, *pvtop;
65 ST_DATA int const_wanted; /* true if constant wanted */
66 ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
67 ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
68 ST_DATA CType func_vt; /* current function return type (used by return instruction) */
69 ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */
70 ST_DATA int func_vc;
71 ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
72 ST_DATA const char *funcname;
74 ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
76 ST_DATA struct switch_t {
77 struct case_t {
78 int v1, v2, sym;
79 } **p; int n; /* list of case ranges */
80 int def_sym; /* default symbol */
81 } *cur_switch; /* current switch */
83 /* ------------------------------------------------------------------------- */
84 static void gen_cast(CType *type);
85 static inline CType *pointed_type(CType *type);
86 static int is_compatible_types(CType *type1, CType *type2);
87 static int parse_btype(CType *type, AttributeDef *ad);
88 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
89 static void parse_expr_type(CType *type);
90 static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
91 static void block(int *bsym, int *csym, int is_expr);
92 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
93 static int decl0(int l, int is_for_loop_init);
94 static void expr_eq(void);
95 static void expr_lor_const(void);
96 static void unary_type(CType *type);
97 static void vla_runtime_type_size(CType *type, int *a);
98 static void vla_sp_restore(void);
99 static void vla_sp_restore_root(void);
100 static int is_compatible_parameter_types(CType *type1, CType *type2);
101 static void expr_type(CType *type);
102 ST_FUNC void vpush64(int ty, unsigned long long v);
103 ST_FUNC void vpush(CType *type);
104 ST_FUNC int gvtst(int inv, int t);
105 ST_FUNC int is_btype_size(int bt);
107 ST_INLN int is_float(int t)
109 int bt;
110 bt = t & VT_BTYPE;
111 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT;
114 /* we use our own 'finite' function to avoid potential problems with
115 non standard math libs */
116 /* XXX: endianness dependent */
117 ST_FUNC int ieee_finite(double d)
119 int p[4];
120 memcpy(p, &d, sizeof(double));
121 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
124 ST_FUNC void test_lvalue(void)
126 if (!(vtop->r & VT_LVAL))
127 expect("lvalue");
130 ST_FUNC void check_vstack(void)
132 if (pvtop != vtop)
133 tcc_error("internal compiler error: vstack leak (%d)", vtop - pvtop);
136 /* ------------------------------------------------------------------------- */
137 /* symbol allocator */
138 static Sym *__sym_malloc(void)
140 Sym *sym_pool, *sym, *last_sym;
141 int i;
143 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
144 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
146 last_sym = sym_free_first;
147 sym = sym_pool;
148 for(i = 0; i < SYM_POOL_NB; i++) {
149 sym->next = last_sym;
150 last_sym = sym;
151 sym++;
153 sym_free_first = last_sym;
154 return last_sym;
157 static inline Sym *sym_malloc(void)
159 Sym *sym;
160 sym = sym_free_first;
161 if (!sym)
162 sym = __sym_malloc();
163 sym_free_first = sym->next;
164 return sym;
167 ST_INLN void sym_free(Sym *sym)
169 sym->next = sym_free_first;
170 sym_free_first = sym;
173 /* push, without hashing */
174 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
176 Sym *s;
178 s = sym_malloc();
179 s->asm_label = 0;
180 s->v = v;
181 s->type.t = t;
182 s->type.ref = NULL;
183 #ifdef _WIN64
184 s->d = NULL;
185 #endif
186 s->c = c;
187 s->next = NULL;
188 /* add in stack */
189 s->prev = *ps;
190 *ps = s;
191 return s;
194 /* find a symbol and return its associated structure. 's' is the top
195 of the symbol stack */
196 ST_FUNC Sym *sym_find2(Sym *s, int v)
198 while (s) {
199 if (s->v == v)
200 return s;
201 else if (s->v == -1)
202 return NULL;
203 s = s->prev;
205 return NULL;
208 /* structure lookup */
209 ST_INLN Sym *struct_find(int v)
211 v -= TOK_IDENT;
212 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
213 return NULL;
214 return table_ident[v]->sym_struct;
217 /* find an identifier */
218 ST_INLN Sym *sym_find(int v)
220 v -= TOK_IDENT;
221 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
222 return NULL;
223 return table_ident[v]->sym_identifier;
226 /* push a given symbol on the symbol stack */
227 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
229 Sym *s, **ps;
230 TokenSym *ts;
232 if (local_stack)
233 ps = &local_stack;
234 else
235 ps = &global_stack;
236 s = sym_push2(ps, v, type->t, c);
237 s->type.ref = type->ref;
238 s->r = r;
239 /* don't record fields or anonymous symbols */
240 /* XXX: simplify */
241 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
242 /* record symbol in token array */
243 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
244 if (v & SYM_STRUCT)
245 ps = &ts->sym_struct;
246 else
247 ps = &ts->sym_identifier;
248 s->prev_tok = *ps;
249 *ps = s;
250 s->scope = local_scope;
251 if (s->prev_tok && s->prev_tok->scope == s->scope)
252 tcc_error("redeclaration of '%s'",
253 get_tok_str(v & ~SYM_STRUCT, NULL));
255 return s;
258 /* push a global identifier */
259 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
261 Sym *s, **ps;
262 s = sym_push2(&global_stack, v, t, c);
263 /* don't record anonymous symbol */
264 if (v < SYM_FIRST_ANOM) {
265 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
266 /* modify the top most local identifier, so that
267 sym_identifier will point to 's' when popped */
268 while (*ps != NULL)
269 ps = &(*ps)->prev_tok;
270 s->prev_tok = NULL;
271 *ps = s;
273 return s;
276 /* pop symbols until top reaches 'b' */
277 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
279 Sym *s, *ss, **ps;
280 TokenSym *ts;
281 int v;
283 s = *ptop;
284 while(s != b) {
285 ss = s->prev;
286 v = s->v;
287 /* remove symbol in token array */
288 /* XXX: simplify */
289 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
290 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
291 if (v & SYM_STRUCT)
292 ps = &ts->sym_struct;
293 else
294 ps = &ts->sym_identifier;
295 *ps = s->prev_tok;
297 sym_free(s);
298 s = ss;
300 *ptop = b;
303 static void weaken_symbol(Sym *sym)
305 sym->type.t |= VT_WEAK;
306 if (sym->c > 0) {
307 int esym_type;
308 ElfW(Sym) *esym;
310 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
311 esym_type = ELFW(ST_TYPE)(esym->st_info);
312 esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
316 static void apply_visibility(Sym *sym, CType *type)
318 int vis = sym->type.t & VT_VIS_MASK;
319 int vis2 = type->t & VT_VIS_MASK;
320 if (vis == (STV_DEFAULT << VT_VIS_SHIFT))
321 vis = vis2;
322 else if (vis2 == (STV_DEFAULT << VT_VIS_SHIFT))
324 else
325 vis = (vis < vis2) ? vis : vis2;
326 sym->type.t &= ~VT_VIS_MASK;
327 sym->type.t |= vis;
329 if (sym->c > 0) {
330 ElfW(Sym) *esym;
332 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
333 vis >>= VT_VIS_SHIFT;
334 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis;
338 /* ------------------------------------------------------------------------- */
340 ST_FUNC void swap(int *p, int *q)
342 int t;
343 t = *p;
344 *p = *q;
345 *q = t;
348 static void vsetc(CType *type, int r, CValue *vc)
350 int v;
352 if (vtop >= vstack + (VSTACK_SIZE - 1))
353 tcc_error("memory full (vstack)");
354 /* cannot let cpu flags if other instruction are generated. Also
355 avoid leaving VT_JMP anywhere except on the top of the stack
356 because it would complicate the code generator. */
357 if (vtop >= vstack) {
358 v = vtop->r & VT_VALMASK;
359 if (v == VT_CMP || (v & ~1) == VT_JMP)
360 gv(RC_INT);
362 vtop++;
363 vtop->type = *type;
364 vtop->r = r;
365 vtop->r2 = VT_CONST;
366 vtop->c = *vc;
369 /* push constant of type "type" with useless value */
370 ST_FUNC void vpush(CType *type)
372 CValue cval;
373 vsetc(type, VT_CONST, &cval);
376 /* push integer constant */
377 ST_FUNC void vpushi(int v)
379 CValue cval;
380 cval.i = v;
381 vsetc(&int_type, VT_CONST, &cval);
384 /* push a pointer sized constant */
385 static void vpushs(addr_t v)
387 CValue cval;
388 cval.i = v;
389 vsetc(&size_type, VT_CONST, &cval);
392 /* push arbitrary 64bit constant */
393 ST_FUNC void vpush64(int ty, unsigned long long v)
395 CValue cval;
396 CType ctype;
397 ctype.t = ty;
398 ctype.ref = NULL;
399 cval.i = v;
400 vsetc(&ctype, VT_CONST, &cval);
403 /* push long long constant */
404 static inline void vpushll(long long v)
406 vpush64(VT_LLONG, v);
409 /* push a symbol value of TYPE */
410 static inline void vpushsym(CType *type, Sym *sym)
412 CValue cval;
413 cval.i = 0;
414 vsetc(type, VT_CONST | VT_SYM, &cval);
415 vtop->sym = sym;
418 /* Return a static symbol pointing to a section */
419 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
421 int v;
422 Sym *sym;
424 v = anon_sym++;
425 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
426 sym->type.ref = type->ref;
427 sym->r = VT_CONST | VT_SYM;
428 put_extern_sym(sym, sec, offset, size);
429 return sym;
432 /* push a reference to a section offset by adding a dummy symbol */
433 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
435 vpushsym(type, get_sym_ref(type, sec, offset, size));
438 /* define a new external reference to a symbol 'v' of type 'u' */
439 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
441 Sym *s;
443 s = sym_find(v);
444 if (!s) {
445 /* push forward reference */
446 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
447 s->type.ref = type->ref;
448 s->r = r | VT_CONST | VT_SYM;
450 return s;
453 /* define a new external reference to a symbol 'v' */
454 static Sym *external_sym(int v, CType *type, int r)
456 Sym *s;
458 s = sym_find(v);
459 if (!s) {
460 /* push forward reference */
461 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
462 s->type.t |= VT_EXTERN;
463 } else if (s->type.ref == func_old_type.ref) {
464 s->type.ref = type->ref;
465 s->r = r | VT_CONST | VT_SYM;
466 s->type.t |= VT_EXTERN;
467 } else if (!is_compatible_types(&s->type, type)) {
468 tcc_error("incompatible types for redefinition of '%s'",
469 get_tok_str(v, NULL));
471 /* Merge some storage attributes. */
472 if (type->t & VT_WEAK)
473 weaken_symbol(s);
475 if (type->t & VT_VIS_MASK)
476 apply_visibility(s, type);
478 return s;
481 /* push a reference to global symbol v */
482 ST_FUNC void vpush_global_sym(CType *type, int v)
484 vpushsym(type, external_global_sym(v, type, 0));
487 ST_FUNC void vset(CType *type, int r, int v)
489 CValue cval;
491 cval.i = v;
492 vsetc(type, r, &cval);
495 static void vseti(int r, int v)
497 CType type;
498 type.t = VT_INT;
499 type.ref = 0;
500 vset(&type, r, v);
503 ST_FUNC void vswap(void)
505 SValue tmp;
506 /* cannot let cpu flags if other instruction are generated. Also
507 avoid leaving VT_JMP anywhere except on the top of the stack
508 because it would complicate the code generator. */
509 if (vtop >= vstack) {
510 int v = vtop->r & VT_VALMASK;
511 if (v == VT_CMP || (v & ~1) == VT_JMP)
512 gv(RC_INT);
514 tmp = vtop[0];
515 vtop[0] = vtop[-1];
516 vtop[-1] = tmp;
518 /* XXX: +2% overall speed possible with optimized memswap
520 * memswap(&vtop[0], &vtop[1], sizeof *vtop);
524 ST_FUNC void vpushv(SValue *v)
526 if (vtop >= vstack + (VSTACK_SIZE - 1))
527 tcc_error("memory full (vstack)");
528 vtop++;
529 *vtop = *v;
532 static void vdup(void)
534 vpushv(vtop);
537 /* save registers up to (vtop - n) stack entry */
538 ST_FUNC void save_regs(int n)
540 SValue *p, *p1;
541 for(p = vstack, p1 = vtop - n; p <= p1; p++)
542 save_reg(p->r);
545 /* save r to the memory stack, and mark it as being free */
546 ST_FUNC void save_reg(int r)
548 save_reg_upstack(r, 0);
551 /* save r to the memory stack, and mark it as being free,
552 if seen up to (vtop - n) stack entry */
553 ST_FUNC void save_reg_upstack(int r, int n)
555 int l, saved, size, align;
556 SValue *p, *p1, sv;
557 CType *type;
559 if ((r &= VT_VALMASK) >= VT_CONST)
560 return;
562 /* modify all stack values */
563 saved = 0;
564 l = 0;
565 for(p = vstack, p1 = vtop - n; p <= p1; p++) {
566 if ((p->r & VT_VALMASK) == r ||
567 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
568 /* must save value on stack if not already done */
569 if (!saved) {
570 /* NOTE: must reload 'r' because r might be equal to r2 */
571 r = p->r & VT_VALMASK;
572 /* store register in the stack */
573 type = &p->type;
574 if ((p->r & VT_LVAL) ||
575 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
576 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
577 type = &char_pointer_type;
578 #else
579 type = &int_type;
580 #endif
581 size = type_size(type, &align);
582 loc = (loc - size) & -align;
583 sv.type.t = type->t;
584 sv.r = VT_LOCAL | VT_LVAL;
585 sv.c.i = loc;
586 store(r, &sv);
587 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
588 /* x86 specific: need to pop fp register ST0 if saved */
589 if (r == TREG_ST0) {
590 o(0xd8dd); /* fstp %st(0) */
592 #endif
593 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
594 /* special long long case */
595 if ((type->t & VT_BTYPE) == VT_LLONG) {
596 sv.c.i += 4;
597 store(p->r2, &sv);
599 #endif
600 l = loc;
601 saved = 1;
603 /* mark that stack entry as being saved on the stack */
604 if (p->r & VT_LVAL) {
605 /* also clear the bounded flag because the
606 relocation address of the function was stored in
607 p->c.i */
608 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
609 } else {
610 p->r = lvalue_type(p->type.t) | VT_LOCAL;
612 p->r2 = VT_CONST;
613 p->c.i = l;
618 #ifdef TCC_TARGET_ARM
619 /* find a register of class 'rc2' with at most one reference on stack.
620 * If none, call get_reg(rc) */
621 ST_FUNC int get_reg_ex(int rc, int rc2)
623 int r;
624 SValue *p;
626 for(r=0;r<NB_REGS;r++) {
627 if (reg_classes[r] & rc2) {
628 int n;
629 n=0;
630 for(p = vstack; p <= vtop; p++) {
631 if ((p->r & VT_VALMASK) == r ||
632 (p->r2 & VT_VALMASK) == r)
633 n++;
635 if (n <= 1)
636 return r;
639 return get_reg(rc);
641 #endif
643 /* find a free register of class 'rc'. If none, save one register */
644 ST_FUNC int get_reg(int rc)
646 int r;
647 SValue *p;
649 /* find a free register */
650 for(r=0;r<NB_REGS;r++) {
651 if (reg_classes[r] & rc) {
652 for(p=vstack;p<=vtop;p++) {
653 if ((p->r & VT_VALMASK) == r ||
654 (p->r2 & VT_VALMASK) == r)
655 goto notfound;
657 return r;
659 notfound: ;
662 /* no register left : free the first one on the stack (VERY
663 IMPORTANT to start from the bottom to ensure that we don't
664 spill registers used in gen_opi()) */
665 for(p=vstack;p<=vtop;p++) {
666 /* look at second register (if long long) */
667 r = p->r2 & VT_VALMASK;
668 if (r < VT_CONST && (reg_classes[r] & rc))
669 goto save_found;
670 r = p->r & VT_VALMASK;
671 if (r < VT_CONST && (reg_classes[r] & rc)) {
672 save_found:
673 save_reg(r);
674 return r;
677 /* Should never comes here */
678 return -1;
681 /* move register 's' (of type 't') to 'r', and flush previous value of r to memory
682 if needed */
683 static void move_reg(int r, int s, int t)
685 SValue sv;
687 if (r != s) {
688 save_reg(r);
689 sv.type.t = t;
690 sv.type.ref = NULL;
691 sv.r = s;
692 sv.c.i = 0;
693 load(r, &sv);
697 /* get address of vtop (vtop MUST BE an lvalue) */
698 ST_FUNC void gaddrof(void)
700 if (vtop->r & VT_REF && !nocode_wanted)
701 gv(RC_INT);
702 vtop->r &= ~VT_LVAL;
703 /* tricky: if saved lvalue, then we can go back to lvalue */
704 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
705 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
710 #ifdef CONFIG_TCC_BCHECK
711 /* generate lvalue bound code */
712 static void gbound(void)
714 int lval_type;
715 CType type1;
717 vtop->r &= ~VT_MUSTBOUND;
718 /* if lvalue, then use checking code before dereferencing */
719 if (vtop->r & VT_LVAL) {
720 /* if not VT_BOUNDED value, then make one */
721 if (!(vtop->r & VT_BOUNDED)) {
722 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
723 /* must save type because we must set it to int to get pointer */
724 type1 = vtop->type;
725 vtop->type.t = VT_PTR;
726 gaddrof();
727 vpushi(0);
728 gen_bounded_ptr_add();
729 vtop->r |= lval_type;
730 vtop->type = type1;
732 /* then check for dereferencing */
733 gen_bounded_ptr_deref();
736 #endif
738 /* store vtop a register belonging to class 'rc'. lvalues are
739 converted to values. Cannot be used if cannot be converted to
740 register value (such as structures). */
741 ST_FUNC int gv(int rc)
743 int r, bit_pos, bit_size, size, align, i;
744 int rc2;
746 /* NOTE: get_reg can modify vstack[] */
747 if (vtop->type.t & VT_BITFIELD) {
748 CType type;
749 int bits = 32;
750 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
751 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
752 /* remove bit field info to avoid loops */
753 vtop->type.t &= ~VT_BITFIELD & ((1 << VT_STRUCT_SHIFT) - 1);
754 /* cast to int to propagate signedness in following ops */
755 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
756 type.t = VT_LLONG;
757 bits = 64;
758 } else
759 type.t = VT_INT;
760 if((vtop->type.t & VT_UNSIGNED) ||
761 (vtop->type.t & VT_BTYPE) == VT_BOOL)
762 type.t |= VT_UNSIGNED;
763 gen_cast(&type);
764 /* generate shifts */
765 vpushi(bits - (bit_pos + bit_size));
766 gen_op(TOK_SHL);
767 vpushi(bits - bit_size);
768 /* NOTE: transformed to SHR if unsigned */
769 gen_op(TOK_SAR);
770 r = gv(rc);
771 } else {
772 if (is_float(vtop->type.t) &&
773 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
774 Sym *sym;
775 int *ptr;
776 unsigned long offset;
777 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
778 CValue check;
779 #endif
781 /* XXX: unify with initializers handling ? */
782 /* CPUs usually cannot use float constants, so we store them
783 generically in data segment */
784 size = type_size(&vtop->type, &align);
785 offset = (data_section->data_offset + align - 1) & -align;
786 data_section->data_offset = offset;
787 /* XXX: not portable yet */
788 #if defined(__i386__) || defined(__x86_64__)
789 /* Zero pad x87 tenbyte long doubles */
790 if (size == LDOUBLE_SIZE) {
791 vtop->c.tab[2] &= 0xffff;
792 #if LDOUBLE_SIZE == 16
793 vtop->c.tab[3] = 0;
794 #endif
796 #endif
797 ptr = section_ptr_add(data_section, size);
798 size = size >> 2;
799 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
800 check.d = 1;
801 if(check.tab[0])
802 for(i=0;i<size;i++)
803 ptr[i] = vtop->c.tab[size-1-i];
804 else
805 #endif
806 for(i=0;i<size;i++)
807 ptr[i] = vtop->c.tab[i];
808 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
809 vtop->r |= VT_LVAL | VT_SYM;
810 vtop->sym = sym;
811 vtop->c.i = 0;
813 #ifdef CONFIG_TCC_BCHECK
814 if (vtop->r & VT_MUSTBOUND)
815 gbound();
816 #endif
818 r = vtop->r & VT_VALMASK;
819 rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
820 #ifndef TCC_TARGET_ARM64
821 if (rc == RC_IRET)
822 rc2 = RC_LRET;
823 #ifdef TCC_TARGET_X86_64
824 else if (rc == RC_FRET)
825 rc2 = RC_QRET;
826 #endif
827 #endif
829 /* need to reload if:
830 - constant
831 - lvalue (need to dereference pointer)
832 - already a register, but not in the right class */
833 if (r >= VT_CONST
834 || (vtop->r & VT_LVAL)
835 || !(reg_classes[r] & rc)
836 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
837 || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
838 || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
839 #else
840 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
841 #endif
844 r = get_reg(rc);
845 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
846 if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
847 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
848 #else
849 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
850 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
851 unsigned long long ll;
852 #endif
853 int r2, original_type;
854 original_type = vtop->type.t;
855 /* two register type load : expand to two words
856 temporarily */
857 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
858 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
859 /* load constant */
860 ll = vtop->c.i;
861 vtop->c.i = ll; /* first word */
862 load(r, vtop);
863 vtop->r = r; /* save register value */
864 vpushi(ll >> 32); /* second word */
865 } else
866 #endif
867 if (vtop->r & VT_LVAL) {
868 /* We do not want to modifier the long long
869 pointer here, so the safest (and less
870 efficient) is to save all the other registers
871 in the stack. XXX: totally inefficient. */
872 #if 0
873 save_regs(1);
874 #else
875 /* lvalue_save: save only if used further down the stack */
876 save_reg_upstack(vtop->r, 1);
877 #endif
878 /* load from memory */
879 vtop->type.t = load_type;
880 load(r, vtop);
881 vdup();
882 vtop[-1].r = r; /* save register value */
883 /* increment pointer to get second word */
884 vtop->type.t = addr_type;
885 gaddrof();
886 vpushi(load_size);
887 gen_op('+');
888 vtop->r |= VT_LVAL;
889 vtop->type.t = load_type;
890 } else {
891 /* move registers */
892 load(r, vtop);
893 vdup();
894 vtop[-1].r = r; /* save register value */
895 vtop->r = vtop[-1].r2;
897 /* Allocate second register. Here we rely on the fact that
898 get_reg() tries first to free r2 of an SValue. */
899 r2 = get_reg(rc2);
900 load(r2, vtop);
901 vpop();
902 /* write second register */
903 vtop->r2 = r2;
904 vtop->type.t = original_type;
905 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
906 int t1, t;
907 /* lvalue of scalar type : need to use lvalue type
908 because of possible cast */
909 t = vtop->type.t;
910 t1 = t;
911 /* compute memory access type */
912 if (vtop->r & VT_REF)
913 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
914 t = VT_PTR;
915 #else
916 t = VT_INT;
917 #endif
918 else if (vtop->r & VT_LVAL_BYTE)
919 t = VT_BYTE;
920 else if (vtop->r & VT_LVAL_SHORT)
921 t = VT_SHORT;
922 if (vtop->r & VT_LVAL_UNSIGNED)
923 t |= VT_UNSIGNED;
924 vtop->type.t = t;
925 load(r, vtop);
926 /* restore wanted type */
927 vtop->type.t = t1;
928 } else {
929 /* one register type load */
930 load(r, vtop);
933 vtop->r = r;
934 #ifdef TCC_TARGET_C67
935 /* uses register pairs for doubles */
936 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
937 vtop->r2 = r+1;
938 #endif
940 return r;
943 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
944 ST_FUNC void gv2(int rc1, int rc2)
946 int v;
948 /* generate more generic register first. But VT_JMP or VT_CMP
949 values must be generated first in all cases to avoid possible
950 reload errors */
951 v = vtop[0].r & VT_VALMASK;
952 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
953 vswap();
954 gv(rc1);
955 vswap();
956 gv(rc2);
957 /* test if reload is needed for first register */
958 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
959 vswap();
960 gv(rc1);
961 vswap();
963 } else {
964 gv(rc2);
965 vswap();
966 gv(rc1);
967 vswap();
968 /* test if reload is needed for first register */
969 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
970 gv(rc2);
975 #ifndef TCC_TARGET_ARM64
976 /* wrapper around RC_FRET to return a register by type */
977 static int rc_fret(int t)
979 #ifdef TCC_TARGET_X86_64
980 if (t == VT_LDOUBLE) {
981 return RC_ST0;
983 #endif
984 return RC_FRET;
986 #endif
988 /* wrapper around REG_FRET to return a register by type */
989 static int reg_fret(int t)
991 #ifdef TCC_TARGET_X86_64
992 if (t == VT_LDOUBLE) {
993 return TREG_ST0;
995 #endif
996 return REG_FRET;
999 /* expand long long on stack in two int registers */
1000 static void lexpand(void)
1002 int u;
1004 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
1005 gv(RC_INT);
1006 vdup();
1007 vtop[0].r = vtop[-1].r2;
1008 vtop[0].r2 = VT_CONST;
1009 vtop[-1].r2 = VT_CONST;
1010 vtop[0].type.t = VT_INT | u;
1011 vtop[-1].type.t = VT_INT | u;
1014 #ifdef TCC_TARGET_ARM
1015 /* expand long long on stack */
1016 ST_FUNC void lexpand_nr(void)
1018 int u,v;
1020 u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
1021 vdup();
1022 vtop->r2 = VT_CONST;
1023 vtop->type.t = VT_INT | u;
1024 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
1025 if (v == VT_CONST) {
1026 vtop[-1].c.i = vtop->c.i;
1027 vtop->c.i = vtop->c.i >> 32;
1028 vtop->r = VT_CONST;
1029 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
1030 vtop->c.i += 4;
1031 vtop->r = vtop[-1].r;
1032 } else if (v > VT_CONST) {
1033 vtop--;
1034 lexpand();
1035 } else
1036 vtop->r = vtop[-1].r2;
1037 vtop[-1].r2 = VT_CONST;
1038 vtop[-1].type.t = VT_INT | u;
1040 #endif
1042 /* build a long long from two ints */
1043 static void lbuild(int t)
1045 gv2(RC_INT, RC_INT);
1046 vtop[-1].r2 = vtop[0].r;
1047 vtop[-1].type.t = t;
1048 vpop();
1051 /* rotate n first stack elements to the bottom
1052 I1 ... In -> I2 ... In I1 [top is right]
1054 ST_FUNC void vrotb(int n)
1056 int i;
1057 SValue tmp;
1059 tmp = vtop[-n + 1];
1060 for(i=-n+1;i!=0;i++)
1061 vtop[i] = vtop[i+1];
1062 vtop[0] = tmp;
1065 /* rotate the n elements before entry e towards the top
1066 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
1068 ST_FUNC void vrote(SValue *e, int n)
1070 int i;
1071 SValue tmp;
1073 tmp = *e;
1074 for(i = 0;i < n - 1; i++)
1075 e[-i] = e[-i - 1];
1076 e[-n + 1] = tmp;
1079 /* rotate n first stack elements to the top
1080 I1 ... In -> In I1 ... I(n-1) [top is right]
1082 ST_FUNC void vrott(int n)
1084 vrote(vtop, n);
1087 /* pop stack value */
1088 ST_FUNC void vpop(void)
1090 int v;
1091 v = vtop->r & VT_VALMASK;
1092 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1093 /* for x86, we need to pop the FP stack */
1094 if (v == TREG_ST0 && !nocode_wanted) {
1095 o(0xd8dd); /* fstp %st(0) */
1096 } else
1097 #endif
1098 if (v == VT_JMP || v == VT_JMPI) {
1099 /* need to put correct jump if && or || without test */
1100 gsym(vtop->c.i);
1102 vtop--;
1105 /* convert stack entry to register and duplicate its value in another
1106 register */
1107 static void gv_dup(void)
1109 int rc, t, r, r1;
1110 SValue sv;
1112 t = vtop->type.t;
1113 if ((t & VT_BTYPE) == VT_LLONG) {
1114 lexpand();
1115 gv_dup();
1116 vswap();
1117 vrotb(3);
1118 gv_dup();
1119 vrotb(4);
1120 /* stack: H L L1 H1 */
1121 lbuild(t);
1122 vrotb(3);
1123 vrotb(3);
1124 vswap();
1125 lbuild(t);
1126 vswap();
1127 } else {
1128 /* duplicate value */
1129 rc = RC_INT;
1130 sv.type.t = VT_INT;
1131 if (is_float(t)) {
1132 rc = RC_FLOAT;
1133 #ifdef TCC_TARGET_X86_64
1134 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1135 rc = RC_ST0;
1137 #endif
1138 sv.type.t = t;
1140 r = gv(rc);
1141 r1 = get_reg(rc);
1142 sv.r = r;
1143 sv.c.i = 0;
1144 load(r1, &sv); /* move r to r1 */
1145 vdup();
1146 /* duplicates value */
1147 if (r != r1)
1148 vtop->r = r1;
1152 /* Generate value test
1154 * Generate a test for any value (jump, comparison and integers) */
1155 ST_FUNC int gvtst(int inv, int t)
1157 int v = vtop->r & VT_VALMASK;
1158 if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) {
1159 vpushi(0);
1160 gen_op(TOK_NE);
1162 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1163 /* constant jmp optimization */
1164 if ((vtop->c.i != 0) != inv)
1165 t = gjmp(t);
1166 vtop--;
1167 return t;
1169 return gtst(inv, t);
1172 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
1173 /* generate CPU independent (unsigned) long long operations */
1174 static void gen_opl(int op)
1176 int t, a, b, op1, c, i;
1177 int func;
1178 unsigned short reg_iret = REG_IRET;
1179 unsigned short reg_lret = REG_LRET;
1180 SValue tmp;
1182 switch(op) {
1183 case '/':
1184 case TOK_PDIV:
1185 func = TOK___divdi3;
1186 goto gen_func;
1187 case TOK_UDIV:
1188 func = TOK___udivdi3;
1189 goto gen_func;
1190 case '%':
1191 func = TOK___moddi3;
1192 goto gen_mod_func;
1193 case TOK_UMOD:
1194 func = TOK___umoddi3;
1195 gen_mod_func:
1196 #ifdef TCC_ARM_EABI
1197 reg_iret = TREG_R2;
1198 reg_lret = TREG_R3;
1199 #endif
1200 gen_func:
1201 /* call generic long long function */
1202 vpush_global_sym(&func_old_type, func);
1203 vrott(3);
1204 gfunc_call(2);
1205 vpushi(0);
1206 vtop->r = reg_iret;
1207 vtop->r2 = reg_lret;
1208 break;
1209 case '^':
1210 case '&':
1211 case '|':
1212 case '*':
1213 case '+':
1214 case '-':
1215 t = vtop->type.t;
1216 vswap();
1217 lexpand();
1218 vrotb(3);
1219 lexpand();
1220 /* stack: L1 H1 L2 H2 */
1221 tmp = vtop[0];
1222 vtop[0] = vtop[-3];
1223 vtop[-3] = tmp;
1224 tmp = vtop[-2];
1225 vtop[-2] = vtop[-3];
1226 vtop[-3] = tmp;
1227 vswap();
1228 /* stack: H1 H2 L1 L2 */
1229 if (op == '*') {
1230 vpushv(vtop - 1);
1231 vpushv(vtop - 1);
1232 gen_op(TOK_UMULL);
1233 lexpand();
1234 /* stack: H1 H2 L1 L2 ML MH */
1235 for(i=0;i<4;i++)
1236 vrotb(6);
1237 /* stack: ML MH H1 H2 L1 L2 */
1238 tmp = vtop[0];
1239 vtop[0] = vtop[-2];
1240 vtop[-2] = tmp;
1241 /* stack: ML MH H1 L2 H2 L1 */
1242 gen_op('*');
1243 vrotb(3);
1244 vrotb(3);
1245 gen_op('*');
1246 /* stack: ML MH M1 M2 */
1247 gen_op('+');
1248 gen_op('+');
1249 } else if (op == '+' || op == '-') {
1250 /* XXX: add non carry method too (for MIPS or alpha) */
1251 if (op == '+')
1252 op1 = TOK_ADDC1;
1253 else
1254 op1 = TOK_SUBC1;
1255 gen_op(op1);
1256 /* stack: H1 H2 (L1 op L2) */
1257 vrotb(3);
1258 vrotb(3);
1259 gen_op(op1 + 1); /* TOK_xxxC2 */
1260 } else {
1261 gen_op(op);
1262 /* stack: H1 H2 (L1 op L2) */
1263 vrotb(3);
1264 vrotb(3);
1265 /* stack: (L1 op L2) H1 H2 */
1266 gen_op(op);
1267 /* stack: (L1 op L2) (H1 op H2) */
1269 /* stack: L H */
1270 lbuild(t);
1271 break;
1272 case TOK_SAR:
1273 case TOK_SHR:
1274 case TOK_SHL:
1275 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1276 t = vtop[-1].type.t;
1277 vswap();
1278 lexpand();
1279 vrotb(3);
1280 /* stack: L H shift */
1281 c = (int)vtop->c.i;
1282 /* constant: simpler */
1283 /* NOTE: all comments are for SHL. the other cases are
1284 done by swaping words */
1285 vpop();
1286 if (op != TOK_SHL)
1287 vswap();
1288 if (c >= 32) {
1289 /* stack: L H */
1290 vpop();
1291 if (c > 32) {
1292 vpushi(c - 32);
1293 gen_op(op);
1295 if (op != TOK_SAR) {
1296 vpushi(0);
1297 } else {
1298 gv_dup();
1299 vpushi(31);
1300 gen_op(TOK_SAR);
1302 vswap();
1303 } else {
1304 vswap();
1305 gv_dup();
1306 /* stack: H L L */
1307 vpushi(c);
1308 gen_op(op);
1309 vswap();
1310 vpushi(32 - c);
1311 if (op == TOK_SHL)
1312 gen_op(TOK_SHR);
1313 else
1314 gen_op(TOK_SHL);
1315 vrotb(3);
1316 /* stack: L L H */
1317 vpushi(c);
1318 if (op == TOK_SHL)
1319 gen_op(TOK_SHL);
1320 else
1321 gen_op(TOK_SHR);
1322 gen_op('|');
1324 if (op != TOK_SHL)
1325 vswap();
1326 lbuild(t);
1327 } else {
1328 /* XXX: should provide a faster fallback on x86 ? */
1329 switch(op) {
1330 case TOK_SAR:
1331 func = TOK___ashrdi3;
1332 goto gen_func;
1333 case TOK_SHR:
1334 func = TOK___lshrdi3;
1335 goto gen_func;
1336 case TOK_SHL:
1337 func = TOK___ashldi3;
1338 goto gen_func;
1341 break;
1342 default:
1343 /* compare operations */
1344 t = vtop->type.t;
1345 vswap();
1346 lexpand();
1347 vrotb(3);
1348 lexpand();
1349 /* stack: L1 H1 L2 H2 */
1350 tmp = vtop[-1];
1351 vtop[-1] = vtop[-2];
1352 vtop[-2] = tmp;
1353 /* stack: L1 L2 H1 H2 */
1354 /* compare high */
1355 op1 = op;
1356 /* when values are equal, we need to compare low words. since
1357 the jump is inverted, we invert the test too. */
1358 if (op1 == TOK_LT)
1359 op1 = TOK_LE;
1360 else if (op1 == TOK_GT)
1361 op1 = TOK_GE;
1362 else if (op1 == TOK_ULT)
1363 op1 = TOK_ULE;
1364 else if (op1 == TOK_UGT)
1365 op1 = TOK_UGE;
1366 a = 0;
1367 b = 0;
1368 gen_op(op1);
1369 if (op1 != TOK_NE) {
1370 a = gvtst(1, 0);
1372 if (op != TOK_EQ) {
1373 /* generate non equal test */
1374 /* XXX: NOT PORTABLE yet */
1375 if (a == 0) {
1376 b = gvtst(0, 0);
1377 } else {
1378 #if defined(TCC_TARGET_I386)
1379 b = psym(0x850f, 0);
1380 #elif defined(TCC_TARGET_ARM)
1381 b = ind;
1382 o(0x1A000000 | encbranch(ind, 0, 1));
1383 #elif defined(TCC_TARGET_C67) || defined(TCC_TARGET_ARM64)
1384 tcc_error("not implemented");
1385 #else
1386 #error not supported
1387 #endif
1390 /* compare low. Always unsigned */
1391 op1 = op;
1392 if (op1 == TOK_LT)
1393 op1 = TOK_ULT;
1394 else if (op1 == TOK_LE)
1395 op1 = TOK_ULE;
1396 else if (op1 == TOK_GT)
1397 op1 = TOK_UGT;
1398 else if (op1 == TOK_GE)
1399 op1 = TOK_UGE;
1400 gen_op(op1);
1401 a = gvtst(1, a);
1402 gsym(b);
1403 vseti(VT_JMPI, a);
1404 break;
1407 #endif
1409 static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b)
1411 uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b);
1412 return (a ^ b) >> 63 ? -x : x;
1415 static int gen_opic_lt(uint64_t a, uint64_t b)
1417 return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63);
1420 /* handle integer constant optimizations and various machine
1421 independent opt */
1422 static void gen_opic(int op)
1424 SValue *v1 = vtop - 1;
1425 SValue *v2 = vtop;
1426 int t1 = v1->type.t & VT_BTYPE;
1427 int t2 = v2->type.t & VT_BTYPE;
1428 int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1429 int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1430 uint64_t l1 = c1 ? v1->c.i : 0;
1431 uint64_t l2 = c2 ? v2->c.i : 0;
1432 int shm = (t1 == VT_LLONG) ? 63 : 31;
1434 if (t1 != VT_LLONG)
1435 l1 = ((uint32_t)l1 |
1436 (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
1437 if (t2 != VT_LLONG)
1438 l2 = ((uint32_t)l2 |
1439 (v2->type.t & VT_UNSIGNED ? 0 : -(l2 & 0x80000000)));
1441 if (c1 && c2) {
1442 switch(op) {
1443 case '+': l1 += l2; break;
1444 case '-': l1 -= l2; break;
1445 case '&': l1 &= l2; break;
1446 case '^': l1 ^= l2; break;
1447 case '|': l1 |= l2; break;
1448 case '*': l1 *= l2; break;
1450 case TOK_PDIV:
1451 case '/':
1452 case '%':
1453 case TOK_UDIV:
1454 case TOK_UMOD:
1455 /* if division by zero, generate explicit division */
1456 if (l2 == 0) {
1457 if (const_wanted)
1458 tcc_error("division by zero in constant");
1459 goto general_case;
1461 switch(op) {
1462 default: l1 = gen_opic_sdiv(l1, l2); break;
1463 case '%': l1 = l1 - l2 * gen_opic_sdiv(l1, l2); break;
1464 case TOK_UDIV: l1 = l1 / l2; break;
1465 case TOK_UMOD: l1 = l1 % l2; break;
1467 break;
1468 case TOK_SHL: l1 <<= (l2 & shm); break;
1469 case TOK_SHR: l1 >>= (l2 & shm); break;
1470 case TOK_SAR:
1471 l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
1472 break;
1473 /* tests */
1474 case TOK_ULT: l1 = l1 < l2; break;
1475 case TOK_UGE: l1 = l1 >= l2; break;
1476 case TOK_EQ: l1 = l1 == l2; break;
1477 case TOK_NE: l1 = l1 != l2; break;
1478 case TOK_ULE: l1 = l1 <= l2; break;
1479 case TOK_UGT: l1 = l1 > l2; break;
1480 case TOK_LT: l1 = gen_opic_lt(l1, l2); break;
1481 case TOK_GE: l1 = !gen_opic_lt(l1, l2); break;
1482 case TOK_LE: l1 = !gen_opic_lt(l2, l1); break;
1483 case TOK_GT: l1 = gen_opic_lt(l2, l1); break;
1484 /* logical */
1485 case TOK_LAND: l1 = l1 && l2; break;
1486 case TOK_LOR: l1 = l1 || l2; break;
1487 default:
1488 goto general_case;
1490 v1->c.i = l1;
1491 vtop--;
1492 } else {
1493 /* if commutative ops, put c2 as constant */
1494 if (c1 && (op == '+' || op == '&' || op == '^' ||
1495 op == '|' || op == '*')) {
1496 vswap();
1497 c2 = c1; //c = c1, c1 = c2, c2 = c;
1498 l2 = l1; //l = l1, l1 = l2, l2 = l;
1500 if (!const_wanted &&
1501 c1 && ((l1 == 0 &&
1502 (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||
1503 (l1 == -1 && op == TOK_SAR))) {
1504 /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
1505 vtop--;
1506 } else if (!const_wanted &&
1507 c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
1508 (l2 == -1 && op == '|') ||
1509 (l2 == 0xffffffff && t2 != VT_LLONG && op == '|') ||
1510 (l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
1511 /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
1512 if (l2 == 1)
1513 vtop->c.i = 0;
1514 vswap();
1515 vtop--;
1516 } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1517 op == TOK_PDIV) &&
1518 l2 == 1) ||
1519 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1520 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1521 l2 == 0) ||
1522 (op == '&' &&
1523 l2 == -1))) {
1524 /* filter out NOP operations like x*1, x-0, x&-1... */
1525 vtop--;
1526 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1527 /* try to use shifts instead of muls or divs */
1528 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1529 int n = -1;
1530 while (l2) {
1531 l2 >>= 1;
1532 n++;
1534 vtop->c.i = n;
1535 if (op == '*')
1536 op = TOK_SHL;
1537 else if (op == TOK_PDIV)
1538 op = TOK_SAR;
1539 else
1540 op = TOK_SHR;
1542 goto general_case;
1543 } else if (c2 && (op == '+' || op == '-') &&
1544 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1545 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1546 /* symbol + constant case */
1547 if (op == '-')
1548 l2 = -l2;
1549 vtop--;
1550 vtop->c.i += l2;
1551 } else {
1552 general_case:
1553 if (!nocode_wanted) {
1554 /* call low level op generator */
1555 if (t1 == VT_LLONG || t2 == VT_LLONG ||
1556 (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR)))
1557 gen_opl(op);
1558 else
1559 gen_opi(op);
1560 } else {
1561 vtop--;
1567 /* generate a floating point operation with constant propagation */
1568 static void gen_opif(int op)
1570 int c1, c2;
1571 SValue *v1, *v2;
1572 long double f1, f2;
1574 v1 = vtop - 1;
1575 v2 = vtop;
1576 /* currently, we cannot do computations with forward symbols */
1577 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1578 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1579 if (c1 && c2) {
1580 if (v1->type.t == VT_FLOAT) {
1581 f1 = v1->c.f;
1582 f2 = v2->c.f;
1583 } else if (v1->type.t == VT_DOUBLE) {
1584 f1 = v1->c.d;
1585 f2 = v2->c.d;
1586 } else {
1587 f1 = v1->c.ld;
1588 f2 = v2->c.ld;
1591 /* NOTE: we only do constant propagation if finite number (not
1592 NaN or infinity) (ANSI spec) */
1593 if (!ieee_finite(f1) || !ieee_finite(f2))
1594 goto general_case;
1596 switch(op) {
1597 case '+': f1 += f2; break;
1598 case '-': f1 -= f2; break;
1599 case '*': f1 *= f2; break;
1600 case '/':
1601 if (f2 == 0.0) {
1602 if (const_wanted)
1603 tcc_error("division by zero in constant");
1604 goto general_case;
1606 f1 /= f2;
1607 break;
1608 /* XXX: also handles tests ? */
1609 default:
1610 goto general_case;
1612 /* XXX: overflow test ? */
1613 if (v1->type.t == VT_FLOAT) {
1614 v1->c.f = f1;
1615 } else if (v1->type.t == VT_DOUBLE) {
1616 v1->c.d = f1;
1617 } else {
1618 v1->c.ld = f1;
1620 vtop--;
1621 } else {
1622 general_case:
1623 if (!nocode_wanted) {
1624 gen_opf(op);
1625 } else {
1626 vtop--;
1631 static int pointed_size(CType *type)
1633 int align;
1634 return type_size(pointed_type(type), &align);
1637 static void vla_runtime_pointed_size(CType *type)
1639 int align;
1640 vla_runtime_type_size(pointed_type(type), &align);
1643 static inline int is_null_pointer(SValue *p)
1645 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1646 return 0;
1647 return ((p->type.t & VT_BTYPE) == VT_INT && (uint32_t)p->c.i == 0) ||
1648 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.i == 0) ||
1649 ((p->type.t & VT_BTYPE) == VT_PTR &&
1650 (PTR_SIZE == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0));
1653 static inline int is_integer_btype(int bt)
1655 return (bt == VT_BYTE || bt == VT_SHORT ||
1656 bt == VT_INT || bt == VT_LLONG);
1659 /* check types for comparison or subtraction of pointers */
1660 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1662 CType *type1, *type2, tmp_type1, tmp_type2;
1663 int bt1, bt2;
1665 /* null pointers are accepted for all comparisons as gcc */
1666 if (is_null_pointer(p1) || is_null_pointer(p2))
1667 return;
1668 type1 = &p1->type;
1669 type2 = &p2->type;
1670 bt1 = type1->t & VT_BTYPE;
1671 bt2 = type2->t & VT_BTYPE;
1672 /* accept comparison between pointer and integer with a warning */
1673 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1674 if (op != TOK_LOR && op != TOK_LAND )
1675 tcc_warning("comparison between pointer and integer");
1676 return;
1679 /* both must be pointers or implicit function pointers */
1680 if (bt1 == VT_PTR) {
1681 type1 = pointed_type(type1);
1682 } else if (bt1 != VT_FUNC)
1683 goto invalid_operands;
1685 if (bt2 == VT_PTR) {
1686 type2 = pointed_type(type2);
1687 } else if (bt2 != VT_FUNC) {
1688 invalid_operands:
1689 tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
1691 if ((type1->t & VT_BTYPE) == VT_VOID ||
1692 (type2->t & VT_BTYPE) == VT_VOID)
1693 return;
1694 tmp_type1 = *type1;
1695 tmp_type2 = *type2;
1696 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1697 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1698 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1699 /* gcc-like error if '-' is used */
1700 if (op == '-')
1701 goto invalid_operands;
1702 else
1703 tcc_warning("comparison of distinct pointer types lacks a cast");
1707 /* generic gen_op: handles types problems */
1708 ST_FUNC void gen_op(int op)
1710 int u, t1, t2, bt1, bt2, t;
1711 CType type1;
1713 t1 = vtop[-1].type.t;
1714 t2 = vtop[0].type.t;
1715 bt1 = t1 & VT_BTYPE;
1716 bt2 = t2 & VT_BTYPE;
1718 if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
1719 tcc_error("operation on a struct");
1720 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
1721 /* at least one operand is a pointer */
1722 /* relationnal op: must be both pointers */
1723 if (op >= TOK_ULT && op <= TOK_LOR) {
1724 check_comparison_pointer_types(vtop - 1, vtop, op);
1725 /* pointers are handled are unsigned */
1726 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1727 t = VT_LLONG | VT_UNSIGNED;
1728 #else
1729 t = VT_INT | VT_UNSIGNED;
1730 #endif
1731 goto std_op;
1733 /* if both pointers, then it must be the '-' op */
1734 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1735 if (op != '-')
1736 tcc_error("cannot use pointers here");
1737 check_comparison_pointer_types(vtop - 1, vtop, op);
1738 /* XXX: check that types are compatible */
1739 if (vtop[-1].type.t & VT_VLA) {
1740 vla_runtime_pointed_size(&vtop[-1].type);
1741 } else {
1742 vpushi(pointed_size(&vtop[-1].type));
1744 vrott(3);
1745 gen_opic(op);
1746 /* set to integer type */
1747 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1748 vtop->type.t = VT_LLONG;
1749 #else
1750 vtop->type.t = VT_INT;
1751 #endif
1752 vswap();
1753 gen_op(TOK_PDIV);
1754 } else {
1755 /* exactly one pointer : must be '+' or '-'. */
1756 if (op != '-' && op != '+')
1757 tcc_error("cannot use pointers here");
1758 /* Put pointer as first operand */
1759 if (bt2 == VT_PTR) {
1760 vswap();
1761 swap(&t1, &t2);
1763 type1 = vtop[-1].type;
1764 type1.t &= ~VT_ARRAY;
1765 if (vtop[-1].type.t & VT_VLA)
1766 vla_runtime_pointed_size(&vtop[-1].type);
1767 else {
1768 u = pointed_size(&vtop[-1].type);
1769 if (u < 0)
1770 tcc_error("unknown array element size");
1771 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1772 vpushll(u);
1773 #else
1774 /* XXX: cast to int ? (long long case) */
1775 vpushi(u);
1776 #endif
1778 gen_op('*');
1779 #if 0
1780 /* #ifdef CONFIG_TCC_BCHECK
1781 The main reason to removing this code:
1782 #include <stdio.h>
1783 int main ()
1785 int v[10];
1786 int i = 10;
1787 int j = 9;
1788 fprintf(stderr, "v+i-j = %p\n", v+i-j);
1789 fprintf(stderr, "v+(i-j) = %p\n", v+(i-j));
1791 When this code is on. then the output looks like
1792 v+i-j = 0xfffffffe
1793 v+(i-j) = 0xbff84000
1795 /* if evaluating constant expression, no code should be
1796 generated, so no bound check */
1797 if (tcc_state->do_bounds_check && !const_wanted) {
1798 /* if bounded pointers, we generate a special code to
1799 test bounds */
1800 if (op == '-') {
1801 vpushi(0);
1802 vswap();
1803 gen_op('-');
1805 gen_bounded_ptr_add();
1806 } else
1807 #endif
1809 gen_opic(op);
1811 /* put again type if gen_opic() swaped operands */
1812 vtop->type = type1;
1814 } else if (is_float(bt1) || is_float(bt2)) {
1815 /* compute bigger type and do implicit casts */
1816 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1817 t = VT_LDOUBLE;
1818 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1819 t = VT_DOUBLE;
1820 } else {
1821 t = VT_FLOAT;
1823 /* floats can only be used for a few operations */
1824 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1825 (op < TOK_ULT || op > TOK_GT))
1826 tcc_error("invalid operands for binary operation");
1827 goto std_op;
1828 } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
1829 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
1830 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (t | VT_UNSIGNED))
1831 t |= VT_UNSIGNED;
1832 goto std_op;
1833 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1834 /* cast to biggest op */
1835 t = VT_LLONG;
1836 /* convert to unsigned if it does not fit in a long long */
1837 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1838 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1839 t |= VT_UNSIGNED;
1840 goto std_op;
1841 } else {
1842 /* integer operations */
1843 t = VT_INT;
1844 /* convert to unsigned if it does not fit in an integer */
1845 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1846 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1847 t |= VT_UNSIGNED;
1848 std_op:
1849 /* XXX: currently, some unsigned operations are explicit, so
1850 we modify them here */
1851 if (t & VT_UNSIGNED) {
1852 if (op == TOK_SAR)
1853 op = TOK_SHR;
1854 else if (op == '/')
1855 op = TOK_UDIV;
1856 else if (op == '%')
1857 op = TOK_UMOD;
1858 else if (op == TOK_LT)
1859 op = TOK_ULT;
1860 else if (op == TOK_GT)
1861 op = TOK_UGT;
1862 else if (op == TOK_LE)
1863 op = TOK_ULE;
1864 else if (op == TOK_GE)
1865 op = TOK_UGE;
1867 vswap();
1868 type1.t = t;
1869 gen_cast(&type1);
1870 vswap();
1871 /* special case for shifts and long long: we keep the shift as
1872 an integer */
1873 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1874 type1.t = VT_INT;
1875 gen_cast(&type1);
1876 if (is_float(t))
1877 gen_opif(op);
1878 else
1879 gen_opic(op);
1880 if (op >= TOK_ULT && op <= TOK_GT) {
1881 /* relationnal op: the result is an int */
1882 vtop->type.t = VT_INT;
1883 } else {
1884 vtop->type.t = t;
1887 // Make sure that we have converted to an rvalue:
1888 if (vtop->r & VT_LVAL && !nocode_wanted)
1889 gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT);
1892 #ifndef TCC_TARGET_ARM
1893 /* generic itof for unsigned long long case */
1894 static void gen_cvt_itof1(int t)
1896 #ifdef TCC_TARGET_ARM64
1897 gen_cvt_itof(t);
1898 #else
1899 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1900 (VT_LLONG | VT_UNSIGNED)) {
1902 if (t == VT_FLOAT)
1903 vpush_global_sym(&func_old_type, TOK___floatundisf);
1904 #if LDOUBLE_SIZE != 8
1905 else if (t == VT_LDOUBLE)
1906 vpush_global_sym(&func_old_type, TOK___floatundixf);
1907 #endif
1908 else
1909 vpush_global_sym(&func_old_type, TOK___floatundidf);
1910 vrott(2);
1911 gfunc_call(1);
1912 vpushi(0);
1913 vtop->r = reg_fret(t);
1914 } else {
1915 gen_cvt_itof(t);
1917 #endif
1919 #endif
1921 /* generic ftoi for unsigned long long case */
1922 static void gen_cvt_ftoi1(int t)
1924 #ifdef TCC_TARGET_ARM64
1925 gen_cvt_ftoi(t);
1926 #else
1927 int st;
1929 if (t == (VT_LLONG | VT_UNSIGNED)) {
1930 /* not handled natively */
1931 st = vtop->type.t & VT_BTYPE;
1932 if (st == VT_FLOAT)
1933 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1934 #if LDOUBLE_SIZE != 8
1935 else if (st == VT_LDOUBLE)
1936 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1937 #endif
1938 else
1939 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1940 vrott(2);
1941 gfunc_call(1);
1942 vpushi(0);
1943 vtop->r = REG_IRET;
1944 vtop->r2 = REG_LRET;
1945 } else {
1946 gen_cvt_ftoi(t);
1948 #endif
1951 /* force char or short cast */
1952 static void force_charshort_cast(int t)
1954 int bits, dbt;
1955 dbt = t & VT_BTYPE;
1956 /* XXX: add optimization if lvalue : just change type and offset */
1957 if (dbt == VT_BYTE)
1958 bits = 8;
1959 else
1960 bits = 16;
1961 if (t & VT_UNSIGNED) {
1962 vpushi((1 << bits) - 1);
1963 gen_op('&');
1964 } else {
1965 if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
1966 bits = 64 - bits;
1967 else
1968 bits = 32 - bits;
1969 vpushi(bits);
1970 gen_op(TOK_SHL);
1971 /* result must be signed or the SAR is converted to an SHL
1972 This was not the case when "t" was a signed short
1973 and the last value on the stack was an unsigned int */
1974 vtop->type.t &= ~VT_UNSIGNED;
1975 vpushi(bits);
1976 gen_op(TOK_SAR);
1980 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1981 static void gen_cast(CType *type)
1983 int sbt, dbt, sf, df, c, p;
1985 /* special delayed cast for char/short */
1986 /* XXX: in some cases (multiple cascaded casts), it may still
1987 be incorrect */
1988 if (vtop->r & VT_MUSTCAST) {
1989 vtop->r &= ~VT_MUSTCAST;
1990 force_charshort_cast(vtop->type.t);
1993 /* bitfields first get cast to ints */
1994 if (vtop->type.t & VT_BITFIELD && !nocode_wanted) {
1995 gv(RC_INT);
1998 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1999 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
2001 if (sbt != dbt) {
2002 sf = is_float(sbt);
2003 df = is_float(dbt);
2004 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
2005 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
2006 if (c) {
2007 /* constant case: we can do it now */
2008 /* XXX: in ISOC, cannot do it if error in convert */
2009 if (sbt == VT_FLOAT)
2010 vtop->c.ld = vtop->c.f;
2011 else if (sbt == VT_DOUBLE)
2012 vtop->c.ld = vtop->c.d;
2014 if (df) {
2015 if ((sbt & VT_BTYPE) == VT_LLONG) {
2016 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 63))
2017 vtop->c.ld = vtop->c.i;
2018 else
2019 vtop->c.ld = -(long double)-vtop->c.i;
2020 } else if(!sf) {
2021 if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 31))
2022 vtop->c.ld = (uint32_t)vtop->c.i;
2023 else
2024 vtop->c.ld = -(long double)-(uint32_t)vtop->c.i;
2027 if (dbt == VT_FLOAT)
2028 vtop->c.f = (float)vtop->c.ld;
2029 else if (dbt == VT_DOUBLE)
2030 vtop->c.d = (double)vtop->c.ld;
2031 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
2032 vtop->c.i = vtop->c.ld;
2033 } else if (sf && dbt == VT_BOOL) {
2034 vtop->c.i = (vtop->c.ld != 0);
2035 } else {
2036 if(sf)
2037 vtop->c.i = vtop->c.ld;
2038 else if (sbt == (VT_LLONG|VT_UNSIGNED))
2040 else if (sbt & VT_UNSIGNED)
2041 vtop->c.i = (uint32_t)vtop->c.i;
2042 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2043 else if (sbt == VT_PTR)
2045 #endif
2046 else if (sbt != VT_LLONG)
2047 vtop->c.i = ((uint32_t)vtop->c.i |
2048 -(vtop->c.i & 0x80000000));
2050 if (dbt == (VT_LLONG|VT_UNSIGNED))
2052 else if (dbt == VT_BOOL)
2053 vtop->c.i = (vtop->c.i != 0);
2054 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2055 else if (dbt == VT_PTR)
2057 #endif
2058 else if (dbt != VT_LLONG) {
2059 uint32_t m = ((dbt & VT_BTYPE) == VT_BYTE ? 0xff :
2060 (dbt & VT_BTYPE) == VT_SHORT ? 0xffff :
2061 0xffffffff);
2062 vtop->c.i &= m;
2063 if (!(dbt & VT_UNSIGNED))
2064 vtop->c.i |= -(vtop->c.i & ((m >> 1) + 1));
2067 } else if (p && dbt == VT_BOOL) {
2068 vtop->r = VT_CONST;
2069 vtop->c.i = 1;
2070 } else if (!nocode_wanted) {
2071 /* non constant case: generate code */
2072 if (sf && df) {
2073 /* convert from fp to fp */
2074 gen_cvt_ftof(dbt);
2075 } else if (df) {
2076 /* convert int to fp */
2077 gen_cvt_itof1(dbt);
2078 } else if (sf) {
2079 /* convert fp to int */
2080 if (dbt == VT_BOOL) {
2081 vpushi(0);
2082 gen_op(TOK_NE);
2083 } else {
2084 /* we handle char/short/etc... with generic code */
2085 if (dbt != (VT_INT | VT_UNSIGNED) &&
2086 dbt != (VT_LLONG | VT_UNSIGNED) &&
2087 dbt != VT_LLONG)
2088 dbt = VT_INT;
2089 gen_cvt_ftoi1(dbt);
2090 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
2091 /* additional cast for char/short... */
2092 vtop->type.t = dbt;
2093 gen_cast(type);
2096 #if !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_X86_64)
2097 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
2098 if ((sbt & VT_BTYPE) != VT_LLONG && !nocode_wanted) {
2099 /* scalar to long long */
2100 /* machine independent conversion */
2101 gv(RC_INT);
2102 /* generate high word */
2103 if (sbt == (VT_INT | VT_UNSIGNED)) {
2104 vpushi(0);
2105 gv(RC_INT);
2106 } else {
2107 if (sbt == VT_PTR) {
2108 /* cast from pointer to int before we apply
2109 shift operation, which pointers don't support*/
2110 gen_cast(&int_type);
2112 gv_dup();
2113 vpushi(31);
2114 gen_op(TOK_SAR);
2116 /* patch second register */
2117 vtop[-1].r2 = vtop->r;
2118 vpop();
2120 #else
2121 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
2122 (dbt & VT_BTYPE) == VT_PTR ||
2123 (dbt & VT_BTYPE) == VT_FUNC) {
2124 if ((sbt & VT_BTYPE) != VT_LLONG &&
2125 (sbt & VT_BTYPE) != VT_PTR &&
2126 (sbt & VT_BTYPE) != VT_FUNC && !nocode_wanted) {
2127 /* need to convert from 32bit to 64bit */
2128 gv(RC_INT);
2129 if (sbt != (VT_INT | VT_UNSIGNED)) {
2130 #if defined(TCC_TARGET_ARM64)
2131 gen_cvt_sxtw();
2132 #elif defined(TCC_TARGET_X86_64)
2133 int r = gv(RC_INT);
2134 /* x86_64 specific: movslq */
2135 o(0x6348);
2136 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
2137 #else
2138 #error
2139 #endif
2142 #endif
2143 } else if (dbt == VT_BOOL) {
2144 /* scalar to bool */
2145 vpushi(0);
2146 gen_op(TOK_NE);
2147 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
2148 (dbt & VT_BTYPE) == VT_SHORT) {
2149 if (sbt == VT_PTR) {
2150 vtop->type.t = VT_INT;
2151 tcc_warning("nonportable conversion from pointer to char/short");
2153 force_charshort_cast(dbt);
2154 } else if ((dbt & VT_BTYPE) == VT_INT) {
2155 /* scalar to int */
2156 if (sbt == VT_LLONG && !nocode_wanted) {
2157 /* from long long: just take low order word */
2158 lexpand();
2159 vpop();
2161 /* if lvalue and single word type, nothing to do because
2162 the lvalue already contains the real type size (see
2163 VT_LVAL_xxx constants) */
2166 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
2167 /* if we are casting between pointer types,
2168 we must update the VT_LVAL_xxx size */
2169 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
2170 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
2172 vtop->type = *type;
2175 /* return type size as known at compile time. Put alignment at 'a' */
2176 ST_FUNC int type_size(CType *type, int *a)
2178 Sym *s;
2179 int bt;
2181 bt = type->t & VT_BTYPE;
2182 if (bt == VT_STRUCT) {
2183 /* struct/union */
2184 s = type->ref;
2185 *a = s->r;
2186 return s->c;
2187 } else if (bt == VT_PTR) {
2188 if (type->t & VT_ARRAY) {
2189 int ts;
2191 s = type->ref;
2192 ts = type_size(&s->type, a);
2194 if (ts < 0 && s->c < 0)
2195 ts = -ts;
2197 return ts * s->c;
2198 } else {
2199 *a = PTR_SIZE;
2200 return PTR_SIZE;
2202 } else if (bt == VT_LDOUBLE) {
2203 *a = LDOUBLE_ALIGN;
2204 return LDOUBLE_SIZE;
2205 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2206 #ifdef TCC_TARGET_I386
2207 #ifdef TCC_TARGET_PE
2208 *a = 8;
2209 #else
2210 *a = 4;
2211 #endif
2212 #elif defined(TCC_TARGET_ARM)
2213 #ifdef TCC_ARM_EABI
2214 *a = 8;
2215 #else
2216 *a = 4;
2217 #endif
2218 #else
2219 *a = 8;
2220 #endif
2221 return 8;
2222 } else if (bt == VT_INT || bt == VT_FLOAT) {
2223 *a = 4;
2224 return 4;
2225 } else if (bt == VT_SHORT) {
2226 *a = 2;
2227 return 2;
2228 } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
2229 *a = 8;
2230 return 16;
2231 } else if (bt == VT_ENUM) {
2232 *a = 4;
2233 /* Enums might be incomplete, so don't just return '4' here. */
2234 return type->ref->c;
2235 } else {
2236 /* char, void, function, _Bool */
2237 *a = 1;
2238 return 1;
2242 /* push type size as known at runtime time on top of value stack. Put
2243 alignment at 'a' */
2244 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2246 if (type->t & VT_VLA) {
2247 type_size(&type->ref->type, a);
2248 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2249 } else {
2250 vpushi(type_size(type, a));
2254 static void vla_sp_restore(void) {
2255 if (vlas_in_scope) {
2256 gen_vla_sp_restore(vla_sp_loc);
2260 static void vla_sp_restore_root(void) {
2261 if (vlas_in_scope) {
2262 gen_vla_sp_restore(vla_sp_root_loc);
2266 /* return the pointed type of t */
2267 static inline CType *pointed_type(CType *type)
2269 return &type->ref->type;
2272 /* modify type so that its it is a pointer to type. */
2273 ST_FUNC void mk_pointer(CType *type)
2275 Sym *s;
2276 s = sym_push(SYM_FIELD, type, 0, -1);
2277 type->t = VT_PTR | (type->t & ~VT_TYPE);
2278 type->ref = s;
2281 /* compare function types. OLD functions match any new functions */
2282 static int is_compatible_func(CType *type1, CType *type2)
2284 Sym *s1, *s2;
2286 s1 = type1->ref;
2287 s2 = type2->ref;
2288 if (!is_compatible_types(&s1->type, &s2->type))
2289 return 0;
2290 /* check func_call */
2291 if (s1->a.func_call != s2->a.func_call)
2292 return 0;
2293 /* XXX: not complete */
2294 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2295 return 1;
2296 if (s1->c != s2->c)
2297 return 0;
2298 while (s1 != NULL) {
2299 if (s2 == NULL)
2300 return 0;
2301 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2302 return 0;
2303 s1 = s1->next;
2304 s2 = s2->next;
2306 if (s2)
2307 return 0;
2308 return 1;
2311 /* return true if type1 and type2 are the same. If unqualified is
2312 true, qualifiers on the types are ignored.
2314 - enums are not checked as gcc __builtin_types_compatible_p ()
2316 static int compare_types(CType *type1, CType *type2, int unqualified)
2318 int bt1, t1, t2;
2320 t1 = type1->t & VT_TYPE;
2321 t2 = type2->t & VT_TYPE;
2322 if (unqualified) {
2323 /* strip qualifiers before comparing */
2324 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2325 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2327 /* Default Vs explicit signedness only matters for char */
2328 if ((t1 & VT_BTYPE) != VT_BYTE) {
2329 t1 &= ~VT_DEFSIGN;
2330 t2 &= ~VT_DEFSIGN;
2332 /* XXX: bitfields ? */
2333 if (t1 != t2)
2334 return 0;
2335 /* test more complicated cases */
2336 bt1 = t1 & VT_BTYPE;
2337 if (bt1 == VT_PTR) {
2338 type1 = pointed_type(type1);
2339 type2 = pointed_type(type2);
2340 return is_compatible_types(type1, type2);
2341 } else if (bt1 == VT_STRUCT) {
2342 return (type1->ref == type2->ref);
2343 } else if (bt1 == VT_FUNC) {
2344 return is_compatible_func(type1, type2);
2345 } else {
2346 return 1;
2350 /* return true if type1 and type2 are exactly the same (including
2351 qualifiers).
2353 static int is_compatible_types(CType *type1, CType *type2)
2355 return compare_types(type1,type2,0);
2358 /* return true if type1 and type2 are the same (ignoring qualifiers).
2360 static int is_compatible_parameter_types(CType *type1, CType *type2)
2362 return compare_types(type1,type2,1);
2365 /* print a type. If 'varstr' is not NULL, then the variable is also
2366 printed in the type */
2367 /* XXX: union */
2368 /* XXX: add array and function pointers */
2369 static void type_to_str(char *buf, int buf_size,
2370 CType *type, const char *varstr)
2372 int bt, v, t;
2373 Sym *s, *sa;
2374 char buf1[256];
2375 const char *tstr;
2377 t = type->t & VT_TYPE;
2378 bt = t & VT_BTYPE;
2379 buf[0] = '\0';
2380 if (t & VT_CONSTANT)
2381 pstrcat(buf, buf_size, "const ");
2382 if (t & VT_VOLATILE)
2383 pstrcat(buf, buf_size, "volatile ");
2384 if ((t & (VT_DEFSIGN | VT_UNSIGNED)) == (VT_DEFSIGN | VT_UNSIGNED))
2385 pstrcat(buf, buf_size, "unsigned ");
2386 else if (t & VT_DEFSIGN)
2387 pstrcat(buf, buf_size, "signed ");
2388 switch(bt) {
2389 case VT_VOID:
2390 tstr = "void";
2391 goto add_tstr;
2392 case VT_BOOL:
2393 tstr = "_Bool";
2394 goto add_tstr;
2395 case VT_BYTE:
2396 tstr = "char";
2397 goto add_tstr;
2398 case VT_SHORT:
2399 tstr = "short";
2400 goto add_tstr;
2401 case VT_INT:
2402 tstr = "int";
2403 goto add_tstr;
2404 case VT_LONG:
2405 tstr = "long";
2406 goto add_tstr;
2407 case VT_LLONG:
2408 tstr = "long long";
2409 goto add_tstr;
2410 case VT_FLOAT:
2411 tstr = "float";
2412 goto add_tstr;
2413 case VT_DOUBLE:
2414 tstr = "double";
2415 goto add_tstr;
2416 case VT_LDOUBLE:
2417 tstr = "long double";
2418 add_tstr:
2419 pstrcat(buf, buf_size, tstr);
2420 break;
2421 case VT_ENUM:
2422 case VT_STRUCT:
2423 if (bt == VT_STRUCT)
2424 tstr = "struct ";
2425 else
2426 tstr = "enum ";
2427 pstrcat(buf, buf_size, tstr);
2428 v = type->ref->v & ~SYM_STRUCT;
2429 if (v >= SYM_FIRST_ANOM)
2430 pstrcat(buf, buf_size, "<anonymous>");
2431 else
2432 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2433 break;
2434 case VT_FUNC:
2435 s = type->ref;
2436 type_to_str(buf, buf_size, &s->type, varstr);
2437 pstrcat(buf, buf_size, "(");
2438 sa = s->next;
2439 while (sa != NULL) {
2440 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2441 pstrcat(buf, buf_size, buf1);
2442 sa = sa->next;
2443 if (sa)
2444 pstrcat(buf, buf_size, ", ");
2446 pstrcat(buf, buf_size, ")");
2447 goto no_var;
2448 case VT_PTR:
2449 s = type->ref;
2450 if (t & VT_ARRAY) {
2451 snprintf(buf1, sizeof(buf1), "%s[%ld]", varstr ? varstr : "", s->c);
2452 type_to_str(buf, buf_size, &s->type, buf1);
2453 goto no_var;
2455 pstrcpy(buf1, sizeof(buf1), "*");
2456 if (t & VT_CONSTANT)
2457 pstrcat(buf1, buf_size, "const ");
2458 if (t & VT_VOLATILE)
2459 pstrcat(buf1, buf_size, "volatile ");
2460 if (varstr)
2461 pstrcat(buf1, sizeof(buf1), varstr);
2462 type_to_str(buf, buf_size, &s->type, buf1);
2463 goto no_var;
2465 if (varstr) {
2466 pstrcat(buf, buf_size, " ");
2467 pstrcat(buf, buf_size, varstr);
2469 no_var: ;
2472 /* verify type compatibility to store vtop in 'dt' type, and generate
2473 casts if needed. */
2474 static void gen_assign_cast(CType *dt)
2476 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2477 char buf1[256], buf2[256];
2478 int dbt, sbt;
2480 st = &vtop->type; /* source type */
2481 dbt = dt->t & VT_BTYPE;
2482 sbt = st->t & VT_BTYPE;
2483 if (sbt == VT_VOID || dbt == VT_VOID) {
2484 if (sbt == VT_VOID && dbt == VT_VOID)
2485 ; /*
2486 It is Ok if both are void
2487 A test program:
2488 void func1() {}
2489 void func2() {
2490 return func1();
2492 gcc accepts this program
2494 else
2495 tcc_error("cannot cast from/to void");
2497 if (dt->t & VT_CONSTANT)
2498 tcc_warning("assignment of read-only location");
2499 switch(dbt) {
2500 case VT_PTR:
2501 /* special cases for pointers */
2502 /* '0' can also be a pointer */
2503 if (is_null_pointer(vtop))
2504 goto type_ok;
2505 /* accept implicit pointer to integer cast with warning */
2506 if (is_integer_btype(sbt)) {
2507 tcc_warning("assignment makes pointer from integer without a cast");
2508 goto type_ok;
2510 type1 = pointed_type(dt);
2511 /* a function is implicitely a function pointer */
2512 if (sbt == VT_FUNC) {
2513 if ((type1->t & VT_BTYPE) != VT_VOID &&
2514 !is_compatible_types(pointed_type(dt), st))
2515 tcc_warning("assignment from incompatible pointer type");
2516 goto type_ok;
2518 if (sbt != VT_PTR)
2519 goto error;
2520 type2 = pointed_type(st);
2521 if ((type1->t & VT_BTYPE) == VT_VOID ||
2522 (type2->t & VT_BTYPE) == VT_VOID) {
2523 /* void * can match anything */
2524 } else {
2525 /* exact type match, except for unsigned */
2526 tmp_type1 = *type1;
2527 tmp_type2 = *type2;
2528 tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT |
2529 VT_VOLATILE);
2530 tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT |
2531 VT_VOLATILE);
2532 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2533 tcc_warning("assignment from incompatible pointer type");
2535 /* check const and volatile */
2536 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2537 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2538 tcc_warning("assignment discards qualifiers from pointer target type");
2539 break;
2540 case VT_BYTE:
2541 case VT_SHORT:
2542 case VT_INT:
2543 case VT_LLONG:
2544 if (sbt == VT_PTR || sbt == VT_FUNC) {
2545 tcc_warning("assignment makes integer from pointer without a cast");
2546 } else if (sbt == VT_STRUCT) {
2547 goto case_VT_STRUCT;
2549 /* XXX: more tests */
2550 break;
2551 case VT_STRUCT:
2552 case_VT_STRUCT:
2553 tmp_type1 = *dt;
2554 tmp_type2 = *st;
2555 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2556 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2557 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2558 error:
2559 type_to_str(buf1, sizeof(buf1), st, NULL);
2560 type_to_str(buf2, sizeof(buf2), dt, NULL);
2561 tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
2563 break;
2565 type_ok:
2566 gen_cast(dt);
2569 /* store vtop in lvalue pushed on stack */
2570 ST_FUNC void vstore(void)
2572 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2574 ft = vtop[-1].type.t;
2575 sbt = vtop->type.t & VT_BTYPE;
2576 dbt = ft & VT_BTYPE;
2577 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2578 (sbt == VT_INT && dbt == VT_SHORT))
2579 && !(vtop->type.t & VT_BITFIELD)) {
2580 /* optimize char/short casts */
2581 delayed_cast = VT_MUSTCAST;
2582 vtop->type.t = (ft & VT_TYPE & ~VT_BITFIELD &
2583 ((1 << VT_STRUCT_SHIFT) - 1));
2584 /* XXX: factorize */
2585 if (ft & VT_CONSTANT)
2586 tcc_warning("assignment of read-only location");
2587 } else {
2588 delayed_cast = 0;
2589 if (!(ft & VT_BITFIELD))
2590 gen_assign_cast(&vtop[-1].type);
2593 if (sbt == VT_STRUCT) {
2594 /* if structure, only generate pointer */
2595 /* structure assignment : generate memcpy */
2596 /* XXX: optimize if small size */
2597 if (!nocode_wanted) {
2598 size = type_size(&vtop->type, &align);
2600 /* destination */
2601 vswap();
2602 vtop->type.t = VT_PTR;
2603 gaddrof();
2605 /* address of memcpy() */
2606 #ifdef TCC_ARM_EABI
2607 if(!(align & 7))
2608 vpush_global_sym(&func_old_type, TOK_memcpy8);
2609 else if(!(align & 3))
2610 vpush_global_sym(&func_old_type, TOK_memcpy4);
2611 else
2612 #endif
2613 /* Use memmove, rather than memcpy, as dest and src may be same: */
2614 vpush_global_sym(&func_old_type, TOK_memmove);
2616 vswap();
2617 /* source */
2618 vpushv(vtop - 2);
2619 vtop->type.t = VT_PTR;
2620 gaddrof();
2621 /* type size */
2622 vpushi(size);
2623 gfunc_call(3);
2624 } else {
2625 vswap();
2626 vpop();
2628 /* leave source on stack */
2629 } else if (ft & VT_BITFIELD) {
2630 /* bitfield store handling */
2632 /* save lvalue as expression result (example: s.b = s.a = n;) */
2633 vdup(), vtop[-1] = vtop[-2];
2635 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2636 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2637 /* remove bit field info to avoid loops */
2638 vtop[-1].type.t = ft & ~VT_BITFIELD & ((1 << VT_STRUCT_SHIFT) - 1);
2640 if((ft & VT_BTYPE) == VT_BOOL) {
2641 gen_cast(&vtop[-1].type);
2642 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2645 /* duplicate destination */
2646 vdup();
2647 vtop[-1] = vtop[-2];
2649 /* mask and shift source */
2650 if((ft & VT_BTYPE) != VT_BOOL) {
2651 if((ft & VT_BTYPE) == VT_LLONG) {
2652 vpushll((1ULL << bit_size) - 1ULL);
2653 } else {
2654 vpushi((1 << bit_size) - 1);
2656 gen_op('&');
2658 vpushi(bit_pos);
2659 gen_op(TOK_SHL);
2660 /* load destination, mask and or with source */
2661 vswap();
2662 if((ft & VT_BTYPE) == VT_LLONG) {
2663 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2664 } else {
2665 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2667 gen_op('&');
2668 gen_op('|');
2669 /* store result */
2670 vstore();
2671 /* ... and discard */
2672 vpop();
2674 } else {
2675 if (!nocode_wanted) {
2676 #ifdef CONFIG_TCC_BCHECK
2677 /* bound check case */
2678 if (vtop[-1].r & VT_MUSTBOUND) {
2679 vswap();
2680 gbound();
2681 vswap();
2683 #endif
2684 rc = RC_INT;
2685 if (is_float(ft)) {
2686 rc = RC_FLOAT;
2687 #ifdef TCC_TARGET_X86_64
2688 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2689 rc = RC_ST0;
2690 } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
2691 rc = RC_FRET;
2693 #endif
2695 r = gv(rc); /* generate value */
2696 /* if lvalue was saved on stack, must read it */
2697 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2698 SValue sv;
2699 t = get_reg(RC_INT);
2700 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2701 sv.type.t = VT_PTR;
2702 #else
2703 sv.type.t = VT_INT;
2704 #endif
2705 sv.r = VT_LOCAL | VT_LVAL;
2706 sv.c.i = vtop[-1].c.i;
2707 load(t, &sv);
2708 vtop[-1].r = t | VT_LVAL;
2710 /* two word case handling : store second register at word + 4 (or +8 for x86-64) */
2711 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2712 if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
2713 int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
2714 #else
2715 if ((ft & VT_BTYPE) == VT_LLONG) {
2716 int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
2717 #endif
2718 vtop[-1].type.t = load_type;
2719 store(r, vtop - 1);
2720 vswap();
2721 /* convert to int to increment easily */
2722 vtop->type.t = addr_type;
2723 gaddrof();
2724 vpushi(load_size);
2725 gen_op('+');
2726 vtop->r |= VT_LVAL;
2727 vswap();
2728 vtop[-1].type.t = load_type;
2729 /* XXX: it works because r2 is spilled last ! */
2730 store(vtop->r2, vtop - 1);
2731 } else {
2732 store(r, vtop - 1);
2735 vswap();
2736 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2737 vtop->r |= delayed_cast;
2741 /* post defines POST/PRE add. c is the token ++ or -- */
2742 ST_FUNC void inc(int post, int c)
2744 test_lvalue();
2745 vdup(); /* save lvalue */
2746 if (post) {
2747 if (!nocode_wanted)
2748 gv_dup(); /* duplicate value */
2749 else
2750 vdup(); /* duplicate value */
2751 vrotb(3);
2752 vrotb(3);
2754 /* add constant */
2755 vpushi(c - TOK_MID);
2756 gen_op('+');
2757 vstore(); /* store value */
2758 if (post)
2759 vpop(); /* if post op, return saved value */
2762 /* Parse GNUC __attribute__ extension. Currently, the following
2763 extensions are recognized:
2764 - aligned(n) : set data/function alignment.
2765 - packed : force data alignment to 1
2766 - section(x) : generate data/code in this section.
2767 - unused : currently ignored, but may be used someday.
2768 - regparm(n) : pass function parameters in registers (i386 only)
2770 static void parse_attribute(AttributeDef *ad)
2772 int t, n;
2774 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2775 next();
2776 skip('(');
2777 skip('(');
2778 while (tok != ')') {
2779 if (tok < TOK_IDENT)
2780 expect("attribute name");
2781 t = tok;
2782 next();
2783 switch(t) {
2784 case TOK_SECTION1:
2785 case TOK_SECTION2:
2786 skip('(');
2787 if (tok != TOK_STR)
2788 expect("section name");
2789 ad->section = find_section(tcc_state, (char *)tokc.str.data);
2790 next();
2791 skip(')');
2792 break;
2793 case TOK_ALIAS1:
2794 case TOK_ALIAS2:
2795 skip('(');
2796 if (tok != TOK_STR)
2797 expect("alias(\"target\")");
2798 ad->alias_target = /* save string as token, for later */
2799 tok_alloc((char*)tokc.str.data, tokc.str.size-1)->tok;
2800 next();
2801 skip(')');
2802 break;
2803 case TOK_VISIBILITY1:
2804 case TOK_VISIBILITY2:
2805 skip('(');
2806 if (tok != TOK_STR)
2807 expect("visibility(\"default|hidden|internal|protected\")");
2808 if (!strcmp (tokc.str.data, "default"))
2809 ad->a.visibility = STV_DEFAULT;
2810 else if (!strcmp (tokc.str.data, "hidden"))
2811 ad->a.visibility = STV_HIDDEN;
2812 else if (!strcmp (tokc.str.data, "internal"))
2813 ad->a.visibility = STV_INTERNAL;
2814 else if (!strcmp (tokc.str.data, "protected"))
2815 ad->a.visibility = STV_PROTECTED;
2816 else
2817 expect("visibility(\"default|hidden|internal|protected\")");
2818 next();
2819 skip(')');
2820 break;
2821 case TOK_ALIGNED1:
2822 case TOK_ALIGNED2:
2823 if (tok == '(') {
2824 next();
2825 n = expr_const();
2826 if (n <= 0 || (n & (n - 1)) != 0)
2827 tcc_error("alignment must be a positive power of two");
2828 skip(')');
2829 } else {
2830 n = MAX_ALIGN;
2832 ad->a.aligned = n;
2833 break;
2834 case TOK_PACKED1:
2835 case TOK_PACKED2:
2836 ad->a.packed = 1;
2837 break;
2838 case TOK_WEAK1:
2839 case TOK_WEAK2:
2840 ad->a.weak = 1;
2841 break;
2842 case TOK_UNUSED1:
2843 case TOK_UNUSED2:
2844 /* currently, no need to handle it because tcc does not
2845 track unused objects */
2846 break;
2847 case TOK_NORETURN1:
2848 case TOK_NORETURN2:
2849 /* currently, no need to handle it because tcc does not
2850 track unused objects */
2851 break;
2852 case TOK_CDECL1:
2853 case TOK_CDECL2:
2854 case TOK_CDECL3:
2855 ad->a.func_call = FUNC_CDECL;
2856 break;
2857 case TOK_STDCALL1:
2858 case TOK_STDCALL2:
2859 case TOK_STDCALL3:
2860 ad->a.func_call = FUNC_STDCALL;
2861 break;
2862 #ifdef TCC_TARGET_I386
2863 case TOK_REGPARM1:
2864 case TOK_REGPARM2:
2865 skip('(');
2866 n = expr_const();
2867 if (n > 3)
2868 n = 3;
2869 else if (n < 0)
2870 n = 0;
2871 if (n > 0)
2872 ad->a.func_call = FUNC_FASTCALL1 + n - 1;
2873 skip(')');
2874 break;
2875 case TOK_FASTCALL1:
2876 case TOK_FASTCALL2:
2877 case TOK_FASTCALL3:
2878 ad->a.func_call = FUNC_FASTCALLW;
2879 break;
2880 #endif
2881 case TOK_MODE:
2882 skip('(');
2883 switch(tok) {
2884 case TOK_MODE_DI:
2885 ad->a.mode = VT_LLONG + 1;
2886 break;
2887 case TOK_MODE_HI:
2888 ad->a.mode = VT_SHORT + 1;
2889 break;
2890 case TOK_MODE_SI:
2891 ad->a.mode = VT_INT + 1;
2892 break;
2893 default:
2894 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2895 break;
2897 next();
2898 skip(')');
2899 break;
2900 case TOK_DLLEXPORT:
2901 ad->a.func_export = 1;
2902 break;
2903 case TOK_DLLIMPORT:
2904 ad->a.func_import = 1;
2905 break;
2906 default:
2907 if (tcc_state->warn_unsupported)
2908 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
2909 /* skip parameters */
2910 if (tok == '(') {
2911 int parenthesis = 0;
2912 do {
2913 if (tok == '(')
2914 parenthesis++;
2915 else if (tok == ')')
2916 parenthesis--;
2917 next();
2918 } while (parenthesis && tok != -1);
2920 break;
2922 if (tok != ',')
2923 break;
2924 next();
2926 skip(')');
2927 skip(')');
2931 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2932 static void struct_decl(CType *type, AttributeDef *ad, int u)
2934 int a, v, size, align, maxalign, c, offset, flexible;
2935 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2936 Sym *s, *ss, *ass, **ps;
2937 AttributeDef ad1;
2938 CType type1, btype;
2940 a = tok; /* save decl type */
2941 next();
2942 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2943 parse_attribute(ad);
2944 next();
2946 if (tok != '{') {
2947 v = tok;
2948 next();
2949 /* struct already defined ? return it */
2950 if (v < TOK_IDENT)
2951 expect("struct/union/enum name");
2952 s = struct_find(v);
2953 if (s && (s->scope == local_scope || (tok != '{' && tok != ';'))) {
2954 if (s->type.t != a)
2955 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
2956 goto do_decl;
2958 } else {
2959 v = anon_sym++;
2961 type1.t = a;
2962 type1.ref = NULL;
2963 /* we put an undefined size for struct/union */
2964 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2965 s->r = 0; /* default alignment is zero as gcc */
2966 /* put struct/union/enum name in type */
2967 do_decl:
2968 type->t = u;
2969 type->ref = s;
2971 if (tok == '{') {
2972 next();
2973 if (s->c != -1)
2974 tcc_error("struct/union/enum already defined");
2975 /* cannot be empty */
2976 c = 0;
2977 /* non empty enums are not allowed */
2978 if (a == TOK_ENUM) {
2979 for(;;) {
2980 v = tok;
2981 if (v < TOK_UIDENT)
2982 expect("identifier");
2983 ss = sym_find(v);
2984 if (ss && !local_stack)
2985 tcc_error("redefinition of enumerator '%s'",
2986 get_tok_str(v, NULL));
2987 next();
2988 if (tok == '=') {
2989 next();
2990 c = expr_const();
2992 /* enum symbols have static storage */
2993 ss = sym_push(v, &int_type, VT_CONST, c);
2994 ss->type.t |= VT_STATIC;
2995 if (tok != ',')
2996 break;
2997 next();
2998 c++;
2999 /* NOTE: we accept a trailing comma */
3000 if (tok == '}')
3001 break;
3003 s->c = type_size(&int_type, &align);
3004 skip('}');
3005 } else {
3006 maxalign = 1;
3007 ps = &s->next;
3008 prevbt = VT_INT;
3009 bit_pos = 0;
3010 offset = 0;
3011 flexible = 0;
3012 while (tok != '}') {
3013 parse_btype(&btype, &ad1);
3014 while (1) {
3015 if (flexible)
3016 tcc_error("flexible array member '%s' not at the end of struct",
3017 get_tok_str(v, NULL));
3018 bit_size = -1;
3019 v = 0;
3020 type1 = btype;
3021 if (tok != ':') {
3022 type_decl(&type1, &ad1, &v, TYPE_DIRECT | TYPE_ABSTRACT);
3023 if (v == 0) {
3024 if ((type1.t & VT_BTYPE) != VT_STRUCT)
3025 expect("identifier");
3026 else {
3027 int v = btype.ref->v;
3028 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
3029 if (tcc_state->ms_extensions == 0)
3030 expect("identifier");
3034 if (type_size(&type1, &align) < 0) {
3035 if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY) && c)
3036 flexible = 1;
3037 else
3038 tcc_error("field '%s' has incomplete type",
3039 get_tok_str(v, NULL));
3041 if ((type1.t & VT_BTYPE) == VT_FUNC ||
3042 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
3043 tcc_error("invalid type for '%s'",
3044 get_tok_str(v, NULL));
3046 if (tok == ':') {
3047 next();
3048 bit_size = expr_const();
3049 /* XXX: handle v = 0 case for messages */
3050 if (bit_size < 0)
3051 tcc_error("negative width in bit-field '%s'",
3052 get_tok_str(v, NULL));
3053 if (v && bit_size == 0)
3054 tcc_error("zero width for bit-field '%s'",
3055 get_tok_str(v, NULL));
3057 size = type_size(&type1, &align);
3058 if (ad1.a.aligned) {
3059 if (align < ad1.a.aligned)
3060 align = ad1.a.aligned;
3061 } else if (ad1.a.packed) {
3062 align = 1;
3063 } else if (*tcc_state->pack_stack_ptr) {
3064 if (align > *tcc_state->pack_stack_ptr)
3065 align = *tcc_state->pack_stack_ptr;
3067 lbit_pos = 0;
3068 if (bit_size >= 0) {
3069 bt = type1.t & VT_BTYPE;
3070 if (bt != VT_INT &&
3071 bt != VT_BYTE &&
3072 bt != VT_SHORT &&
3073 bt != VT_BOOL &&
3074 bt != VT_ENUM &&
3075 bt != VT_LLONG)
3076 tcc_error("bitfields must have scalar type");
3077 bsize = size * 8;
3078 if (bit_size > bsize) {
3079 tcc_error("width of '%s' exceeds its type",
3080 get_tok_str(v, NULL));
3081 } else if (bit_size == bsize) {
3082 /* no need for bit fields */
3083 bit_pos = 0;
3084 } else if (bit_size == 0) {
3085 /* XXX: what to do if only padding in a
3086 structure ? */
3087 /* zero size: means to pad */
3088 bit_pos = 0;
3089 } else {
3090 /* we do not have enough room ?
3091 did the type change?
3092 is it a union? */
3093 if ((bit_pos + bit_size) > bsize ||
3094 bt != prevbt || a == TOK_UNION)
3095 bit_pos = 0;
3096 lbit_pos = bit_pos;
3097 /* XXX: handle LSB first */
3098 type1.t |= VT_BITFIELD |
3099 (bit_pos << VT_STRUCT_SHIFT) |
3100 (bit_size << (VT_STRUCT_SHIFT + 6));
3101 bit_pos += bit_size;
3103 prevbt = bt;
3104 } else {
3105 bit_pos = 0;
3107 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
3108 /* add new memory data only if starting
3109 bit field */
3110 if (lbit_pos == 0) {
3111 if (a == TOK_STRUCT) {
3112 c = (c + align - 1) & -align;
3113 offset = c;
3114 if (size > 0)
3115 c += size;
3116 } else {
3117 offset = 0;
3118 if (size > c)
3119 c = size;
3121 if (align > maxalign)
3122 maxalign = align;
3124 #if 0
3125 printf("add field %s offset=%d",
3126 get_tok_str(v, NULL), offset);
3127 if (type1.t & VT_BITFIELD) {
3128 printf(" pos=%d size=%d",
3129 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
3130 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
3132 printf("\n");
3133 #endif
3135 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
3136 ass = type1.ref;
3137 while ((ass = ass->next) != NULL) {
3138 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
3139 *ps = ss;
3140 ps = &ss->next;
3142 } else if (v) {
3143 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
3144 *ps = ss;
3145 ps = &ss->next;
3147 if (tok == ';' || tok == TOK_EOF)
3148 break;
3149 skip(',');
3151 skip(';');
3153 skip('}');
3154 /* store size and alignment */
3155 s->c = (c + maxalign - 1) & -maxalign;
3156 s->r = maxalign;
3161 /* return 1 if basic type is a type size (short, long, long long) */
3162 ST_FUNC int is_btype_size(int bt)
3164 return bt == VT_SHORT || bt == VT_LONG || bt == VT_LLONG;
3167 /* Add type qualifiers to a type. If the type is an array then the qualifiers
3168 are added to the element type, copied because it could be a typedef. */
3169 static void parse_btype_qualify(CType *type, int qualifiers)
3171 while (type->t & VT_ARRAY) {
3172 type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
3173 type = &type->ref->type;
3175 type->t |= qualifiers;
3178 /* return 0 if no type declaration. otherwise, return the basic type
3179 and skip it.
3181 static int parse_btype(CType *type, AttributeDef *ad)
3183 int t, u, bt_size, complete, type_found, typespec_found;
3184 Sym *s;
3185 CType type1;
3187 memset(ad, 0, sizeof(AttributeDef));
3188 complete = 0;
3189 type_found = 0;
3190 typespec_found = 0;
3191 t = 0;
3192 while(1) {
3193 switch(tok) {
3194 case TOK_EXTENSION:
3195 /* currently, we really ignore extension */
3196 next();
3197 continue;
3199 /* basic types */
3200 case TOK_CHAR:
3201 u = VT_BYTE;
3202 basic_type:
3203 next();
3204 basic_type1:
3205 if (complete)
3206 tcc_error("too many basic types");
3207 t |= u;
3208 bt_size = is_btype_size (u & VT_BTYPE);
3209 if (u == VT_INT || (!bt_size && !(t & VT_TYPEDEF)))
3210 complete = 1;
3211 typespec_found = 1;
3212 break;
3213 case TOK_VOID:
3214 u = VT_VOID;
3215 goto basic_type;
3216 case TOK_SHORT:
3217 u = VT_SHORT;
3218 goto basic_type;
3219 case TOK_INT:
3220 u = VT_INT;
3221 goto basic_type;
3222 case TOK_LONG:
3223 next();
3224 if ((t & VT_BTYPE) == VT_DOUBLE) {
3225 #ifndef TCC_TARGET_PE
3226 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3227 #endif
3228 } else if ((t & VT_BTYPE) == VT_LONG) {
3229 t = (t & ~VT_BTYPE) | VT_LLONG;
3230 } else {
3231 u = VT_LONG;
3232 goto basic_type1;
3234 break;
3235 #ifdef TCC_TARGET_ARM64
3236 case TOK_UINT128:
3237 /* GCC's __uint128_t appears in some Linux header files. Make it a
3238 synonym for long double to get the size and alignment right. */
3239 u = VT_LDOUBLE;
3240 goto basic_type;
3241 #endif
3242 case TOK_BOOL:
3243 u = VT_BOOL;
3244 goto basic_type;
3245 case TOK_FLOAT:
3246 u = VT_FLOAT;
3247 goto basic_type;
3248 case TOK_DOUBLE:
3249 next();
3250 if ((t & VT_BTYPE) == VT_LONG) {
3251 #ifdef TCC_TARGET_PE
3252 t = (t & ~VT_BTYPE) | VT_DOUBLE;
3253 #else
3254 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
3255 #endif
3256 } else {
3257 u = VT_DOUBLE;
3258 goto basic_type1;
3260 break;
3261 case TOK_ENUM:
3262 struct_decl(&type1, ad, VT_ENUM);
3263 basic_type2:
3264 u = type1.t;
3265 type->ref = type1.ref;
3266 goto basic_type1;
3267 case TOK_STRUCT:
3268 case TOK_UNION:
3269 struct_decl(&type1, ad, VT_STRUCT);
3270 goto basic_type2;
3272 /* type modifiers */
3273 case TOK_CONST1:
3274 case TOK_CONST2:
3275 case TOK_CONST3:
3276 type->t = t;
3277 parse_btype_qualify(type, VT_CONSTANT);
3278 t = type->t;
3279 next();
3280 break;
3281 case TOK_VOLATILE1:
3282 case TOK_VOLATILE2:
3283 case TOK_VOLATILE3:
3284 type->t = t;
3285 parse_btype_qualify(type, VT_VOLATILE);
3286 t = type->t;
3287 next();
3288 break;
3289 case TOK_SIGNED1:
3290 case TOK_SIGNED2:
3291 case TOK_SIGNED3:
3292 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
3293 tcc_error("signed and unsigned modifier");
3294 typespec_found = 1;
3295 t |= VT_DEFSIGN;
3296 next();
3297 break;
3298 case TOK_REGISTER:
3299 case TOK_AUTO:
3300 case TOK_RESTRICT1:
3301 case TOK_RESTRICT2:
3302 case TOK_RESTRICT3:
3303 next();
3304 break;
3305 case TOK_UNSIGNED:
3306 if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
3307 tcc_error("signed and unsigned modifier");
3308 t |= VT_DEFSIGN | VT_UNSIGNED;
3309 next();
3310 typespec_found = 1;
3311 break;
3313 /* storage */
3314 case TOK_EXTERN:
3315 t |= VT_EXTERN;
3316 next();
3317 break;
3318 case TOK_STATIC:
3319 t |= VT_STATIC;
3320 next();
3321 break;
3322 case TOK_TYPEDEF:
3323 t |= VT_TYPEDEF;
3324 next();
3325 break;
3326 case TOK_INLINE1:
3327 case TOK_INLINE2:
3328 case TOK_INLINE3:
3329 t |= VT_INLINE;
3330 next();
3331 break;
3333 /* GNUC attribute */
3334 case TOK_ATTRIBUTE1:
3335 case TOK_ATTRIBUTE2:
3336 parse_attribute(ad);
3337 if (ad->a.mode) {
3338 u = ad->a.mode -1;
3339 t = (t & ~VT_BTYPE) | u;
3341 break;
3342 /* GNUC typeof */
3343 case TOK_TYPEOF1:
3344 case TOK_TYPEOF2:
3345 case TOK_TYPEOF3:
3346 next();
3347 parse_expr_type(&type1);
3348 /* remove all storage modifiers except typedef */
3349 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
3350 goto basic_type2;
3351 default:
3352 if (typespec_found)
3353 goto the_end;
3354 s = sym_find(tok);
3355 if (!s || !(s->type.t & VT_TYPEDEF))
3356 goto the_end;
3358 type->t = ((s->type.t & ~VT_TYPEDEF) |
3359 (t & ~(VT_CONSTANT | VT_VOLATILE)));
3360 type->ref = s->type.ref;
3361 if (t & (VT_CONSTANT | VT_VOLATILE))
3362 parse_btype_qualify(type, t & (VT_CONSTANT | VT_VOLATILE));
3363 t = type->t;
3365 if (s->r) {
3366 /* get attributes from typedef */
3367 if (0 == ad->a.aligned)
3368 ad->a.aligned = s->a.aligned;
3369 if (0 == ad->a.func_call)
3370 ad->a.func_call = s->a.func_call;
3371 ad->a.packed |= s->a.packed;
3373 next();
3374 typespec_found = 1;
3375 break;
3377 type_found = 1;
3379 the_end:
3380 if (tcc_state->char_is_unsigned) {
3381 if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
3382 t |= VT_UNSIGNED;
3385 /* long is never used as type */
3386 if ((t & VT_BTYPE) == VT_LONG)
3387 #if (!defined TCC_TARGET_X86_64 && !defined TCC_TARGET_ARM64) || \
3388 defined TCC_TARGET_PE
3389 t = (t & ~VT_BTYPE) | VT_INT;
3390 #else
3391 t = (t & ~VT_BTYPE) | VT_LLONG;
3392 #endif
3393 type->t = t;
3394 return type_found;
3397 /* convert a function parameter type (array to pointer and function to
3398 function pointer) */
3399 static inline void convert_parameter_type(CType *pt)
3401 /* remove const and volatile qualifiers (XXX: const could be used
3402 to indicate a const function parameter */
3403 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3404 /* array must be transformed to pointer according to ANSI C */
3405 pt->t &= ~VT_ARRAY;
3406 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3407 mk_pointer(pt);
3411 ST_FUNC void parse_asm_str(CString *astr)
3413 skip('(');
3414 /* read the string */
3415 if (tok != TOK_STR)
3416 expect("string constant");
3417 cstr_new(astr);
3418 while (tok == TOK_STR) {
3419 /* XXX: add \0 handling too ? */
3420 cstr_cat(astr, tokc.str.data, -1);
3421 next();
3423 cstr_ccat(astr, '\0');
3426 /* Parse an asm label and return the token */
3427 static int asm_label_instr(void)
3429 int v;
3430 CString astr;
3432 next();
3433 parse_asm_str(&astr);
3434 skip(')');
3435 #ifdef ASM_DEBUG
3436 printf("asm_alias: \"%s\"\n", (char *)astr.data);
3437 #endif
3438 v = tok_alloc(astr.data, astr.size - 1)->tok;
3439 cstr_free(&astr);
3440 return v;
3443 static void post_type(CType *type, AttributeDef *ad)
3445 int n, l, t1, arg_size, align;
3446 Sym **plast, *s, *first;
3447 AttributeDef ad1;
3448 CType pt;
3450 if (tok == '(') {
3451 /* function declaration */
3452 next();
3453 l = 0;
3454 first = NULL;
3455 plast = &first;
3456 arg_size = 0;
3457 if (tok != ')') {
3458 for(;;) {
3459 /* read param name and compute offset */
3460 if (l != FUNC_OLD) {
3461 if (!parse_btype(&pt, &ad1)) {
3462 if (l) {
3463 tcc_error("invalid type");
3464 } else {
3465 l = FUNC_OLD;
3466 goto old_proto;
3469 l = FUNC_NEW;
3470 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3471 break;
3472 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3473 if ((pt.t & VT_BTYPE) == VT_VOID)
3474 tcc_error("parameter declared as void");
3475 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3476 } else {
3477 old_proto:
3478 n = tok;
3479 if (n < TOK_UIDENT)
3480 expect("identifier");
3481 pt.t = VT_INT;
3482 next();
3484 convert_parameter_type(&pt);
3485 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3486 *plast = s;
3487 plast = &s->next;
3488 if (tok == ')')
3489 break;
3490 skip(',');
3491 if (l == FUNC_NEW && tok == TOK_DOTS) {
3492 l = FUNC_ELLIPSIS;
3493 next();
3494 break;
3498 /* if no parameters, then old type prototype */
3499 if (l == 0)
3500 l = FUNC_OLD;
3501 skip(')');
3502 /* NOTE: const is ignored in returned type as it has a special
3503 meaning in gcc / C++ */
3504 type->t &= ~VT_CONSTANT;
3505 /* some ancient pre-K&R C allows a function to return an array
3506 and the array brackets to be put after the arguments, such
3507 that "int c()[]" means something like "int[] c()" */
3508 if (tok == '[') {
3509 next();
3510 skip(']'); /* only handle simple "[]" */
3511 type->t |= VT_PTR;
3513 /* we push a anonymous symbol which will contain the function prototype */
3514 ad->a.func_args = arg_size;
3515 s = sym_push(SYM_FIELD, type, 0, l);
3516 s->a = ad->a;
3517 s->next = first;
3518 type->t = VT_FUNC;
3519 type->ref = s;
3520 } else if (tok == '[') {
3521 /* array definition */
3522 next();
3523 if (tok == TOK_RESTRICT1)
3524 next();
3525 n = -1;
3526 t1 = 0;
3527 if (tok != ']') {
3528 if (!local_stack || nocode_wanted)
3529 vpushi(expr_const());
3530 else gexpr();
3531 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3532 n = vtop->c.i;
3533 if (n < 0)
3534 tcc_error("invalid array size");
3535 } else {
3536 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3537 tcc_error("size of variable length array should be an integer");
3538 t1 = VT_VLA;
3541 skip(']');
3542 /* parse next post type */
3543 post_type(type, ad);
3544 if (type->t == VT_FUNC)
3545 tcc_error("declaration of an array of functions");
3546 t1 |= type->t & VT_VLA;
3548 if (t1 & VT_VLA) {
3549 loc -= type_size(&int_type, &align);
3550 loc &= -align;
3551 n = loc;
3553 vla_runtime_type_size(type, &align);
3554 gen_op('*');
3555 vset(&int_type, VT_LOCAL|VT_LVAL, n);
3556 vswap();
3557 vstore();
3559 if (n != -1)
3560 vpop();
3562 /* we push an anonymous symbol which will contain the array
3563 element type */
3564 s = sym_push(SYM_FIELD, type, 0, n);
3565 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3566 type->ref = s;
3570 /* Parse a type declaration (except basic type), and return the type
3571 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3572 expected. 'type' should contain the basic type. 'ad' is the
3573 attribute definition of the basic type. It can be modified by
3574 type_decl().
3576 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3578 Sym *s;
3579 CType type1, *type2;
3580 int qualifiers, storage;
3582 while (tok == '*') {
3583 qualifiers = 0;
3584 redo:
3585 next();
3586 switch(tok) {
3587 case TOK_CONST1:
3588 case TOK_CONST2:
3589 case TOK_CONST3:
3590 qualifiers |= VT_CONSTANT;
3591 goto redo;
3592 case TOK_VOLATILE1:
3593 case TOK_VOLATILE2:
3594 case TOK_VOLATILE3:
3595 qualifiers |= VT_VOLATILE;
3596 goto redo;
3597 case TOK_RESTRICT1:
3598 case TOK_RESTRICT2:
3599 case TOK_RESTRICT3:
3600 goto redo;
3602 mk_pointer(type);
3603 type->t |= qualifiers;
3606 /* XXX: clarify attribute handling */
3607 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3608 parse_attribute(ad);
3610 /* recursive type */
3611 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3612 type1.t = 0; /* XXX: same as int */
3613 if (tok == '(') {
3614 next();
3615 /* XXX: this is not correct to modify 'ad' at this point, but
3616 the syntax is not clear */
3617 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3618 parse_attribute(ad);
3619 type_decl(&type1, ad, v, td);
3620 skip(')');
3621 } else {
3622 /* type identifier */
3623 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3624 *v = tok;
3625 next();
3626 } else {
3627 if (!(td & TYPE_ABSTRACT))
3628 expect("identifier");
3629 *v = 0;
3632 storage = type->t & VT_STORAGE;
3633 type->t &= ~VT_STORAGE;
3634 if (storage & VT_STATIC) {
3635 int saved_nocode_wanted = nocode_wanted;
3636 nocode_wanted = 1;
3637 post_type(type, ad);
3638 nocode_wanted = saved_nocode_wanted;
3639 } else
3640 post_type(type, ad);
3641 type->t |= storage;
3642 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3643 parse_attribute(ad);
3645 if (!type1.t)
3646 return;
3647 /* append type at the end of type1 */
3648 type2 = &type1;
3649 for(;;) {
3650 s = type2->ref;
3651 type2 = &s->type;
3652 if (!type2->t) {
3653 *type2 = *type;
3654 break;
3657 *type = type1;
3660 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3661 ST_FUNC int lvalue_type(int t)
3663 int bt, r;
3664 r = VT_LVAL;
3665 bt = t & VT_BTYPE;
3666 if (bt == VT_BYTE || bt == VT_BOOL)
3667 r |= VT_LVAL_BYTE;
3668 else if (bt == VT_SHORT)
3669 r |= VT_LVAL_SHORT;
3670 else
3671 return r;
3672 if (t & VT_UNSIGNED)
3673 r |= VT_LVAL_UNSIGNED;
3674 return r;
3677 /* indirection with full error checking and bound check */
3678 ST_FUNC void indir(void)
3680 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3681 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3682 return;
3683 expect("pointer");
3685 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3686 gv(RC_INT);
3687 vtop->type = *pointed_type(&vtop->type);
3688 /* Arrays and functions are never lvalues */
3689 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3690 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3691 vtop->r |= lvalue_type(vtop->type.t);
3692 /* if bound checking, the referenced pointer must be checked */
3693 #ifdef CONFIG_TCC_BCHECK
3694 if (tcc_state->do_bounds_check)
3695 vtop->r |= VT_MUSTBOUND;
3696 #endif
3700 /* pass a parameter to a function and do type checking and casting */
3701 static void gfunc_param_typed(Sym *func, Sym *arg)
3703 int func_type;
3704 CType type;
3706 func_type = func->c;
3707 if (func_type == FUNC_OLD ||
3708 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3709 /* default casting : only need to convert float to double */
3710 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3711 type.t = VT_DOUBLE;
3712 gen_cast(&type);
3713 } else if (vtop->type.t & VT_BITFIELD) {
3714 type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
3715 gen_cast(&type);
3717 } else if (arg == NULL) {
3718 tcc_error("too many arguments to function");
3719 } else {
3720 type = arg->type;
3721 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3722 gen_assign_cast(&type);
3726 /* parse an expression of the form '(type)' or '(expr)' and return its
3727 type */
3728 static void parse_expr_type(CType *type)
3730 int n;
3731 AttributeDef ad;
3733 skip('(');
3734 if (parse_btype(type, &ad)) {
3735 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3736 } else {
3737 expr_type(type);
3739 skip(')');
3742 static void parse_type(CType *type)
3744 AttributeDef ad;
3745 int n;
3747 if (!parse_btype(type, &ad)) {
3748 expect("type");
3750 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3753 static void vpush_tokc(int t)
3755 CType type;
3756 type.t = t;
3757 type.ref = 0;
3758 vsetc(&type, VT_CONST, &tokc);
3761 ST_FUNC void unary(void)
3763 int n, t, align, size, r, sizeof_caller;
3764 CType type;
3765 Sym *s;
3766 AttributeDef ad;
3768 sizeof_caller = in_sizeof;
3769 in_sizeof = 0;
3770 /* XXX: GCC 2.95.3 does not generate a table although it should be
3771 better here */
3772 tok_next:
3773 switch(tok) {
3774 case TOK_EXTENSION:
3775 next();
3776 goto tok_next;
3777 case TOK_CINT:
3778 case TOK_CCHAR:
3779 case TOK_LCHAR:
3780 vpushi(tokc.i);
3781 next();
3782 break;
3783 case TOK_CUINT:
3784 vpush_tokc(VT_INT | VT_UNSIGNED);
3785 next();
3786 break;
3787 case TOK_CLLONG:
3788 vpush_tokc(VT_LLONG);
3789 next();
3790 break;
3791 case TOK_CULLONG:
3792 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3793 next();
3794 break;
3795 case TOK_CFLOAT:
3796 vpush_tokc(VT_FLOAT);
3797 next();
3798 break;
3799 case TOK_CDOUBLE:
3800 vpush_tokc(VT_DOUBLE);
3801 next();
3802 break;
3803 case TOK_CLDOUBLE:
3804 vpush_tokc(VT_LDOUBLE);
3805 next();
3806 break;
3807 case TOK___FUNCTION__:
3808 if (!gnu_ext)
3809 goto tok_identifier;
3810 /* fall thru */
3811 case TOK___FUNC__:
3813 void *ptr;
3814 int len;
3815 /* special function name identifier */
3816 len = strlen(funcname) + 1;
3817 /* generate char[len] type */
3818 type.t = VT_BYTE;
3819 mk_pointer(&type);
3820 type.t |= VT_ARRAY;
3821 type.ref->c = len;
3822 vpush_ref(&type, data_section, data_section->data_offset, len);
3823 ptr = section_ptr_add(data_section, len);
3824 memcpy(ptr, funcname, len);
3825 next();
3827 break;
3828 case TOK_LSTR:
3829 #ifdef TCC_TARGET_PE
3830 t = VT_SHORT | VT_UNSIGNED;
3831 #else
3832 t = VT_INT;
3833 #endif
3834 goto str_init;
3835 case TOK_STR:
3836 /* string parsing */
3837 t = VT_BYTE;
3838 str_init:
3839 if (tcc_state->warn_write_strings)
3840 t |= VT_CONSTANT;
3841 type.t = t;
3842 mk_pointer(&type);
3843 type.t |= VT_ARRAY;
3844 memset(&ad, 0, sizeof(AttributeDef));
3845 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
3846 break;
3847 case '(':
3848 next();
3849 /* cast ? */
3850 if (parse_btype(&type, &ad)) {
3851 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3852 skip(')');
3853 /* check ISOC99 compound literal */
3854 if (tok == '{') {
3855 /* data is allocated locally by default */
3856 if (global_expr)
3857 r = VT_CONST;
3858 else
3859 r = VT_LOCAL;
3860 /* all except arrays are lvalues */
3861 if (!(type.t & VT_ARRAY))
3862 r |= lvalue_type(type.t);
3863 memset(&ad, 0, sizeof(AttributeDef));
3864 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
3865 } else {
3866 if (sizeof_caller) {
3867 vpush(&type);
3868 return;
3870 unary();
3871 gen_cast(&type);
3873 } else if (tok == '{') {
3874 if (const_wanted)
3875 tcc_error("expected constant");
3876 /* save all registers */
3877 if (!nocode_wanted)
3878 save_regs(0);
3879 /* statement expression : we do not accept break/continue
3880 inside as GCC does */
3881 block(NULL, NULL, 1);
3882 skip(')');
3883 } else {
3884 gexpr();
3885 skip(')');
3887 break;
3888 case '*':
3889 next();
3890 unary();
3891 indir();
3892 break;
3893 case '&':
3894 next();
3895 unary();
3896 /* functions names must be treated as function pointers,
3897 except for unary '&' and sizeof. Since we consider that
3898 functions are not lvalues, we only have to handle it
3899 there and in function calls. */
3900 /* arrays can also be used although they are not lvalues */
3901 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3902 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3903 test_lvalue();
3904 mk_pointer(&vtop->type);
3905 gaddrof();
3906 break;
3907 case '!':
3908 next();
3909 unary();
3910 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3911 CType boolean;
3912 boolean.t = VT_BOOL;
3913 gen_cast(&boolean);
3914 vtop->c.i = !vtop->c.i;
3915 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3916 vtop->c.i ^= 1;
3917 else {
3918 save_regs(1);
3919 vseti(VT_JMP, gvtst(1, 0));
3921 break;
3922 case '~':
3923 next();
3924 unary();
3925 vpushi(-1);
3926 gen_op('^');
3927 break;
3928 case '+':
3929 next();
3930 unary();
3931 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3932 tcc_error("pointer not accepted for unary plus");
3933 /* In order to force cast, we add zero, except for floating point
3934 where we really need an noop (otherwise -0.0 will be transformed
3935 into +0.0). */
3936 if (!is_float(vtop->type.t)) {
3937 vpushi(0);
3938 gen_op('+');
3940 break;
3941 case TOK_SIZEOF:
3942 case TOK_ALIGNOF1:
3943 case TOK_ALIGNOF2:
3944 t = tok;
3945 next();
3946 in_sizeof++;
3947 unary_type(&type); // Perform a in_sizeof = 0;
3948 size = type_size(&type, &align);
3949 if (t == TOK_SIZEOF) {
3950 if (!(type.t & VT_VLA)) {
3951 if (size < 0)
3952 tcc_error("sizeof applied to an incomplete type");
3953 vpushs(size);
3954 } else {
3955 vla_runtime_type_size(&type, &align);
3957 } else {
3958 vpushs(align);
3960 vtop->type.t |= VT_UNSIGNED;
3961 break;
3963 case TOK_builtin_expect:
3965 /* __builtin_expect is a no-op for now */
3966 int saved_nocode_wanted;
3967 next();
3968 skip('(');
3969 expr_eq();
3970 skip(',');
3971 saved_nocode_wanted = nocode_wanted;
3972 nocode_wanted = 1;
3973 expr_lor_const();
3974 vpop();
3975 nocode_wanted = saved_nocode_wanted;
3976 skip(')');
3978 break;
3979 case TOK_builtin_types_compatible_p:
3981 CType type1, type2;
3982 next();
3983 skip('(');
3984 parse_type(&type1);
3985 skip(',');
3986 parse_type(&type2);
3987 skip(')');
3988 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3989 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3990 vpushi(is_compatible_types(&type1, &type2));
3992 break;
3993 case TOK_builtin_constant_p:
3995 int saved_nocode_wanted, res;
3996 next();
3997 skip('(');
3998 saved_nocode_wanted = nocode_wanted;
3999 nocode_wanted = 1;
4000 gexpr();
4001 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4002 vpop();
4003 nocode_wanted = saved_nocode_wanted;
4004 skip(')');
4005 vpushi(res);
4007 break;
4008 case TOK_builtin_frame_address:
4009 case TOK_builtin_return_address:
4011 int tok1 = tok;
4012 int level;
4013 CType type;
4014 next();
4015 skip('(');
4016 if (tok != TOK_CINT) {
4017 tcc_error("%s only takes positive integers",
4018 tok1 == TOK_builtin_return_address ?
4019 "__builtin_return_address" :
4020 "__builtin_frame_address");
4022 level = (uint32_t)tokc.i;
4023 next();
4024 skip(')');
4025 type.t = VT_VOID;
4026 mk_pointer(&type);
4027 vset(&type, VT_LOCAL, 0); /* local frame */
4028 while (level--) {
4029 mk_pointer(&vtop->type);
4030 indir(); /* -> parent frame */
4032 if (tok1 == TOK_builtin_return_address) {
4033 // assume return address is just above frame pointer on stack
4034 vpushi(PTR_SIZE);
4035 gen_op('+');
4036 mk_pointer(&vtop->type);
4037 indir();
4040 break;
4041 #ifdef TCC_TARGET_X86_64
4042 #ifdef TCC_TARGET_PE
4043 case TOK_builtin_va_start:
4045 next();
4046 skip('(');
4047 expr_eq();
4048 skip(',');
4049 expr_eq();
4050 skip(')');
4051 if ((vtop->r & VT_VALMASK) != VT_LOCAL)
4052 tcc_error("__builtin_va_start expects a local variable");
4053 vtop->r &= ~(VT_LVAL | VT_REF);
4054 vtop->type = char_pointer_type;
4055 vtop->c.i += 8;
4056 vstore();
4058 break;
4059 #else
4060 case TOK_builtin_va_arg_types:
4062 CType type;
4063 next();
4064 skip('(');
4065 parse_type(&type);
4066 skip(')');
4067 vpushi(classify_x86_64_va_arg(&type));
4069 break;
4070 #endif
4071 #endif
4073 #ifdef TCC_TARGET_ARM64
4074 case TOK___va_start: {
4075 if (nocode_wanted)
4076 tcc_error("statement in global scope");
4077 next();
4078 skip('(');
4079 expr_eq();
4080 skip(',');
4081 expr_eq();
4082 skip(')');
4083 //xx check types
4084 gen_va_start();
4085 vpushi(0);
4086 vtop->type.t = VT_VOID;
4087 break;
4089 case TOK___va_arg: {
4090 CType type;
4091 if (nocode_wanted)
4092 tcc_error("statement in global scope");
4093 next();
4094 skip('(');
4095 expr_eq();
4096 skip(',');
4097 parse_type(&type);
4098 skip(')');
4099 //xx check types
4100 gen_va_arg(&type);
4101 vtop->type = type;
4102 break;
4104 case TOK___arm64_clear_cache: {
4105 next();
4106 skip('(');
4107 expr_eq();
4108 skip(',');
4109 expr_eq();
4110 skip(')');
4111 gen_clear_cache();
4112 vpushi(0);
4113 vtop->type.t = VT_VOID;
4114 break;
4116 #endif
4117 /* pre operations */
4118 case TOK_INC:
4119 case TOK_DEC:
4120 t = tok;
4121 next();
4122 unary();
4123 inc(0, t);
4124 break;
4125 case '-':
4126 next();
4127 unary();
4128 t = vtop->type.t & VT_BTYPE;
4129 if (is_float(t)) {
4130 /* In IEEE negate(x) isn't subtract(0,x), but rather
4131 subtract(-0, x). */
4132 vpush(&vtop->type);
4133 if (t == VT_FLOAT)
4134 vtop->c.f = -0.0f;
4135 else if (t == VT_DOUBLE)
4136 vtop->c.d = -0.0;
4137 else
4138 vtop->c.ld = -0.0;
4139 } else
4140 vpushi(0);
4141 vswap();
4142 gen_op('-');
4143 break;
4144 case TOK_LAND:
4145 if (!gnu_ext)
4146 goto tok_identifier;
4147 next();
4148 /* allow to take the address of a label */
4149 if (tok < TOK_UIDENT)
4150 expect("label identifier");
4151 s = label_find(tok);
4152 if (!s) {
4153 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
4154 } else {
4155 if (s->r == LABEL_DECLARED)
4156 s->r = LABEL_FORWARD;
4158 if (!s->type.t) {
4159 s->type.t = VT_VOID;
4160 mk_pointer(&s->type);
4161 s->type.t |= VT_STATIC;
4163 vpushsym(&s->type, s);
4164 next();
4165 break;
4167 // special qnan , snan and infinity values
4168 case TOK___NAN__:
4169 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
4170 next();
4171 break;
4172 case TOK___SNAN__:
4173 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
4174 next();
4175 break;
4176 case TOK___INF__:
4177 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
4178 next();
4179 break;
4181 default:
4182 tok_identifier:
4183 t = tok;
4184 next();
4185 if (t < TOK_UIDENT)
4186 expect("identifier");
4187 s = sym_find(t);
4188 if (!s) {
4189 const char *name = get_tok_str(t, NULL);
4190 if (tok != '(')
4191 tcc_error("'%s' undeclared", name);
4192 /* for simple function calls, we tolerate undeclared
4193 external reference to int() function */
4194 if (tcc_state->warn_implicit_function_declaration
4195 #ifdef TCC_TARGET_PE
4196 /* people must be warned about using undeclared WINAPI functions
4197 (which usually start with uppercase letter) */
4198 || (name[0] >= 'A' && name[0] <= 'Z')
4199 #endif
4201 tcc_warning("implicit declaration of function '%s'", name);
4202 s = external_global_sym(t, &func_old_type, 0);
4204 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
4205 (VT_STATIC | VT_INLINE | VT_FUNC)) {
4206 /* if referencing an inline function, then we generate a
4207 symbol to it if not already done. It will have the
4208 effect to generate code for it at the end of the
4209 compilation unit. Inline function as always
4210 generated in the text section. */
4211 if (!s->c)
4212 put_extern_sym(s, text_section, 0, 0);
4213 r = VT_SYM | VT_CONST;
4214 } else {
4215 r = s->r;
4217 vset(&s->type, r, s->c);
4218 /* if forward reference, we must point to s */
4219 if (vtop->r & VT_SYM) {
4220 vtop->sym = s;
4221 vtop->c.i = 0;
4223 break;
4226 /* post operations */
4227 while (1) {
4228 if (tok == TOK_INC || tok == TOK_DEC) {
4229 inc(1, tok);
4230 next();
4231 } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) {
4232 int qualifiers;
4233 /* field */
4234 if (tok == TOK_ARROW)
4235 indir();
4236 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
4237 test_lvalue();
4238 gaddrof();
4239 /* expect pointer on structure */
4240 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
4241 expect("struct or union");
4242 if (tok == TOK_CDOUBLE)
4243 expect("field name");
4244 next();
4245 if (tok == TOK_CINT || tok == TOK_CUINT)
4246 expect("field name");
4247 s = vtop->type.ref;
4248 /* find field */
4249 tok |= SYM_FIELD;
4250 while ((s = s->next) != NULL) {
4251 if (s->v == tok)
4252 break;
4254 if (!s)
4255 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, &tokc));
4256 /* add field offset to pointer */
4257 vtop->type = char_pointer_type; /* change type to 'char *' */
4258 vpushi(s->c);
4259 gen_op('+');
4260 /* change type to field type, and set to lvalue */
4261 vtop->type = s->type;
4262 vtop->type.t |= qualifiers;
4263 /* an array is never an lvalue */
4264 if (!(vtop->type.t & VT_ARRAY)) {
4265 vtop->r |= lvalue_type(vtop->type.t);
4266 #ifdef CONFIG_TCC_BCHECK
4267 /* if bound checking, the referenced pointer must be checked */
4268 if (tcc_state->do_bounds_check)
4269 vtop->r |= VT_MUSTBOUND;
4270 #endif
4272 next();
4273 } else if (tok == '[') {
4274 next();
4275 gexpr();
4276 gen_op('+');
4277 indir();
4278 skip(']');
4279 } else if (tok == '(') {
4280 SValue ret;
4281 Sym *sa;
4282 int nb_args, ret_nregs, ret_align, regsize, variadic;
4284 /* function call */
4285 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
4286 /* pointer test (no array accepted) */
4287 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
4288 vtop->type = *pointed_type(&vtop->type);
4289 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
4290 goto error_func;
4291 } else {
4292 error_func:
4293 expect("function pointer");
4295 } else {
4296 vtop->r &= ~VT_LVAL; /* no lvalue */
4298 /* get return type */
4299 s = vtop->type.ref;
4300 next();
4301 sa = s->next; /* first parameter */
4302 nb_args = 0;
4303 ret.r2 = VT_CONST;
4304 /* compute first implicit argument if a structure is returned */
4305 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
4306 variadic = (s->c == FUNC_ELLIPSIS);
4307 ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
4308 &ret_align, &regsize);
4309 if (!ret_nregs) {
4310 /* get some space for the returned structure */
4311 size = type_size(&s->type, &align);
4312 #ifdef TCC_TARGET_ARM64
4313 /* On arm64, a small struct is return in registers.
4314 It is much easier to write it to memory if we know
4315 that we are allowed to write some extra bytes, so
4316 round the allocated space up to a power of 2: */
4317 if (size < 16)
4318 while (size & (size - 1))
4319 size = (size | (size - 1)) + 1;
4320 #endif
4321 loc = (loc - size) & -align;
4322 ret.type = s->type;
4323 ret.r = VT_LOCAL | VT_LVAL;
4324 /* pass it as 'int' to avoid structure arg passing
4325 problems */
4326 vseti(VT_LOCAL, loc);
4327 ret.c = vtop->c;
4328 nb_args++;
4330 } else {
4331 ret_nregs = 1;
4332 ret.type = s->type;
4335 if (ret_nregs) {
4336 /* return in register */
4337 if (is_float(ret.type.t)) {
4338 ret.r = reg_fret(ret.type.t);
4339 #ifdef TCC_TARGET_X86_64
4340 if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
4341 ret.r2 = REG_QRET;
4342 #endif
4343 } else {
4344 #ifndef TCC_TARGET_ARM64
4345 #ifdef TCC_TARGET_X86_64
4346 if ((ret.type.t & VT_BTYPE) == VT_QLONG)
4347 #else
4348 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
4349 #endif
4350 ret.r2 = REG_LRET;
4351 #endif
4352 ret.r = REG_IRET;
4354 ret.c.i = 0;
4356 if (tok != ')') {
4357 for(;;) {
4358 expr_eq();
4359 gfunc_param_typed(s, sa);
4360 nb_args++;
4361 if (sa)
4362 sa = sa->next;
4363 if (tok == ')')
4364 break;
4365 skip(',');
4368 if (sa)
4369 tcc_error("too few arguments to function");
4370 skip(')');
4371 if (!nocode_wanted) {
4372 gfunc_call(nb_args);
4373 } else {
4374 vtop -= (nb_args + 1);
4377 /* return value */
4378 for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
4379 vsetc(&ret.type, r, &ret.c);
4380 vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
4383 /* handle packed struct return */
4384 if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
4385 int addr, offset;
4387 size = type_size(&s->type, &align);
4388 /* We're writing whole regs often, make sure there's enough
4389 space. Assume register size is power of 2. */
4390 if (regsize > align)
4391 align = regsize;
4392 loc = (loc - size) & -align;
4393 addr = loc;
4394 offset = 0;
4395 for (;;) {
4396 vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
4397 vswap();
4398 vstore();
4399 vtop--;
4400 if (--ret_nregs == 0)
4401 break;
4402 offset += regsize;
4404 vset(&s->type, VT_LOCAL | VT_LVAL, addr);
4406 } else {
4407 break;
4412 ST_FUNC void expr_prod(void)
4414 int t;
4416 unary();
4417 while (tok == '*' || tok == '/' || tok == '%') {
4418 t = tok;
4419 next();
4420 unary();
4421 gen_op(t);
4425 ST_FUNC void expr_sum(void)
4427 int t;
4429 expr_prod();
4430 while (tok == '+' || tok == '-') {
4431 t = tok;
4432 next();
4433 expr_prod();
4434 gen_op(t);
4438 static void expr_shift(void)
4440 int t;
4442 expr_sum();
4443 while (tok == TOK_SHL || tok == TOK_SAR) {
4444 t = tok;
4445 next();
4446 expr_sum();
4447 gen_op(t);
4451 static void expr_cmp(void)
4453 int t;
4455 expr_shift();
4456 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
4457 tok == TOK_ULT || tok == TOK_UGE) {
4458 t = tok;
4459 next();
4460 expr_shift();
4461 gen_op(t);
4465 static void expr_cmpeq(void)
4467 int t;
4469 expr_cmp();
4470 while (tok == TOK_EQ || tok == TOK_NE) {
4471 t = tok;
4472 next();
4473 expr_cmp();
4474 gen_op(t);
4478 static void expr_and(void)
4480 expr_cmpeq();
4481 while (tok == '&') {
4482 next();
4483 expr_cmpeq();
4484 gen_op('&');
4488 static void expr_xor(void)
4490 expr_and();
4491 while (tok == '^') {
4492 next();
4493 expr_and();
4494 gen_op('^');
4498 static void expr_or(void)
4500 expr_xor();
4501 while (tok == '|') {
4502 next();
4503 expr_xor();
4504 gen_op('|');
4508 /* XXX: fix this mess */
4509 static void expr_land_const(void)
4511 expr_or();
4512 while (tok == TOK_LAND) {
4513 next();
4514 expr_or();
4515 gen_op(TOK_LAND);
4518 static void expr_lor_const(void)
4520 expr_land_const();
4521 while (tok == TOK_LOR) {
4522 next();
4523 expr_land_const();
4524 gen_op(TOK_LOR);
4528 static void expr_land(void)
4530 expr_or();
4531 if (tok == TOK_LAND) {
4532 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4533 CType ctb, cti;
4534 ctb.t = VT_BOOL;
4535 cti.t = VT_INT;
4536 next();
4537 gen_cast(&ctb);
4538 if (vtop->c.i) {
4539 vpop();
4540 expr_land();
4541 gen_cast(&ctb);
4542 } else {
4543 int saved_nocode_wanted = nocode_wanted;
4544 nocode_wanted = 1;
4545 expr_land();
4546 vpop();
4547 nocode_wanted = saved_nocode_wanted;
4549 gen_cast(&cti);
4550 } else {
4551 int t = 0;
4552 save_regs(1);
4553 for(;;) {
4554 t = gvtst(1, t);
4555 if (tok != TOK_LAND) {
4556 vseti(VT_JMPI, t);
4557 break;
4559 next();
4560 expr_or();
4566 static void expr_lor(void)
4568 expr_land();
4569 if (tok == TOK_LOR) {
4570 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4571 CType ctb, cti;
4572 ctb.t = VT_BOOL;
4573 cti.t = VT_INT;
4574 next();
4575 gen_cast(&ctb);
4576 if (vtop->c.i) {
4577 int saved_nocode_wanted = nocode_wanted;
4578 nocode_wanted = 1;
4579 expr_lor();
4580 vpop();
4581 nocode_wanted = saved_nocode_wanted;
4582 } else {
4583 vpop();
4584 expr_lor();
4585 gen_cast(&ctb);
4587 gen_cast(&cti);
4588 } else {
4589 int t = 0;
4590 save_regs(1);
4591 for(;;) {
4592 t = gvtst(0, t);
4593 if (tok != TOK_LOR) {
4594 vseti(VT_JMP, t);
4595 break;
4597 next();
4598 expr_land();
4604 static void expr_cond(void)
4606 int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv;
4607 SValue sv;
4608 CType type, type1, type2;
4610 expr_lor();
4611 if (tok == '?') {
4612 next();
4613 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4614 int saved_nocode_wanted = nocode_wanted;
4615 CType boolean;
4616 int c;
4617 boolean.t = VT_BOOL;
4618 vdup();
4619 gen_cast(&boolean);
4620 c = vtop->c.i;
4621 vpop();
4622 if (c) {
4623 if (tok != ':' || !gnu_ext) {
4624 vpop();
4625 gexpr();
4627 skip(':');
4628 nocode_wanted = 1;
4629 expr_cond();
4630 vpop();
4631 nocode_wanted = saved_nocode_wanted;
4632 } else {
4633 vpop();
4634 if (tok != ':' || !gnu_ext) {
4635 nocode_wanted = 1;
4636 gexpr();
4637 vpop();
4638 nocode_wanted = saved_nocode_wanted;
4640 skip(':');
4641 expr_cond();
4644 else {
4645 if (vtop != vstack) {
4646 /* needed to avoid having different registers saved in
4647 each branch */
4648 if (is_float(vtop->type.t)) {
4649 rc = RC_FLOAT;
4650 #ifdef TCC_TARGET_X86_64
4651 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
4652 rc = RC_ST0;
4654 #endif
4656 else
4657 rc = RC_INT;
4658 gv(rc);
4659 save_regs(1);
4661 if (tok == ':' && gnu_ext) {
4662 gv_dup();
4663 tt = gvtst(1, 0);
4664 } else {
4665 tt = gvtst(1, 0);
4666 gexpr();
4668 type1 = vtop->type;
4669 sv = *vtop; /* save value to handle it later */
4670 vtop--; /* no vpop so that FP stack is not flushed */
4671 skip(':');
4672 u = gjmp(0);
4673 gsym(tt);
4674 expr_cond();
4675 type2 = vtop->type;
4677 t1 = type1.t;
4678 bt1 = t1 & VT_BTYPE;
4679 t2 = type2.t;
4680 bt2 = t2 & VT_BTYPE;
4681 /* cast operands to correct type according to ISOC rules */
4682 if (is_float(bt1) || is_float(bt2)) {
4683 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4684 type.t = VT_LDOUBLE;
4685 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4686 type.t = VT_DOUBLE;
4687 } else {
4688 type.t = VT_FLOAT;
4690 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4691 /* cast to biggest op */
4692 type.t = VT_LLONG;
4693 /* convert to unsigned if it does not fit in a long long */
4694 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4695 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4696 type.t |= VT_UNSIGNED;
4697 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
4698 /* If one is a null ptr constant the result type
4699 is the other. */
4700 if (is_null_pointer (vtop))
4701 type = type1;
4702 else if (is_null_pointer (&sv))
4703 type = type2;
4704 /* XXX: test pointer compatibility, C99 has more elaborate
4705 rules here. */
4706 else
4707 type = type1;
4708 } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
4709 /* XXX: test function pointer compatibility */
4710 type = bt1 == VT_FUNC ? type1 : type2;
4711 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4712 /* XXX: test structure compatibility */
4713 type = bt1 == VT_STRUCT ? type1 : type2;
4714 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
4715 /* NOTE: as an extension, we accept void on only one side */
4716 type.t = VT_VOID;
4717 } else {
4718 /* integer operations */
4719 type.t = VT_INT;
4720 /* convert to unsigned if it does not fit in an integer */
4721 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4722 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4723 type.t |= VT_UNSIGNED;
4725 /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
4726 that `(expr ? a : b).mem` does not error with "lvalue expected" */
4727 islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE);
4729 /* now we convert second operand */
4730 gen_cast(&type);
4731 if (islv) {
4732 mk_pointer(&vtop->type);
4733 gaddrof();
4735 else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4736 gaddrof();
4737 rc = RC_INT;
4738 if (is_float(type.t)) {
4739 rc = RC_FLOAT;
4740 #ifdef TCC_TARGET_X86_64
4741 if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
4742 rc = RC_ST0;
4744 #endif
4745 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
4746 /* for long longs, we use fixed registers to avoid having
4747 to handle a complicated move */
4748 rc = RC_IRET;
4751 r2 = gv(rc);
4752 /* this is horrible, but we must also convert first
4753 operand */
4754 tt = gjmp(0);
4755 gsym(u);
4756 /* put again first value and cast it */
4757 *vtop = sv;
4758 gen_cast(&type);
4759 if (islv) {
4760 mk_pointer(&vtop->type);
4761 gaddrof();
4763 else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
4764 gaddrof();
4765 r1 = gv(rc);
4766 move_reg(r2, r1, type.t);
4767 vtop->r = r2;
4768 gsym(tt);
4769 if (islv)
4770 indir();
4775 static void expr_eq(void)
4777 int t;
4779 expr_cond();
4780 if (tok == '=' ||
4781 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
4782 tok == TOK_A_XOR || tok == TOK_A_OR ||
4783 tok == TOK_A_SHL || tok == TOK_A_SAR) {
4784 test_lvalue();
4785 t = tok;
4786 next();
4787 if (t == '=') {
4788 expr_eq();
4789 } else {
4790 vdup();
4791 expr_eq();
4792 gen_op(t & 0x7f);
4794 vstore();
4798 ST_FUNC void gexpr(void)
4800 while (1) {
4801 expr_eq();
4802 if (tok != ',')
4803 break;
4804 vpop();
4805 next();
4809 /* parse an expression and return its type without any side effect. */
4810 static void expr_type(CType *type)
4812 int saved_nocode_wanted;
4814 saved_nocode_wanted = nocode_wanted;
4815 nocode_wanted = 1;
4816 gexpr();
4817 *type = vtop->type;
4818 vpop();
4819 nocode_wanted = saved_nocode_wanted;
4822 /* parse a unary expression and return its type without any side
4823 effect. */
4824 static void unary_type(CType *type)
4826 int a;
4828 a = nocode_wanted;
4829 nocode_wanted = 1;
4830 unary();
4831 *type = vtop->type;
4832 vpop();
4833 nocode_wanted = a;
4836 /* parse a constant expression and return value in vtop. */
4837 static void expr_const1(void)
4839 int a;
4840 a = const_wanted;
4841 const_wanted = 1;
4842 expr_cond();
4843 const_wanted = a;
4846 /* parse an integer constant and return its value. */
4847 ST_FUNC int expr_const(void)
4849 int c;
4850 expr_const1();
4851 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
4852 expect("constant expression");
4853 c = vtop->c.i;
4854 vpop();
4855 return c;
4858 /* return the label token if current token is a label, otherwise
4859 return zero */
4860 static int is_label(void)
4862 int last_tok;
4864 /* fast test first */
4865 if (tok < TOK_UIDENT)
4866 return 0;
4867 /* no need to save tokc because tok is an identifier */
4868 last_tok = tok;
4869 next();
4870 if (tok == ':') {
4871 next();
4872 return last_tok;
4873 } else {
4874 unget_tok(last_tok);
4875 return 0;
4879 static void label_or_decl(int l)
4881 int last_tok;
4883 /* fast test first */
4884 if (tok >= TOK_UIDENT)
4886 /* no need to save tokc because tok is an identifier */
4887 last_tok = tok;
4888 next();
4889 if (tok == ':') {
4890 unget_tok(last_tok);
4891 return;
4893 unget_tok(last_tok);
4895 decl(l);
4898 static int case_cmp(const void *pa, const void *pb)
4900 int a = (*(struct case_t**) pa)->v1;
4901 int b = (*(struct case_t**) pb)->v1;
4902 return a < b ? -1 : a > b;
4905 static int gcase(struct case_t **base, int len, int case_reg, int *bsym)
4907 struct case_t *p;
4908 int e;
4909 while (len > 4) {
4910 /* binary search */
4911 p = base[len/2];
4912 vseti(case_reg, 0);
4913 vdup();
4914 vpushi(p->v2);
4915 gen_op(TOK_LE);
4916 e = gtst(1, 0);
4917 case_reg = gv(RC_INT);
4918 vpop();
4919 vseti(case_reg, 0);
4920 vdup();
4921 vpushi(p->v1);
4922 gen_op(TOK_GE);
4923 gtst_addr(0, p->sym); /* v1 <= x <= v2 */
4924 case_reg = gv(RC_INT);
4925 vpop();
4926 /* x < v1 */
4927 case_reg = gcase(base, len/2, case_reg, bsym);
4928 if (cur_switch->def_sym)
4929 gjmp_addr(cur_switch->def_sym);
4930 else
4931 *bsym = gjmp(*bsym);
4932 /* x > v2 */
4933 gsym(e);
4934 e = len/2 + 1;
4935 base += e; len -= e;
4937 /* linear scan */
4938 while (len--) {
4939 p = *base++;
4940 vseti(case_reg, 0);
4941 vdup();
4942 vpushi(p->v2);
4943 if (p->v1 == p->v2) {
4944 gen_op(TOK_EQ);
4945 gtst_addr(0, p->sym);
4946 } else {
4947 gen_op(TOK_LE);
4948 e = gtst(1, 0);
4949 case_reg = gv(RC_INT);
4950 vpop();
4951 vseti(case_reg, 0);
4952 vdup();
4953 vpushi(p->v1);
4954 gen_op(TOK_GE);
4955 gtst_addr(0, p->sym);
4956 gsym(e);
4958 case_reg = gv(RC_INT);
4959 vpop();
4961 return case_reg;
4964 static void block(int *bsym, int *csym, int is_expr)
4966 int a, b, c, d;
4967 Sym *s;
4969 /* generate line number info */
4970 if (tcc_state->do_debug &&
4971 (last_line_num != file->line_num || last_ind != ind)) {
4972 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
4973 last_ind = ind;
4974 last_line_num = file->line_num;
4977 if (is_expr) {
4978 /* default return value is (void) */
4979 vpushi(0);
4980 vtop->type.t = VT_VOID;
4983 if (tok == TOK_IF) {
4984 /* if test */
4985 next();
4986 skip('(');
4987 gexpr();
4988 skip(')');
4989 a = gvtst(1, 0);
4990 block(bsym, csym, 0);
4991 c = tok;
4992 if (c == TOK_ELSE) {
4993 next();
4994 d = gjmp(0);
4995 gsym(a);
4996 block(bsym, csym, 0);
4997 gsym(d); /* patch else jmp */
4998 } else
4999 gsym(a);
5000 } else if (tok == TOK_WHILE) {
5001 next();
5002 d = ind;
5003 vla_sp_restore();
5004 skip('(');
5005 gexpr();
5006 skip(')');
5007 a = gvtst(1, 0);
5008 b = 0;
5009 ++local_scope;
5010 block(&a, &b, 0);
5011 --local_scope;
5012 if(!nocode_wanted)
5013 gjmp_addr(d);
5014 gsym(a);
5015 gsym_addr(b, d);
5016 } else if (tok == '{') {
5017 Sym *llabel;
5018 int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope;
5020 next();
5021 /* record local declaration stack position */
5022 s = local_stack;
5023 llabel = local_label_stack;
5024 ++local_scope;
5026 /* handle local labels declarations */
5027 if (tok == TOK_LABEL) {
5028 next();
5029 for(;;) {
5030 if (tok < TOK_UIDENT)
5031 expect("label identifier");
5032 label_push(&local_label_stack, tok, LABEL_DECLARED);
5033 next();
5034 if (tok == ',') {
5035 next();
5036 } else {
5037 skip(';');
5038 break;
5042 while (tok != '}') {
5043 label_or_decl(VT_LOCAL);
5044 if (tok != '}') {
5045 if (is_expr)
5046 vpop();
5047 block(bsym, csym, is_expr);
5050 /* pop locally defined labels */
5051 label_pop(&local_label_stack, llabel);
5052 if(is_expr) {
5053 /* XXX: this solution makes only valgrind happy...
5054 triggered by gcc.c-torture/execute/20000917-1.c */
5055 Sym *p;
5056 switch(vtop->type.t & VT_BTYPE) {
5057 /* case VT_PTR: */
5058 /* this breaks a compilation of the linux kernel v2.4.26 */
5059 /* pmd_t *new = ({ __asm__ __volatile__("ud2\n") ; ((pmd_t *)1); }); */
5060 /* Look a commit a80acab: Display error on statement expressions with complex return type */
5061 /* A pointer is not a complex return type */
5062 case VT_STRUCT:
5063 case VT_ENUM:
5064 case VT_FUNC:
5065 for(p=vtop->type.ref;p;p=p->prev)
5066 if(p->prev==s)
5067 tcc_error("unsupported expression type");
5070 /* pop locally defined symbols */
5071 --local_scope;
5072 sym_pop(&local_stack, s);
5074 /* Pop VLA frames and restore stack pointer if required */
5075 if (vlas_in_scope > saved_vlas_in_scope) {
5076 vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc;
5077 vla_sp_restore();
5079 vlas_in_scope = saved_vlas_in_scope;
5081 next();
5082 } else if (tok == TOK_RETURN) {
5083 next();
5084 if (tok != ';') {
5085 gexpr();
5086 gen_assign_cast(&func_vt);
5087 #ifdef TCC_TARGET_ARM64
5088 // Perhaps it would be better to use this for all backends:
5089 greturn();
5090 #else
5091 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
5092 CType type, ret_type;
5093 int ret_align, ret_nregs, regsize;
5094 ret_nregs = gfunc_sret(&func_vt, func_var, &ret_type,
5095 &ret_align, &regsize);
5096 if (0 == ret_nregs) {
5097 /* if returning structure, must copy it to implicit
5098 first pointer arg location */
5099 type = func_vt;
5100 mk_pointer(&type);
5101 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
5102 indir();
5103 vswap();
5104 /* copy structure value to pointer */
5105 vstore();
5106 } else {
5107 /* returning structure packed into registers */
5108 int r, size, addr, align;
5109 size = type_size(&func_vt,&align);
5110 if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
5111 (vtop->c.i & (ret_align-1)))
5112 && (align & (ret_align-1))) {
5113 loc = (loc - size) & -ret_align;
5114 addr = loc;
5115 type = func_vt;
5116 vset(&type, VT_LOCAL | VT_LVAL, addr);
5117 vswap();
5118 vstore();
5119 vpop();
5120 vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
5122 vtop->type = ret_type;
5123 if (is_float(ret_type.t))
5124 r = rc_fret(ret_type.t);
5125 else
5126 r = RC_IRET;
5128 if (ret_nregs == 1)
5129 gv(r);
5130 else {
5131 for (;;) {
5132 vdup();
5133 gv(r);
5134 vpop();
5135 if (--ret_nregs == 0)
5136 break;
5137 /* We assume that when a structure is returned in multiple
5138 registers, their classes are consecutive values of the
5139 suite s(n) = 2^n */
5140 r <<= 1;
5141 vtop->c.i += regsize;
5145 } else if (is_float(func_vt.t)) {
5146 gv(rc_fret(func_vt.t));
5147 } else {
5148 gv(RC_IRET);
5150 #endif
5151 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5153 skip(';');
5154 /* jump unless last stmt in top-level block */
5155 if (tok != '}' || local_scope != 1)
5156 rsym = gjmp(rsym);
5157 } else if (tok == TOK_BREAK) {
5158 /* compute jump */
5159 if (!bsym)
5160 tcc_error("cannot break");
5161 *bsym = gjmp(*bsym);
5162 next();
5163 skip(';');
5164 } else if (tok == TOK_CONTINUE) {
5165 /* compute jump */
5166 if (!csym)
5167 tcc_error("cannot continue");
5168 vla_sp_restore_root();
5169 *csym = gjmp(*csym);
5170 next();
5171 skip(';');
5172 } else if (tok == TOK_FOR) {
5173 int e;
5174 next();
5175 skip('(');
5176 s = local_stack;
5177 ++local_scope;
5178 if (tok != ';') {
5179 /* c99 for-loop init decl? */
5180 if (!decl0(VT_LOCAL, 1)) {
5181 /* no, regular for-loop init expr */
5182 gexpr();
5183 vpop();
5186 skip(';');
5187 d = ind;
5188 c = ind;
5189 vla_sp_restore();
5190 a = 0;
5191 b = 0;
5192 if (tok != ';') {
5193 gexpr();
5194 a = gvtst(1, 0);
5196 skip(';');
5197 if (tok != ')') {
5198 e = gjmp(0);
5199 c = ind;
5200 vla_sp_restore();
5201 gexpr();
5202 vpop();
5203 gjmp_addr(d);
5204 gsym(e);
5206 skip(')');
5207 block(&a, &b, 0);
5208 if(!nocode_wanted)
5209 gjmp_addr(c);
5210 gsym(a);
5211 gsym_addr(b, c);
5212 --local_scope;
5213 sym_pop(&local_stack, s);
5215 } else
5216 if (tok == TOK_DO) {
5217 next();
5218 a = 0;
5219 b = 0;
5220 d = ind;
5221 vla_sp_restore();
5222 block(&a, &b, 0);
5223 skip(TOK_WHILE);
5224 skip('(');
5225 gsym(b);
5226 gexpr();
5227 c = gvtst(0, 0);
5228 gsym_addr(c, d);
5229 skip(')');
5230 gsym(a);
5231 skip(';');
5232 } else
5233 if (tok == TOK_SWITCH) {
5234 struct switch_t *saved, sw;
5235 next();
5236 skip('(');
5237 gexpr();
5238 /* XXX: other types than integer */
5239 c = gv(RC_INT);
5240 vpop();
5241 skip(')');
5242 a = 0;
5243 b = gjmp(0); /* jump to first case */
5244 sw.p = NULL; sw.n = 0; sw.def_sym = 0;
5245 saved = cur_switch;
5246 cur_switch = &sw;
5247 block(&a, csym, 0);
5248 a = gjmp(a); /* add implicit break */
5249 /* case lookup */
5250 gsym(b);
5251 qsort(sw.p, sw.n, sizeof(void*), case_cmp);
5252 for (b = 1; b < sw.n; b++)
5253 if (sw.p[b - 1]->v2 >= sw.p[b]->v1)
5254 tcc_error("duplicate case value");
5255 gcase(sw.p, sw.n, c, &a);
5256 if (sw.def_sym)
5257 gjmp_addr(sw.def_sym);
5258 dynarray_reset(&sw.p, &sw.n);
5259 cur_switch = saved;
5260 /* break label */
5261 gsym(a);
5262 } else
5263 if (tok == TOK_CASE) {
5264 struct case_t *cr = tcc_malloc(sizeof(struct case_t));
5265 if (!cur_switch)
5266 expect("switch");
5267 next();
5268 cr->v1 = cr->v2 = expr_const();
5269 if (gnu_ext && tok == TOK_DOTS) {
5270 next();
5271 cr->v2 = expr_const();
5272 if (cr->v2 < cr->v1)
5273 tcc_warning("empty case range");
5275 cr->sym = ind;
5276 dynarray_add((void***) &cur_switch->p, &cur_switch->n, cr);
5277 skip(':');
5278 is_expr = 0;
5279 goto block_after_label;
5280 } else
5281 if (tok == TOK_DEFAULT) {
5282 next();
5283 skip(':');
5284 if (!cur_switch)
5285 expect("switch");
5286 if (cur_switch->def_sym)
5287 tcc_error("too many 'default'");
5288 cur_switch->def_sym = ind;
5289 is_expr = 0;
5290 goto block_after_label;
5291 } else
5292 if (tok == TOK_GOTO) {
5293 next();
5294 if (tok == '*' && gnu_ext) {
5295 /* computed goto */
5296 next();
5297 gexpr();
5298 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
5299 expect("pointer");
5300 ggoto();
5301 } else if (tok >= TOK_UIDENT) {
5302 s = label_find(tok);
5303 /* put forward definition if needed */
5304 if (!s) {
5305 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
5306 } else {
5307 if (s->r == LABEL_DECLARED)
5308 s->r = LABEL_FORWARD;
5310 vla_sp_restore_root();
5311 if (s->r & LABEL_FORWARD)
5312 s->jnext = gjmp(s->jnext);
5313 else
5314 gjmp_addr(s->jnext);
5315 next();
5316 } else {
5317 expect("label identifier");
5319 skip(';');
5320 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
5321 asm_instr();
5322 } else {
5323 b = is_label();
5324 if (b) {
5325 /* label case */
5326 s = label_find(b);
5327 if (s) {
5328 if (s->r == LABEL_DEFINED)
5329 tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
5330 gsym(s->jnext);
5331 s->r = LABEL_DEFINED;
5332 } else {
5333 s = label_push(&global_label_stack, b, LABEL_DEFINED);
5335 s->jnext = ind;
5336 vla_sp_restore();
5337 /* we accept this, but it is a mistake */
5338 block_after_label:
5339 if (tok == '}') {
5340 tcc_warning("deprecated use of label at end of compound statement");
5341 } else {
5342 if (is_expr)
5343 vpop();
5344 block(bsym, csym, is_expr);
5346 } else {
5347 /* expression case */
5348 if (tok != ';') {
5349 if (is_expr) {
5350 vpop();
5351 gexpr();
5352 } else {
5353 gexpr();
5354 vpop();
5357 skip(';');
5362 /* t is the array or struct type. c is the array or struct
5363 address. cur_index/cur_field is the pointer to the current
5364 value. 'size_only' is true if only size info is needed (only used
5365 in arrays) */
5366 static void decl_designator(CType *type, Section *sec, unsigned long c,
5367 int *cur_index, Sym **cur_field,
5368 int size_only)
5370 Sym *s, *f;
5371 int notfirst, index, index_last, align, l, nb_elems, elem_size;
5372 CType type1;
5374 notfirst = 0;
5375 elem_size = 0;
5376 nb_elems = 1;
5377 if (gnu_ext && (l = is_label()) != 0)
5378 goto struct_field;
5379 while (tok == '[' || tok == '.') {
5380 if (tok == '[') {
5381 if (!(type->t & VT_ARRAY))
5382 expect("array type");
5383 s = type->ref;
5384 next();
5385 index = expr_const();
5386 if (index < 0 || (s->c >= 0 && index >= s->c))
5387 expect("invalid index");
5388 if (tok == TOK_DOTS && gnu_ext) {
5389 next();
5390 index_last = expr_const();
5391 if (index_last < 0 ||
5392 (s->c >= 0 && index_last >= s->c) ||
5393 index_last < index)
5394 expect("invalid index");
5395 } else {
5396 index_last = index;
5398 skip(']');
5399 if (!notfirst)
5400 *cur_index = index_last;
5401 type = pointed_type(type);
5402 elem_size = type_size(type, &align);
5403 c += index * elem_size;
5404 /* NOTE: we only support ranges for last designator */
5405 nb_elems = index_last - index + 1;
5406 if (nb_elems != 1) {
5407 notfirst = 1;
5408 break;
5410 } else {
5411 next();
5412 l = tok;
5413 next();
5414 struct_field:
5415 if ((type->t & VT_BTYPE) != VT_STRUCT)
5416 expect("struct/union type");
5417 s = type->ref;
5418 l |= SYM_FIELD;
5419 f = s->next;
5420 while (f) {
5421 if (f->v == l)
5422 break;
5423 f = f->next;
5425 if (!f)
5426 expect("field");
5427 if (!notfirst)
5428 *cur_field = f;
5429 /* XXX: fix this mess by using explicit storage field */
5430 type1 = f->type;
5431 type1.t |= (type->t & ~VT_TYPE);
5432 type = &type1;
5433 c += f->c;
5435 notfirst = 1;
5437 if (notfirst) {
5438 if (tok == '=') {
5439 next();
5440 } else {
5441 if (!gnu_ext)
5442 expect("=");
5444 } else {
5445 if (type->t & VT_ARRAY) {
5446 index = *cur_index;
5447 type = pointed_type(type);
5448 c += index * type_size(type, &align);
5449 } else {
5450 f = *cur_field;
5451 if (!f)
5452 tcc_error("too many field init");
5453 /* XXX: fix this mess by using explicit storage field */
5454 type1 = f->type;
5455 type1.t |= (type->t & ~VT_TYPE);
5456 type = &type1;
5457 c += f->c;
5460 decl_initializer(type, sec, c, 0, size_only);
5462 /* XXX: make it more general */
5463 if (!size_only && nb_elems > 1) {
5464 unsigned long c_end;
5465 uint8_t *src, *dst;
5466 int i;
5468 if (!sec)
5469 tcc_error("range init not supported yet for dynamic storage");
5470 c_end = c + nb_elems * elem_size;
5471 if (c_end > sec->data_allocated)
5472 section_realloc(sec, c_end);
5473 src = sec->data + c;
5474 dst = src;
5475 for(i = 1; i < nb_elems; i++) {
5476 dst += elem_size;
5477 memcpy(dst, src, elem_size);
5482 #define EXPR_VAL 0
5483 #define EXPR_CONST 1
5484 #define EXPR_ANY 2
5486 /* store a value or an expression directly in global data or in local array */
5487 static void init_putv(CType *type, Section *sec, unsigned long c,
5488 int v, int expr_type)
5490 int saved_global_expr, bt, bit_pos, bit_size;
5491 void *ptr;
5492 unsigned long long bit_mask;
5493 CType dtype;
5495 switch(expr_type) {
5496 case EXPR_VAL:
5497 vpushi(v);
5498 break;
5499 case EXPR_CONST:
5500 /* compound literals must be allocated globally in this case */
5501 saved_global_expr = global_expr;
5502 global_expr = 1;
5503 expr_const1();
5504 global_expr = saved_global_expr;
5505 /* NOTE: symbols are accepted */
5506 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
5507 tcc_error("initializer element is not constant");
5508 break;
5509 case EXPR_ANY:
5510 expr_eq();
5511 break;
5514 dtype = *type;
5515 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
5517 if (sec) {
5518 /* XXX: not portable */
5519 /* XXX: generate error if incorrect relocation */
5520 gen_assign_cast(&dtype);
5521 bt = type->t & VT_BTYPE;
5522 /* we'll write at most 16 bytes */
5523 if (c + 16 > sec->data_allocated) {
5524 section_realloc(sec, c + 16);
5526 ptr = sec->data + c;
5527 /* XXX: make code faster ? */
5528 if (!(type->t & VT_BITFIELD)) {
5529 bit_pos = 0;
5530 bit_size = 32;
5531 bit_mask = -1LL;
5532 } else {
5533 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5534 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5535 bit_mask = (1LL << bit_size) - 1;
5537 if ((vtop->r & VT_SYM) &&
5538 (bt == VT_BYTE ||
5539 bt == VT_SHORT ||
5540 bt == VT_DOUBLE ||
5541 bt == VT_LDOUBLE ||
5542 bt == VT_LLONG ||
5543 (bt == VT_INT && bit_size != 32)))
5544 tcc_error("initializer element is not computable at load time");
5545 switch(bt) {
5546 /* XXX: when cross-compiling we assume that each type has the
5547 same representation on host and target, which is likely to
5548 be wrong in the case of long double */
5549 case VT_BOOL:
5550 vtop->c.i = (vtop->c.i != 0);
5551 case VT_BYTE:
5552 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5553 break;
5554 case VT_SHORT:
5555 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5556 break;
5557 case VT_DOUBLE:
5558 *(double *)ptr = vtop->c.d;
5559 break;
5560 case VT_LDOUBLE:
5561 if (sizeof(long double) == LDOUBLE_SIZE)
5562 *(long double *)ptr = vtop->c.ld;
5563 else if (sizeof(double) == LDOUBLE_SIZE)
5564 *(double *)ptr = vtop->c.ld;
5565 else
5566 tcc_error("can't cross compile long double constants");
5567 break;
5568 case VT_LLONG:
5569 *(long long *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5570 break;
5571 case VT_PTR: {
5572 addr_t val = (vtop->c.i & bit_mask) << bit_pos;
5573 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
5574 if (vtop->r & VT_SYM)
5575 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
5576 else
5577 *(addr_t *)ptr |= val;
5578 #else
5579 if (vtop->r & VT_SYM)
5580 greloc(sec, vtop->sym, c, R_DATA_PTR);
5581 *(addr_t *)ptr |= val;
5582 #endif
5583 break;
5585 default: {
5586 int val = (vtop->c.i & bit_mask) << bit_pos;
5587 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
5588 if (vtop->r & VT_SYM)
5589 greloca(sec, vtop->sym, c, R_DATA_PTR, val);
5590 else
5591 *(int *)ptr |= val;
5592 #else
5593 if (vtop->r & VT_SYM)
5594 greloc(sec, vtop->sym, c, R_DATA_PTR);
5595 *(int *)ptr |= val;
5596 #endif
5597 break;
5600 vtop--;
5601 } else {
5602 vset(&dtype, VT_LOCAL|VT_LVAL, c);
5603 vswap();
5604 vstore();
5605 vpop();
5609 /* put zeros for variable based init */
5610 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
5612 if (sec) {
5613 /* nothing to do because globals are already set to zero */
5614 } else {
5615 vpush_global_sym(&func_old_type, TOK_memset);
5616 vseti(VT_LOCAL, c);
5617 #ifdef TCC_TARGET_ARM
5618 vpushs(size);
5619 vpushi(0);
5620 #else
5621 vpushi(0);
5622 vpushs(size);
5623 #endif
5624 gfunc_call(3);
5628 /* 't' contains the type and storage info. 'c' is the offset of the
5629 object in section 'sec'. If 'sec' is NULL, it means stack based
5630 allocation. 'first' is true if array '{' must be read (multi
5631 dimension implicit array init handling). 'size_only' is true if
5632 size only evaluation is wanted (only for arrays). */
5633 static void decl_initializer(CType *type, Section *sec, unsigned long c,
5634 int first, int size_only)
5636 int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
5637 int size1, align1, expr_type;
5638 Sym *s, *f;
5639 CType *t1;
5641 if (type->t & VT_VLA) {
5642 int a;
5644 /* save current stack pointer */
5645 if (vlas_in_scope == 0) {
5646 if (vla_sp_root_loc == -1)
5647 vla_sp_root_loc = (loc -= PTR_SIZE);
5648 gen_vla_sp_save(vla_sp_root_loc);
5651 vla_runtime_type_size(type, &a);
5652 gen_vla_alloc(type, a);
5653 gen_vla_sp_save(c);
5654 vla_sp_loc = c;
5655 vlas_in_scope++;
5656 } else if (type->t & VT_ARRAY) {
5657 s = type->ref;
5658 n = s->c;
5659 array_length = 0;
5660 t1 = pointed_type(type);
5661 size1 = type_size(t1, &align1);
5663 no_oblock = 1;
5664 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
5665 tok == '{') {
5666 if (tok != '{')
5667 tcc_error("character array initializer must be a literal,"
5668 " optionally enclosed in braces");
5669 skip('{');
5670 no_oblock = 0;
5673 /* only parse strings here if correct type (otherwise: handle
5674 them as ((w)char *) expressions */
5675 if ((tok == TOK_LSTR &&
5676 #ifdef TCC_TARGET_PE
5677 (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
5678 #else
5679 (t1->t & VT_BTYPE) == VT_INT
5680 #endif
5681 ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
5682 while (tok == TOK_STR || tok == TOK_LSTR) {
5683 int cstr_len, ch;
5685 /* compute maximum number of chars wanted */
5686 if (tok == TOK_STR)
5687 cstr_len = tokc.str.size;
5688 else
5689 cstr_len = tokc.str.size / sizeof(nwchar_t);
5690 cstr_len--;
5691 nb = cstr_len;
5692 if (n >= 0 && nb > (n - array_length))
5693 nb = n - array_length;
5694 if (!size_only) {
5695 if (cstr_len > nb)
5696 tcc_warning("initializer-string for array is too long");
5697 /* in order to go faster for common case (char
5698 string in global variable, we handle it
5699 specifically */
5700 if (sec && tok == TOK_STR && size1 == 1) {
5701 memcpy(sec->data + c + array_length, tokc.str.data, nb);
5702 } else {
5703 for(i=0;i<nb;i++) {
5704 if (tok == TOK_STR)
5705 ch = ((unsigned char *)tokc.str.data)[i];
5706 else
5707 ch = ((nwchar_t *)tokc.str.data)[i];
5708 init_putv(t1, sec, c + (array_length + i) * size1,
5709 ch, EXPR_VAL);
5713 array_length += nb;
5714 next();
5716 /* only add trailing zero if enough storage (no
5717 warning in this case since it is standard) */
5718 if (n < 0 || array_length < n) {
5719 if (!size_only) {
5720 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
5722 array_length++;
5724 } else {
5725 index = 0;
5726 while (tok != '}') {
5727 decl_designator(type, sec, c, &index, NULL, size_only);
5728 if (n >= 0 && index >= n)
5729 tcc_error("index too large");
5730 /* must put zero in holes (note that doing it that way
5731 ensures that it even works with designators) */
5732 if (!size_only && array_length < index) {
5733 init_putz(t1, sec, c + array_length * size1,
5734 (index - array_length) * size1);
5736 index++;
5737 if (index > array_length)
5738 array_length = index;
5739 /* special test for multi dimensional arrays (may not
5740 be strictly correct if designators are used at the
5741 same time) */
5742 if (index >= n && no_oblock)
5743 break;
5744 if (tok == '}')
5745 break;
5746 skip(',');
5749 if (!no_oblock)
5750 skip('}');
5751 /* put zeros at the end */
5752 if (!size_only && n >= 0 && array_length < n) {
5753 init_putz(t1, sec, c + array_length * size1,
5754 (n - array_length) * size1);
5756 /* patch type size if needed */
5757 if (n < 0)
5758 s->c = array_length;
5759 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
5760 (sec || !first || tok == '{')) {
5762 /* NOTE: the previous test is a specific case for automatic
5763 struct/union init */
5764 /* XXX: union needs only one init */
5766 int par_count = 0;
5767 if (tok == '(') {
5768 AttributeDef ad1;
5769 CType type1;
5770 next();
5771 if (tcc_state->old_struct_init_code) {
5772 /* an old version of struct initialization.
5773 It have a problems. But with a new version
5774 linux 2.4.26 can't load ramdisk.
5776 while (tok == '(') {
5777 par_count++;
5778 next();
5780 if (!parse_btype(&type1, &ad1))
5781 expect("cast");
5782 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5783 #if 0
5784 if (!is_assignable_types(type, &type1))
5785 tcc_error("invalid type for cast");
5786 #endif
5787 skip(')');
5789 else
5791 if (tok != '(') {
5792 if (!parse_btype(&type1, &ad1))
5793 expect("cast");
5794 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
5795 #if 0
5796 if (!is_assignable_types(type, &type1))
5797 tcc_error("invalid type for cast");
5798 #endif
5799 skip(')');
5800 } else
5801 unget_tok(tok);
5805 no_oblock = 1;
5806 if (first || tok == '{') {
5807 skip('{');
5808 no_oblock = 0;
5810 s = type->ref;
5811 f = s->next;
5812 array_length = 0;
5813 index = 0;
5814 n = s->c;
5815 while (tok != '}') {
5816 decl_designator(type, sec, c, NULL, &f, size_only);
5817 index = f->c;
5818 if (!size_only && array_length < index) {
5819 init_putz(type, sec, c + array_length,
5820 index - array_length);
5822 index = index + type_size(&f->type, &align1);
5823 if (index > array_length)
5824 array_length = index;
5826 /* gr: skip fields from same union - ugly. */
5827 while (f->next) {
5828 int align = 0;
5829 int f_size = type_size(&f->type, &align);
5830 int f_type = (f->type.t & VT_BTYPE);
5832 ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
5833 /* test for same offset */
5834 if (f->next->c != f->c)
5835 break;
5836 if ((f_type == VT_STRUCT) && (f_size == 0)) {
5838 Lets assume a structure of size 0 can't be a member of the union.
5839 This allow to compile the following code from a linux kernel v2.4.26
5840 typedef struct { } rwlock_t;
5841 struct fs_struct {
5842 int count;
5843 rwlock_t lock;
5844 int umask;
5846 struct fs_struct init_fs = { { (1) }, (rwlock_t) {}, 0022, };
5847 tcc-0.9.23 can succesfully compile this version of the kernel.
5848 gcc don't have problems with this code too.
5850 break;
5852 /* if yes, test for bitfield shift */
5853 if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
5854 int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5855 int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
5856 //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
5857 if (bit_pos_1 != bit_pos_2)
5858 break;
5860 f = f->next;
5863 f = f->next;
5864 if (no_oblock && f == NULL)
5865 break;
5866 if (tok == '}')
5867 break;
5868 skip(',');
5870 /* put zeros at the end */
5871 if (!size_only && array_length < n) {
5872 init_putz(type, sec, c + array_length,
5873 n - array_length);
5875 if (!no_oblock)
5876 skip('}');
5877 while (par_count) {
5878 skip(')');
5879 par_count--;
5881 } else if (tok == '{') {
5882 next();
5883 decl_initializer(type, sec, c, first, size_only);
5884 skip('}');
5885 } else if (size_only) {
5886 /* just skip expression */
5887 parlevel = parlevel1 = 0;
5888 while ((parlevel > 0 || parlevel1 > 0 ||
5889 (tok != '}' && tok != ',')) && tok != -1) {
5890 if (tok == '(')
5891 parlevel++;
5892 else if (tok == ')') {
5893 if (parlevel == 0 && parlevel1 == 0)
5894 break;
5895 parlevel--;
5897 else if (tok == '{')
5898 parlevel1++;
5899 else if (tok == '}') {
5900 if (parlevel == 0 && parlevel1 == 0)
5901 break;
5902 parlevel1--;
5904 next();
5906 } else {
5907 /* currently, we always use constant expression for globals
5908 (may change for scripting case) */
5909 expr_type = EXPR_CONST;
5910 if (!sec)
5911 expr_type = EXPR_ANY;
5912 init_putv(type, sec, c, 0, expr_type);
5916 /* parse an initializer for type 't' if 'has_init' is non zero, and
5917 allocate space in local or global data space ('r' is either
5918 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5919 variable 'v' of scope 'scope' is declared before initializers
5920 are parsed. If 'v' is zero, then a reference to the new object
5921 is put in the value stack. If 'has_init' is 2, a special parsing
5922 is done to handle string constants. */
5923 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5924 int has_init, int v, int scope)
5926 int size, align, addr, data_offset;
5927 int level;
5928 ParseState saved_parse_state = {0};
5929 TokenString *init_str = NULL;
5930 Section *sec;
5931 Sym *flexible_array;
5933 flexible_array = NULL;
5934 if ((type->t & VT_BTYPE) == VT_STRUCT) {
5935 Sym *field = type->ref->next;
5936 if (field) {
5937 while (field->next)
5938 field = field->next;
5939 if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
5940 flexible_array = field;
5944 size = type_size(type, &align);
5945 /* If unknown size, we must evaluate it before
5946 evaluating initializers because
5947 initializers can generate global data too
5948 (e.g. string pointers or ISOC99 compound
5949 literals). It also simplifies local
5950 initializers handling */
5951 if (size < 0 || (flexible_array && has_init)) {
5952 if (!has_init)
5953 tcc_error("unknown type size");
5954 /* get all init string */
5955 init_str = tok_str_alloc();
5956 if (has_init == 2) {
5957 /* only get strings */
5958 while (tok == TOK_STR || tok == TOK_LSTR) {
5959 tok_str_add_tok(init_str);
5960 next();
5962 } else {
5963 level = 0;
5964 while (level > 0 || (tok != ',' && tok != ';')) {
5965 if (tok < 0)
5966 tcc_error("unexpected end of file in initializer");
5967 tok_str_add_tok(init_str);
5968 if (tok == '{')
5969 level++;
5970 else if (tok == '}') {
5971 level--;
5972 if (level <= 0) {
5973 next();
5974 break;
5977 next();
5980 tok_str_add(init_str, -1);
5981 tok_str_add(init_str, 0);
5983 /* compute size */
5984 save_parse_state(&saved_parse_state);
5986 begin_macro(init_str, 1);
5987 next();
5988 decl_initializer(type, NULL, 0, 1, 1);
5989 /* prepare second initializer parsing */
5990 macro_ptr = init_str->str;
5991 next();
5993 /* if still unknown size, error */
5994 size = type_size(type, &align);
5995 if (size < 0)
5996 tcc_error("unknown type size");
5998 /* If there's a flex member and it was used in the initializer
5999 adjust size. */
6000 if (flexible_array &&
6001 flexible_array->type.ref->c > 0)
6002 size += flexible_array->type.ref->c
6003 * pointed_size(&flexible_array->type);
6004 /* take into account specified alignment if bigger */
6005 if (ad->a.aligned) {
6006 if (ad->a.aligned > align)
6007 align = ad->a.aligned;
6008 } else if (ad->a.packed) {
6009 align = 1;
6011 if ((r & VT_VALMASK) == VT_LOCAL) {
6012 sec = NULL;
6013 #ifdef CONFIG_TCC_BCHECK
6014 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
6015 loc--;
6017 #endif
6018 loc = (loc - size) & -align;
6019 addr = loc;
6020 #ifdef CONFIG_TCC_BCHECK
6021 /* handles bounds */
6022 /* XXX: currently, since we do only one pass, we cannot track
6023 '&' operators, so we add only arrays */
6024 if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
6025 addr_t *bounds_ptr;
6026 /* add padding between regions */
6027 loc--;
6028 /* then add local bound info */
6029 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(addr_t));
6030 bounds_ptr[0] = addr;
6031 bounds_ptr[1] = size;
6033 #endif
6034 if (v) {
6035 /* local variable */
6036 sym_push(v, type, r, addr);
6037 } else {
6038 /* push local reference */
6039 vset(type, r, addr);
6041 } else {
6042 Sym *sym;
6044 sym = NULL;
6045 if (v && scope == VT_CONST) {
6046 /* see if the symbol was already defined */
6047 sym = sym_find(v);
6048 if (sym) {
6049 if (!is_compatible_types(&sym->type, type))
6050 tcc_error("incompatible types for redefinition of '%s'",
6051 get_tok_str(v, NULL));
6052 if (sym->type.t & VT_EXTERN) {
6053 /* if the variable is extern, it was not allocated */
6054 sym->type.t &= ~VT_EXTERN;
6055 /* set array size if it was omitted in extern
6056 declaration */
6057 if ((sym->type.t & VT_ARRAY) &&
6058 sym->type.ref->c < 0 &&
6059 type->ref->c >= 0)
6060 sym->type.ref->c = type->ref->c;
6061 } else {
6062 /* we accept several definitions of the same
6063 global variable. this is tricky, because we
6064 must play with the SHN_COMMON type of the symbol */
6065 /* XXX: should check if the variable was already
6066 initialized. It is incorrect to initialized it
6067 twice */
6068 /* no init data, we won't add more to the symbol */
6069 if (!has_init)
6070 goto no_alloc;
6075 /* allocate symbol in corresponding section */
6076 sec = ad->section;
6077 if (!sec) {
6078 if (has_init)
6079 sec = data_section;
6080 else if (tcc_state->nocommon)
6081 sec = bss_section;
6083 if (sec) {
6084 data_offset = sec->data_offset;
6085 data_offset = (data_offset + align - 1) & -align;
6086 addr = data_offset;
6087 /* very important to increment global pointer at this time
6088 because initializers themselves can create new initializers */
6089 data_offset += size;
6090 #ifdef CONFIG_TCC_BCHECK
6091 /* add padding if bound check */
6092 if (tcc_state->do_bounds_check)
6093 data_offset++;
6094 #endif
6095 sec->data_offset = data_offset;
6096 /* allocate section space to put the data */
6097 if (sec->sh_type != SHT_NOBITS &&
6098 data_offset > sec->data_allocated)
6099 section_realloc(sec, data_offset);
6100 /* align section if needed */
6101 if (align > sec->sh_addralign)
6102 sec->sh_addralign = align;
6103 } else {
6104 addr = 0; /* avoid warning */
6107 if (v) {
6108 if (scope != VT_CONST || !sym) {
6109 sym = sym_push(v, type, r | VT_SYM, 0);
6110 sym->asm_label = ad->asm_label;
6112 /* update symbol definition */
6113 if (sec) {
6114 put_extern_sym(sym, sec, addr, size);
6115 } else {
6116 ElfW(Sym) *esym;
6117 /* put a common area */
6118 put_extern_sym(sym, NULL, align, size);
6119 /* XXX: find a nicer way */
6120 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
6121 esym->st_shndx = SHN_COMMON;
6123 } else {
6124 /* push global reference */
6125 sym = get_sym_ref(type, sec, addr, size);
6126 vpushsym(type, sym);
6128 /* patch symbol weakness */
6129 if (type->t & VT_WEAK)
6130 weaken_symbol(sym);
6131 apply_visibility(sym, type);
6132 #ifdef CONFIG_TCC_BCHECK
6133 /* handles bounds now because the symbol must be defined
6134 before for the relocation */
6135 if (tcc_state->do_bounds_check) {
6136 addr_t *bounds_ptr;
6138 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
6139 /* then add global bound info */
6140 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
6141 bounds_ptr[0] = 0; /* relocated */
6142 bounds_ptr[1] = size;
6144 #endif
6146 if (has_init || (type->t & VT_VLA)) {
6147 decl_initializer(type, sec, addr, 1, 0);
6148 /* patch flexible array member size back to -1, */
6149 /* for possible subsequent similar declarations */
6150 if (flexible_array)
6151 flexible_array->type.ref->c = -1;
6153 no_alloc: ;
6154 /* restore parse state if needed */
6155 if (init_str) {
6156 end_macro();
6157 restore_parse_state(&saved_parse_state);
6161 static void put_func_debug(Sym *sym)
6163 char buf[512];
6165 /* stabs info */
6166 /* XXX: we put here a dummy type */
6167 snprintf(buf, sizeof(buf), "%s:%c1",
6168 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
6169 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
6170 cur_text_section, sym->c);
6171 /* //gr gdb wants a line at the function */
6172 put_stabn(N_SLINE, 0, file->line_num, 0);
6173 last_ind = 0;
6174 last_line_num = 0;
6177 /* parse an old style function declaration list */
6178 /* XXX: check multiple parameter */
6179 static void func_decl_list(Sym *func_sym)
6181 AttributeDef ad;
6182 int v;
6183 Sym *s;
6184 CType btype, type;
6186 /* parse each declaration */
6187 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
6188 tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
6189 if (!parse_btype(&btype, &ad))
6190 expect("declaration list");
6191 if (((btype.t & VT_BTYPE) == VT_ENUM ||
6192 (btype.t & VT_BTYPE) == VT_STRUCT) &&
6193 tok == ';') {
6194 /* we accept no variable after */
6195 } else {
6196 for(;;) {
6197 type = btype;
6198 type_decl(&type, &ad, &v, TYPE_DIRECT);
6199 /* find parameter in function parameter list */
6200 s = func_sym->next;
6201 while (s != NULL) {
6202 if ((s->v & ~SYM_FIELD) == v)
6203 goto found;
6204 s = s->next;
6206 tcc_error("declaration for parameter '%s' but no such parameter",
6207 get_tok_str(v, NULL));
6208 found:
6209 /* check that no storage specifier except 'register' was given */
6210 if (type.t & VT_STORAGE)
6211 tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
6212 convert_parameter_type(&type);
6213 /* we can add the type (NOTE: it could be local to the function) */
6214 s->type = type;
6215 /* accept other parameters */
6216 if (tok == ',')
6217 next();
6218 else
6219 break;
6222 skip(';');
6226 /* parse a function defined by symbol 'sym' and generate its code in
6227 'cur_text_section' */
6228 static void gen_function(Sym *sym)
6230 int saved_nocode_wanted = nocode_wanted;
6232 nocode_wanted = 0;
6233 ind = cur_text_section->data_offset;
6234 /* NOTE: we patch the symbol size later */
6235 put_extern_sym(sym, cur_text_section, ind, 0);
6236 funcname = get_tok_str(sym->v, NULL);
6237 func_ind = ind;
6238 /* Initialize VLA state */
6239 vla_sp_loc = -1;
6240 vla_sp_root_loc = -1;
6241 /* put debug symbol */
6242 if (tcc_state->do_debug)
6243 put_func_debug(sym);
6245 /* push a dummy symbol to enable local sym storage */
6246 sym_push2(&local_stack, SYM_FIELD, 0, 0);
6247 local_scope = 1; /* for function parameters */
6248 gfunc_prolog(&sym->type);
6249 local_scope = 0;
6251 rsym = 0;
6252 block(NULL, NULL, 0);
6253 gsym(rsym);
6254 gfunc_epilog();
6255 cur_text_section->data_offset = ind;
6256 label_pop(&global_label_stack, NULL);
6257 /* reset local stack */
6258 local_scope = 0;
6259 sym_pop(&local_stack, NULL);
6260 /* end of function */
6261 /* patch symbol size */
6262 ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
6263 ind - func_ind;
6264 /* patch symbol weakness (this definition overrules any prototype) */
6265 if (sym->type.t & VT_WEAK)
6266 weaken_symbol(sym);
6267 apply_visibility(sym, &sym->type);
6268 if (tcc_state->do_debug) {
6269 put_stabn(N_FUN, 0, 0, ind - func_ind);
6271 /* It's better to crash than to generate wrong code */
6272 cur_text_section = NULL;
6273 funcname = ""; /* for safety */
6274 func_vt.t = VT_VOID; /* for safety */
6275 func_var = 0; /* for safety */
6276 ind = 0; /* for safety */
6277 nocode_wanted = saved_nocode_wanted;
6278 check_vstack();
6281 ST_FUNC void gen_inline_functions(void)
6283 Sym *sym;
6284 int inline_generated, i, ln;
6285 struct InlineFunc *fn;
6287 ln = file->line_num;
6288 /* iterate while inline function are referenced */
6289 for(;;) {
6290 inline_generated = 0;
6291 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
6292 fn = tcc_state->inline_fns[i];
6293 sym = fn->sym;
6294 if (sym && sym->c) {
6295 /* the function was used: generate its code and
6296 convert it to a normal function */
6297 fn->sym = NULL;
6298 if (file)
6299 pstrcpy(file->filename, sizeof file->filename, fn->filename);
6300 sym->r = VT_SYM | VT_CONST;
6301 sym->type.t &= ~VT_INLINE;
6303 begin_macro(&fn->func_str, 0);
6304 next();
6305 cur_text_section = text_section;
6306 gen_function(sym);
6307 end_macro();
6309 inline_generated = 1;
6312 if (!inline_generated)
6313 break;
6315 file->line_num = ln;
6316 /* free tokens of unused inline functions */
6317 for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
6318 fn = tcc_state->inline_fns[i];
6319 if (fn->sym)
6320 tok_str_free(fn->func_str.str);
6322 dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
6325 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6326 static int decl0(int l, int is_for_loop_init)
6328 int v, has_init, r;
6329 CType type, btype;
6330 Sym *sym;
6331 AttributeDef ad;
6333 while (1) {
6334 if (!parse_btype(&btype, &ad)) {
6335 if (is_for_loop_init)
6336 return 0;
6337 /* skip redundant ';' */
6338 /* XXX: find more elegant solution */
6339 if (tok == ';') {
6340 next();
6341 continue;
6343 if (l == VT_CONST &&
6344 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
6345 /* global asm block */
6346 asm_global_instr();
6347 continue;
6349 /* special test for old K&R protos without explicit int
6350 type. Only accepted when defining global data */
6351 if (l == VT_LOCAL || tok < TOK_UIDENT)
6352 break;
6353 btype.t = VT_INT;
6355 if (((btype.t & VT_BTYPE) == VT_ENUM ||
6356 (btype.t & VT_BTYPE) == VT_STRUCT) &&
6357 tok == ';') {
6358 if ((btype.t & VT_BTYPE) == VT_STRUCT) {
6359 int v = btype.ref->v;
6360 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
6361 tcc_warning("unnamed struct/union that defines no instances");
6363 next();
6364 continue;
6366 while (1) { /* iterate thru each declaration */
6367 type = btype;
6368 type_decl(&type, &ad, &v, TYPE_DIRECT);
6369 #if 0
6371 char buf[500];
6372 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
6373 printf("type = '%s'\n", buf);
6375 #endif
6376 if ((type.t & VT_BTYPE) == VT_FUNC) {
6377 if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
6378 tcc_error("function without file scope cannot be static");
6380 /* if old style function prototype, we accept a
6381 declaration list */
6382 sym = type.ref;
6383 if (sym->c == FUNC_OLD)
6384 func_decl_list(sym);
6387 if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
6388 ad.asm_label = asm_label_instr();
6389 /* parse one last attribute list, after asm label */
6390 parse_attribute(&ad);
6391 if (tok == '{')
6392 expect(";");
6395 if (ad.a.weak)
6396 type.t |= VT_WEAK;
6397 #ifdef TCC_TARGET_PE
6398 if (ad.a.func_import)
6399 type.t |= VT_IMPORT;
6400 if (ad.a.func_export)
6401 type.t |= VT_EXPORT;
6402 #endif
6403 type.t |= ad.a.visibility << VT_VIS_SHIFT;
6405 if (tok == '{') {
6406 if (l == VT_LOCAL)
6407 tcc_error("cannot use local functions");
6408 if ((type.t & VT_BTYPE) != VT_FUNC)
6409 expect("function definition");
6411 /* reject abstract declarators in function definition */
6412 sym = type.ref;
6413 while ((sym = sym->next) != NULL)
6414 if (!(sym->v & ~SYM_FIELD))
6415 expect("identifier");
6417 /* XXX: cannot do better now: convert extern line to static inline */
6418 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
6419 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6421 sym = sym_find(v);
6422 if (sym) {
6423 Sym *ref;
6424 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
6425 goto func_error1;
6427 ref = sym->type.ref;
6428 if (0 == ref->a.func_proto)
6429 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
6431 /* use func_call from prototype if not defined */
6432 if (ref->a.func_call != FUNC_CDECL
6433 && type.ref->a.func_call == FUNC_CDECL)
6434 type.ref->a.func_call = ref->a.func_call;
6436 /* use export from prototype */
6437 if (ref->a.func_export)
6438 type.ref->a.func_export = 1;
6440 /* use static from prototype */
6441 if (sym->type.t & VT_STATIC)
6442 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
6444 /* If the definition has no visibility use the
6445 one from prototype. */
6446 if (! (type.t & VT_VIS_MASK))
6447 type.t |= sym->type.t & VT_VIS_MASK;
6449 if (!is_compatible_types(&sym->type, &type)) {
6450 func_error1:
6451 tcc_error("incompatible types for redefinition of '%s'",
6452 get_tok_str(v, NULL));
6454 type.ref->a.func_proto = 0;
6455 /* if symbol is already defined, then put complete type */
6456 sym->type = type;
6457 } else {
6458 /* put function symbol */
6459 sym = global_identifier_push(v, type.t, 0);
6460 sym->type.ref = type.ref;
6463 /* static inline functions are just recorded as a kind
6464 of macro. Their code will be emitted at the end of
6465 the compilation unit only if they are used */
6466 if ((type.t & (VT_INLINE | VT_STATIC)) ==
6467 (VT_INLINE | VT_STATIC)) {
6468 int block_level;
6469 struct InlineFunc *fn;
6470 const char *filename;
6472 filename = file ? file->filename : "";
6473 fn = tcc_malloc(sizeof *fn + strlen(filename));
6474 strcpy(fn->filename, filename);
6475 fn->sym = sym;
6476 tok_str_new(&fn->func_str);
6478 block_level = 0;
6479 for(;;) {
6480 int t;
6481 if (tok == TOK_EOF)
6482 tcc_error("unexpected end of file");
6483 tok_str_add_tok(&fn->func_str);
6484 t = tok;
6485 next();
6486 if (t == '{') {
6487 block_level++;
6488 } else if (t == '}') {
6489 block_level--;
6490 if (block_level == 0)
6491 break;
6494 tok_str_add(&fn->func_str, -1);
6495 tok_str_add(&fn->func_str, 0);
6496 dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
6498 } else {
6499 /* compute text section */
6500 cur_text_section = ad.section;
6501 if (!cur_text_section)
6502 cur_text_section = text_section;
6503 sym->r = VT_SYM | VT_CONST;
6504 gen_function(sym);
6506 break;
6507 } else {
6508 if (btype.t & VT_TYPEDEF) {
6509 /* save typedefed type */
6510 /* XXX: test storage specifiers ? */
6511 sym = sym_find(v);
6512 if (sym && sym->scope == local_scope) {
6513 if (!is_compatible_types(&sym->type, &type)
6514 || !(sym->type.t & VT_TYPEDEF))
6515 tcc_error("incompatible redefinition of '%s'",
6516 get_tok_str(v, NULL));
6517 sym->type = type;
6518 } else {
6519 sym = sym_push(v, &type, 0, 0);
6521 sym->a = ad.a;
6522 sym->type.t |= VT_TYPEDEF;
6523 } else {
6524 r = 0;
6525 if ((type.t & VT_BTYPE) == VT_FUNC) {
6526 /* external function definition */
6527 /* specific case for func_call attribute */
6528 ad.a.func_proto = 1;
6529 type.ref->a = ad.a;
6530 } else if (!(type.t & VT_ARRAY)) {
6531 /* not lvalue if array */
6532 r |= lvalue_type(type.t);
6534 has_init = (tok == '=');
6535 if (has_init && (type.t & VT_VLA))
6536 tcc_error("Variable length array cannot be initialized");
6537 if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
6538 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
6539 !has_init && l == VT_CONST && type.ref->c < 0)) {
6540 /* external variable or function */
6541 /* NOTE: as GCC, uninitialized global static
6542 arrays of null size are considered as
6543 extern */
6544 sym = external_sym(v, &type, r);
6545 sym->asm_label = ad.asm_label;
6547 if (ad.alias_target) {
6548 Section tsec;
6549 Elf32_Sym *esym;
6550 Sym *alias_target;
6552 alias_target = sym_find(ad.alias_target);
6553 if (!alias_target || !alias_target->c)
6554 tcc_error("unsupported forward __alias__ attribute");
6555 esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
6556 tsec.sh_num = esym->st_shndx;
6557 put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
6559 } else {
6560 type.t |= (btype.t & VT_STATIC); /* Retain "static". */
6561 if (type.t & VT_STATIC)
6562 r |= VT_CONST;
6563 else
6564 r |= l;
6565 if (has_init)
6566 next();
6567 decl_initializer_alloc(&type, &ad, r, has_init, v, l);
6570 if (tok != ',') {
6571 if (is_for_loop_init)
6572 return 1;
6573 skip(';');
6574 break;
6576 next();
6578 ad.a.aligned = 0;
6581 return 0;
6584 ST_FUNC void decl(int l)
6586 decl0(l, 0);