Add my copyright for changes in arm-gen.c
[tinycc.git] / tccgen.c
blob4300403f33b6b21ef11871890b6bf7ba8c4c77b2
1 /*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "tcc.h"
23 /********************************************************/
24 /* global variables */
26 /* loc : local variable index
27 ind : output code index
28 rsym: return symbol
29 anon_sym: anonymous symbol index
31 ST_DATA int rsym, anon_sym, ind, loc;
33 ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
34 ST_DATA Section *cur_text_section; /* current section where function code is generated */
35 #ifdef CONFIG_TCC_ASM
36 ST_DATA Section *last_text_section; /* to handle .previous asm directive */
37 #endif
38 #ifdef CONFIG_TCC_BCHECK
39 /* bound check related sections */
40 ST_DATA Section *bounds_section; /* contains global data bound description */
41 ST_DATA Section *lbounds_section; /* contains local data bound description */
42 #endif
43 /* symbol sections */
44 ST_DATA Section *symtab_section, *strtab_section;
45 /* debug sections */
46 ST_DATA Section *stab_section, *stabstr_section;
47 ST_DATA Sym *sym_free_first;
48 ST_DATA void **sym_pools;
49 ST_DATA int nb_sym_pools;
51 ST_DATA Sym *global_stack;
52 ST_DATA Sym *local_stack;
53 ST_DATA Sym *scope_stack_bottom;
54 ST_DATA Sym *define_stack;
55 ST_DATA Sym *global_label_stack;
56 ST_DATA Sym *local_label_stack;
58 ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop;
60 ST_DATA int const_wanted; /* true if constant wanted */
61 ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
62 ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
63 ST_DATA CType func_vt; /* current function return type (used by return instruction) */
64 ST_DATA int func_vc;
65 ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
66 ST_DATA char *funcname;
68 ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
70 /* ------------------------------------------------------------------------- */
71 static void gen_cast(CType *type);
72 static inline CType *pointed_type(CType *type);
73 static int is_compatible_types(CType *type1, CType *type2);
74 static int parse_btype(CType *type, AttributeDef *ad);
75 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
76 static void parse_expr_type(CType *type);
77 static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
78 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr);
79 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, char *asm_label, int scope);
80 static int decl0(int l, int is_for_loop_init);
81 static void expr_eq(void);
82 static void unary_type(CType *type);
83 static void vla_runtime_type_size(CType *type, int *a);
84 static int is_compatible_parameter_types(CType *type1, CType *type2);
85 static void expr_type(CType *type);
87 ST_INLN int is_float(int t)
89 int bt;
90 bt = t & VT_BTYPE;
91 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
94 /* we use our own 'finite' function to avoid potential problems with
95 non standard math libs */
96 /* XXX: endianness dependent */
97 ST_FUNC int ieee_finite(double d)
99 int *p = (int *)&d;
100 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
103 ST_FUNC void test_lvalue(void)
105 if (!(vtop->r & VT_LVAL))
106 expect("lvalue");
109 /* ------------------------------------------------------------------------- */
110 /* symbol allocator */
111 static Sym *__sym_malloc(void)
113 Sym *sym_pool, *sym, *last_sym;
114 int i;
116 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
117 dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
119 last_sym = sym_free_first;
120 sym = sym_pool;
121 for(i = 0; i < SYM_POOL_NB; i++) {
122 sym->next = last_sym;
123 last_sym = sym;
124 sym++;
126 sym_free_first = last_sym;
127 return last_sym;
130 static inline Sym *sym_malloc(void)
132 Sym *sym;
133 sym = sym_free_first;
134 if (!sym)
135 sym = __sym_malloc();
136 sym_free_first = sym->next;
137 return sym;
140 ST_INLN void sym_free(Sym *sym)
142 sym->next = sym_free_first;
143 tcc_free(sym->asm_label);
144 sym_free_first = sym;
147 /* push, without hashing */
148 ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
150 Sym *s;
151 if (ps == &local_stack) {
152 for (s = *ps; s && s != scope_stack_bottom; s = s->prev)
153 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM && s->v == v)
154 tcc_error("incompatible types for redefinition of '%s'",
155 get_tok_str(v, NULL));
157 s = *ps;
158 s = sym_malloc();
159 s->asm_label = NULL;
160 s->v = v;
161 s->type.t = t;
162 s->type.ref = NULL;
163 #ifdef _WIN64
164 s->d = NULL;
165 #endif
166 s->c = c;
167 s->next = NULL;
168 /* add in stack */
169 s->prev = *ps;
170 *ps = s;
171 return s;
174 /* find a symbol and return its associated structure. 's' is the top
175 of the symbol stack */
176 ST_FUNC Sym *sym_find2(Sym *s, int v)
178 while (s) {
179 if (s->v == v)
180 return s;
181 s = s->prev;
183 return NULL;
186 /* structure lookup */
187 ST_INLN Sym *struct_find(int v)
189 v -= TOK_IDENT;
190 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
191 return NULL;
192 return table_ident[v]->sym_struct;
195 /* find an identifier */
196 ST_INLN Sym *sym_find(int v)
198 v -= TOK_IDENT;
199 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
200 return NULL;
201 return table_ident[v]->sym_identifier;
204 /* push a given symbol on the symbol stack */
205 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
207 Sym *s, **ps;
208 TokenSym *ts;
210 if (local_stack)
211 ps = &local_stack;
212 else
213 ps = &global_stack;
214 s = sym_push2(ps, v, type->t, c);
215 s->type.ref = type->ref;
216 s->r = r;
217 /* don't record fields or anonymous symbols */
218 /* XXX: simplify */
219 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
220 /* record symbol in token array */
221 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
222 if (v & SYM_STRUCT)
223 ps = &ts->sym_struct;
224 else
225 ps = &ts->sym_identifier;
226 s->prev_tok = *ps;
227 *ps = s;
229 return s;
232 /* push a global identifier */
233 ST_FUNC Sym *global_identifier_push(int v, int t, int c)
235 Sym *s, **ps;
236 s = sym_push2(&global_stack, v, t, c);
237 /* don't record anonymous symbol */
238 if (v < SYM_FIRST_ANOM) {
239 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
240 /* modify the top most local identifier, so that
241 sym_identifier will point to 's' when popped */
242 while (*ps != NULL)
243 ps = &(*ps)->prev_tok;
244 s->prev_tok = NULL;
245 *ps = s;
247 return s;
250 /* pop symbols until top reaches 'b' */
251 ST_FUNC void sym_pop(Sym **ptop, Sym *b)
253 Sym *s, *ss, **ps;
254 TokenSym *ts;
255 int v;
257 s = *ptop;
258 while(s != b) {
259 ss = s->prev;
260 v = s->v;
261 /* remove symbol in token array */
262 /* XXX: simplify */
263 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
264 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
265 if (v & SYM_STRUCT)
266 ps = &ts->sym_struct;
267 else
268 ps = &ts->sym_identifier;
269 *ps = s->prev_tok;
271 sym_free(s);
272 s = ss;
274 *ptop = b;
277 static void weaken_symbol(Sym *sym)
279 sym->type.t |= VT_WEAK;
280 if (sym->c > 0) {
281 int esym_type;
282 ElfW(Sym) *esym;
284 esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
285 esym_type = ELFW(ST_TYPE)(esym->st_info);
286 esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
290 /* ------------------------------------------------------------------------- */
292 ST_FUNC void swap(int *p, int *q)
294 int t;
295 t = *p;
296 *p = *q;
297 *q = t;
300 static void vsetc(CType *type, int r, CValue *vc)
302 int v;
304 if (vtop >= vstack + (VSTACK_SIZE - 1))
305 tcc_error("memory full");
306 /* cannot let cpu flags if other instruction are generated. Also
307 avoid leaving VT_JMP anywhere except on the top of the stack
308 because it would complicate the code generator. */
309 if (vtop >= vstack) {
310 v = vtop->r & VT_VALMASK;
311 if (v == VT_CMP || (v & ~1) == VT_JMP)
312 gv(RC_INT);
314 vtop++;
315 vtop->type = *type;
316 vtop->r = r;
317 vtop->r2 = VT_CONST;
318 vtop->c = *vc;
321 /* push constant of type "type" with useless value */
322 void vpush(CType *type)
324 CValue cval;
325 vsetc(type, VT_CONST, &cval);
328 /* push integer constant */
329 ST_FUNC void vpushi(int v)
331 CValue cval;
332 cval.i = v;
333 vsetc(&int_type, VT_CONST, &cval);
336 /* push a pointer sized constant */
337 static void vpushs(long long v)
339 CValue cval;
340 if (PTR_SIZE == 4)
341 cval.i = (int)v;
342 else
343 cval.ull = v;
344 vsetc(&size_type, VT_CONST, &cval);
347 /* push long long constant */
348 static void vpushll(long long v)
350 CValue cval;
351 CType ctype;
352 ctype.t = VT_LLONG;
353 ctype.ref = 0;
354 cval.ull = v;
355 vsetc(&ctype, VT_CONST, &cval);
358 /* push arbitrary 64bit constant */
359 void vpush64(int ty, unsigned long long v)
361 CValue cval;
362 CType ctype;
363 ctype.t = ty;
364 cval.ull = v;
365 vsetc(&ctype, VT_CONST, &cval);
368 /* Return a static symbol pointing to a section */
369 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
371 int v;
372 Sym *sym;
374 v = anon_sym++;
375 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
376 sym->type.ref = type->ref;
377 sym->r = VT_CONST | VT_SYM;
378 put_extern_sym(sym, sec, offset, size);
379 return sym;
382 /* push a reference to a section offset by adding a dummy symbol */
383 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
385 CValue cval;
387 cval.ul = 0;
388 vsetc(type, VT_CONST | VT_SYM, &cval);
389 vtop->sym = get_sym_ref(type, sec, offset, size);
392 /* define a new external reference to a symbol 'v' of type 'u' */
393 ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
395 Sym *s;
397 s = sym_find(v);
398 if (!s) {
399 /* push forward reference */
400 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
401 s->type.ref = type->ref;
402 s->r = r | VT_CONST | VT_SYM;
404 return s;
407 /* define a new external reference to a symbol 'v' with alternate asm
408 name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
409 is no alternate name (most cases) */
410 static Sym *external_sym(int v, CType *type, int r, char *asm_label)
412 Sym *s;
414 s = sym_find(v);
415 if (!s) {
416 /* push forward reference */
417 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
418 s->asm_label = asm_label;
419 s->type.t |= VT_EXTERN;
420 } else if (s->type.ref == func_old_type.ref) {
421 s->type.ref = type->ref;
422 s->r = r | VT_CONST | VT_SYM;
423 s->type.t |= VT_EXTERN;
424 } else if (!is_compatible_types(&s->type, type)) {
425 tcc_error("incompatible types for redefinition of '%s'",
426 get_tok_str(v, NULL));
428 return s;
431 /* push a reference to global symbol v */
432 ST_FUNC void vpush_global_sym(CType *type, int v)
434 Sym *sym;
435 CValue cval;
437 sym = external_global_sym(v, type, 0);
438 cval.ul = 0;
439 vsetc(type, VT_CONST | VT_SYM, &cval);
440 vtop->sym = sym;
443 ST_FUNC void vset(CType *type, int r, int v)
445 CValue cval;
447 cval.i = v;
448 vsetc(type, r, &cval);
451 static void vseti(int r, int v)
453 CType type;
454 type.t = VT_INT;
455 type.ref = 0;
456 vset(&type, r, v);
459 ST_FUNC void vswap(void)
461 SValue tmp;
462 /* cannot let cpu flags if other instruction are generated. Also
463 avoid leaving VT_JMP anywhere except on the top of the stack
464 because it would complicate the code generator. */
465 if (vtop >= vstack) {
466 int v = vtop->r & VT_VALMASK;
467 if (v == VT_CMP || (v & ~1) == VT_JMP)
468 gv(RC_INT);
470 tmp = vtop[0];
471 vtop[0] = vtop[-1];
472 vtop[-1] = tmp;
474 /* XXX: +2% overall speed possible with optimized memswap
476 * memswap(&vtop[0], &vtop[1], sizeof *vtop);
480 ST_FUNC void vpushv(SValue *v)
482 if (vtop >= vstack + (VSTACK_SIZE - 1))
483 tcc_error("memory full");
484 vtop++;
485 *vtop = *v;
488 static void vdup(void)
490 vpushv(vtop);
493 /* save r to the memory stack, and mark it as being free */
494 ST_FUNC void save_reg(int r)
496 int l, saved, size, align;
497 SValue *p, sv;
498 CType *type;
500 /* modify all stack values */
501 saved = 0;
502 l = 0;
503 for(p=vstack;p<=vtop;p++) {
504 if ((p->r & VT_VALMASK) == r ||
505 ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
506 /* must save value on stack if not already done */
507 if (!saved) {
508 /* NOTE: must reload 'r' because r might be equal to r2 */
509 r = p->r & VT_VALMASK;
510 /* store register in the stack */
511 type = &p->type;
512 if ((p->r & VT_LVAL) ||
513 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
514 #ifdef TCC_TARGET_X86_64
515 type = &char_pointer_type;
516 #else
517 type = &int_type;
518 #endif
519 size = type_size(type, &align);
520 loc = (loc - size) & -align;
521 sv.type.t = type->t;
522 sv.r = VT_LOCAL | VT_LVAL;
523 sv.c.ul = loc;
524 store(r, &sv);
525 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
526 /* x86 specific: need to pop fp register ST0 if saved */
527 if (r == TREG_ST0) {
528 o(0xd8dd); /* fstp %st(0) */
530 #endif
531 #ifndef TCC_TARGET_X86_64
532 /* special long long case */
533 if ((type->t & VT_BTYPE) == VT_LLONG) {
534 sv.c.ul += 4;
535 store(p->r2, &sv);
537 #endif
538 l = loc;
539 saved = 1;
541 /* mark that stack entry as being saved on the stack */
542 if (p->r & VT_LVAL) {
543 /* also clear the bounded flag because the
544 relocation address of the function was stored in
545 p->c.ul */
546 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
547 } else {
548 p->r = lvalue_type(p->type.t) | VT_LOCAL;
550 p->r2 = VT_CONST;
551 p->c.ul = l;
556 #ifdef TCC_TARGET_ARM
557 /* find a register of class 'rc2' with at most one reference on stack.
558 * If none, call get_reg(rc) */
559 ST_FUNC int get_reg_ex(int rc, int rc2)
561 int r;
562 SValue *p;
564 for(r=0;r<NB_REGS;r++) {
565 if (reg_classes[r] & rc2) {
566 int n;
567 n=0;
568 for(p = vstack; p <= vtop; p++) {
569 if ((p->r & VT_VALMASK) == r ||
570 (p->r2 & VT_VALMASK) == r)
571 n++;
573 if (n <= 1)
574 return r;
577 return get_reg(rc);
579 #endif
581 /* find a free register of class 'rc'. If none, save one register */
582 ST_FUNC int get_reg(int rc)
584 int r;
585 SValue *p;
587 /* find a free register */
588 for(r=0;r<NB_REGS;r++) {
589 if (reg_classes[r] & rc) {
590 for(p=vstack;p<=vtop;p++) {
591 if ((p->r & VT_VALMASK) == r ||
592 (p->r2 & VT_VALMASK) == r)
593 goto notfound;
595 return r;
597 notfound: ;
600 /* no register left : free the first one on the stack (VERY
601 IMPORTANT to start from the bottom to ensure that we don't
602 spill registers used in gen_opi()) */
603 for(p=vstack;p<=vtop;p++) {
604 /* look at second register (if long long) */
605 r = p->r2 & VT_VALMASK;
606 if (r < VT_CONST && (reg_classes[r] & rc))
607 goto save_found;
608 r = p->r & VT_VALMASK;
609 if (r < VT_CONST && (reg_classes[r] & rc)) {
610 save_found:
611 save_reg(r);
612 return r;
615 /* Should never comes here */
616 return -1;
619 /* save registers up to (vtop - n) stack entry */
620 ST_FUNC void save_regs(int n)
622 int r;
623 SValue *p, *p1;
624 p1 = vtop - n;
625 for(p = vstack;p <= p1; p++) {
626 r = p->r & VT_VALMASK;
627 if (r < VT_CONST) {
628 save_reg(r);
633 /* move register 's' to 'r', and flush previous value of r to memory
634 if needed */
635 static void move_reg(int r, int s)
637 SValue sv;
639 if (r != s) {
640 save_reg(r);
641 sv.type.t = VT_INT;
642 sv.r = s;
643 sv.c.ul = 0;
644 load(r, &sv);
648 /* get address of vtop (vtop MUST BE an lvalue) */
649 static void gaddrof(void)
651 if (vtop->r & VT_REF)
652 gv(RC_INT);
653 vtop->r &= ~VT_LVAL;
654 /* tricky: if saved lvalue, then we can go back to lvalue */
655 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
656 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
661 #ifdef CONFIG_TCC_BCHECK
662 /* generate lvalue bound code */
663 static void gbound(void)
665 int lval_type;
666 CType type1;
668 vtop->r &= ~VT_MUSTBOUND;
669 /* if lvalue, then use checking code before dereferencing */
670 if (vtop->r & VT_LVAL) {
671 /* if not VT_BOUNDED value, then make one */
672 if (!(vtop->r & VT_BOUNDED)) {
673 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
674 /* must save type because we must set it to int to get pointer */
675 type1 = vtop->type;
676 vtop->type.t = VT_INT;
677 gaddrof();
678 vpushi(0);
679 gen_bounded_ptr_add();
680 vtop->r |= lval_type;
681 vtop->type = type1;
683 /* then check for dereferencing */
684 gen_bounded_ptr_deref();
687 #endif
689 /* store vtop a register belonging to class 'rc'. lvalues are
690 converted to values. Cannot be used if cannot be converted to
691 register value (such as structures). */
692 ST_FUNC int gv(int rc)
694 int r, bit_pos, bit_size, size, align, i;
695 #ifndef TCC_TARGET_X86_64
696 int rc2;
697 #endif
699 /* NOTE: get_reg can modify vstack[] */
700 if (vtop->type.t & VT_BITFIELD) {
701 CType type;
702 int bits = 32;
703 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
704 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
705 /* remove bit field info to avoid loops */
706 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
707 /* cast to int to propagate signedness in following ops */
708 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
709 type.t = VT_LLONG;
710 bits = 64;
711 } else
712 type.t = VT_INT;
713 if((vtop->type.t & VT_UNSIGNED) ||
714 (vtop->type.t & VT_BTYPE) == VT_BOOL)
715 type.t |= VT_UNSIGNED;
716 gen_cast(&type);
717 /* generate shifts */
718 vpushi(bits - (bit_pos + bit_size));
719 gen_op(TOK_SHL);
720 vpushi(bits - bit_size);
721 /* NOTE: transformed to SHR if unsigned */
722 gen_op(TOK_SAR);
723 r = gv(rc);
724 } else {
725 if (is_float(vtop->type.t) &&
726 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
727 Sym *sym;
728 int *ptr;
729 unsigned long offset;
730 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
731 CValue check;
732 #endif
734 /* XXX: unify with initializers handling ? */
735 /* CPUs usually cannot use float constants, so we store them
736 generically in data segment */
737 size = type_size(&vtop->type, &align);
738 offset = (data_section->data_offset + align - 1) & -align;
739 data_section->data_offset = offset;
740 /* XXX: not portable yet */
741 #if defined(__i386__) || defined(__x86_64__)
742 /* Zero pad x87 tenbyte long doubles */
743 if (size == LDOUBLE_SIZE) {
744 vtop->c.tab[2] &= 0xffff;
745 #if LDOUBLE_SIZE == 16
746 vtop->c.tab[3] = 0;
747 #endif
749 #endif
750 ptr = section_ptr_add(data_section, size);
751 size = size >> 2;
752 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
753 check.d = 1;
754 if(check.tab[0])
755 for(i=0;i<size;i++)
756 ptr[i] = vtop->c.tab[size-1-i];
757 else
758 #endif
759 for(i=0;i<size;i++)
760 ptr[i] = vtop->c.tab[i];
761 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
762 vtop->r |= VT_LVAL | VT_SYM;
763 vtop->sym = sym;
764 vtop->c.ul = 0;
766 #ifdef CONFIG_TCC_BCHECK
767 if (vtop->r & VT_MUSTBOUND)
768 gbound();
769 #endif
771 r = vtop->r & VT_VALMASK;
772 #ifndef TCC_TARGET_X86_64
773 rc2 = RC_INT;
774 if (rc == RC_IRET)
775 rc2 = RC_LRET;
776 #endif
777 /* need to reload if:
778 - constant
779 - lvalue (need to dereference pointer)
780 - already a register, but not in the right class */
781 if (r >= VT_CONST
782 || (vtop->r & VT_LVAL)
783 || !(reg_classes[r] & rc)
784 #ifndef TCC_TARGET_X86_64
785 || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
786 #endif
789 r = get_reg(rc);
790 #ifndef TCC_TARGET_X86_64
791 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
792 int r2;
793 unsigned long long ll;
794 /* two register type load : expand to two words
795 temporarily */
796 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
797 /* load constant */
798 ll = vtop->c.ull;
799 vtop->c.ui = ll; /* first word */
800 load(r, vtop);
801 vtop->r = r; /* save register value */
802 vpushi(ll >> 32); /* second word */
803 } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
804 (vtop->r & VT_LVAL)) {
805 /* We do not want to modifier the long long
806 pointer here, so the safest (and less
807 efficient) is to save all the other registers
808 in the stack. XXX: totally inefficient. */
809 save_regs(1);
810 /* load from memory */
811 load(r, vtop);
812 vdup();
813 vtop[-1].r = r; /* save register value */
814 /* increment pointer to get second word */
815 vtop->type.t = VT_INT;
816 gaddrof();
817 vpushi(4);
818 gen_op('+');
819 vtop->r |= VT_LVAL;
820 } else {
821 /* move registers */
822 load(r, vtop);
823 vdup();
824 vtop[-1].r = r; /* save register value */
825 vtop->r = vtop[-1].r2;
827 /* Allocate second register. Here we rely on the fact that
828 get_reg() tries first to free r2 of an SValue. */
829 r2 = get_reg(rc2);
830 load(r2, vtop);
831 vpop();
832 /* write second register */
833 vtop->r2 = r2;
834 } else
835 #endif
836 if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
837 int t1, t;
838 /* lvalue of scalar type : need to use lvalue type
839 because of possible cast */
840 t = vtop->type.t;
841 t1 = t;
842 /* compute memory access type */
843 if (vtop->r & VT_LVAL_BYTE)
844 t = VT_BYTE;
845 else if (vtop->r & VT_LVAL_SHORT)
846 t = VT_SHORT;
847 if (vtop->r & VT_LVAL_UNSIGNED)
848 t |= VT_UNSIGNED;
849 vtop->type.t = t;
850 load(r, vtop);
851 /* restore wanted type */
852 vtop->type.t = t1;
853 } else {
854 /* one register type load */
855 load(r, vtop);
858 vtop->r = r;
859 #ifdef TCC_TARGET_C67
860 /* uses register pairs for doubles */
861 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
862 vtop->r2 = r+1;
863 #endif
865 return r;
868 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
869 ST_FUNC void gv2(int rc1, int rc2)
871 int v;
873 /* generate more generic register first. But VT_JMP or VT_CMP
874 values must be generated first in all cases to avoid possible
875 reload errors */
876 v = vtop[0].r & VT_VALMASK;
877 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
878 vswap();
879 gv(rc1);
880 vswap();
881 gv(rc2);
882 /* test if reload is needed for first register */
883 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
884 vswap();
885 gv(rc1);
886 vswap();
888 } else {
889 gv(rc2);
890 vswap();
891 gv(rc1);
892 vswap();
893 /* test if reload is needed for first register */
894 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
895 gv(rc2);
900 /* wrapper around RC_FRET to return a register by type */
901 static int rc_fret(int t)
903 #ifdef TCC_TARGET_X86_64
904 if (t == VT_LDOUBLE) {
905 return RC_ST0;
907 #endif
908 return RC_FRET;
911 /* wrapper around REG_FRET to return a register by type */
912 static int reg_fret(int t)
914 #ifdef TCC_TARGET_X86_64
915 if (t == VT_LDOUBLE) {
916 return TREG_ST0;
918 #endif
919 return REG_FRET;
922 /* expand long long on stack in two int registers */
923 static void lexpand(void)
925 int u;
927 u = vtop->type.t & VT_UNSIGNED;
928 gv(RC_INT);
929 vdup();
930 vtop[0].r = vtop[-1].r2;
931 vtop[0].r2 = VT_CONST;
932 vtop[-1].r2 = VT_CONST;
933 vtop[0].type.t = VT_INT | u;
934 vtop[-1].type.t = VT_INT | u;
937 #ifdef TCC_TARGET_ARM
938 /* expand long long on stack */
939 ST_FUNC void lexpand_nr(void)
941 int u,v;
943 u = vtop->type.t & VT_UNSIGNED;
944 vdup();
945 vtop->r2 = VT_CONST;
946 vtop->type.t = VT_INT | u;
947 v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
948 if (v == VT_CONST) {
949 vtop[-1].c.ui = vtop->c.ull;
950 vtop->c.ui = vtop->c.ull >> 32;
951 vtop->r = VT_CONST;
952 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
953 vtop->c.ui += 4;
954 vtop->r = vtop[-1].r;
955 } else if (v > VT_CONST) {
956 vtop--;
957 lexpand();
958 } else
959 vtop->r = vtop[-1].r2;
960 vtop[-1].r2 = VT_CONST;
961 vtop[-1].type.t = VT_INT | u;
963 #endif
965 /* build a long long from two ints */
966 static void lbuild(int t)
968 gv2(RC_INT, RC_INT);
969 vtop[-1].r2 = vtop[0].r;
970 vtop[-1].type.t = t;
971 vpop();
974 /* rotate n first stack elements to the bottom
975 I1 ... In -> I2 ... In I1 [top is right]
977 ST_FUNC void vrotb(int n)
979 int i;
980 SValue tmp;
982 tmp = vtop[-n + 1];
983 for(i=-n+1;i!=0;i++)
984 vtop[i] = vtop[i+1];
985 vtop[0] = tmp;
988 /* rotate the n elements before entry e towards the top
989 I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
991 ST_FUNC void vrote(SValue *e, int n)
993 int i;
994 SValue tmp;
996 tmp = *e;
997 for(i = 0;i < n - 1; i++)
998 e[-i] = e[-i - 1];
999 e[-n + 1] = tmp;
1002 /* rotate n first stack elements to the top
1003 I1 ... In -> In I1 ... I(n-1) [top is right]
1005 ST_FUNC void vrott(int n)
1007 vrote(vtop, n);
1010 /* pop stack value */
1011 ST_FUNC void vpop(void)
1013 int v;
1014 v = vtop->r & VT_VALMASK;
1015 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1016 /* for x86, we need to pop the FP stack */
1017 if (v == TREG_ST0 && !nocode_wanted) {
1018 o(0xd8dd); /* fstp %st(0) */
1019 } else
1020 #endif
1021 if (v == VT_JMP || v == VT_JMPI) {
1022 /* need to put correct jump if && or || without test */
1023 gsym(vtop->c.ul);
1025 vtop--;
1028 /* convert stack entry to register and duplicate its value in another
1029 register */
1030 static void gv_dup(void)
1032 int rc, t, r, r1;
1033 SValue sv;
1035 t = vtop->type.t;
1036 if ((t & VT_BTYPE) == VT_LLONG) {
1037 lexpand();
1038 gv_dup();
1039 vswap();
1040 vrotb(3);
1041 gv_dup();
1042 vrotb(4);
1043 /* stack: H L L1 H1 */
1044 lbuild(t);
1045 vrotb(3);
1046 vrotb(3);
1047 vswap();
1048 lbuild(t);
1049 vswap();
1050 } else {
1051 /* duplicate value */
1052 rc = RC_INT;
1053 sv.type.t = VT_INT;
1054 if (is_float(t)) {
1055 rc = RC_FLOAT;
1056 #ifdef TCC_TARGET_X86_64
1057 if ((t & VT_BTYPE) == VT_LDOUBLE) {
1058 rc = RC_ST0;
1060 #endif
1061 sv.type.t = t;
1063 r = gv(rc);
1064 r1 = get_reg(rc);
1065 sv.r = r;
1066 sv.c.ul = 0;
1067 load(r1, &sv); /* move r to r1 */
1068 vdup();
1069 /* duplicates value */
1070 if (r != r1)
1071 vtop->r = r1;
1075 #ifndef TCC_TARGET_X86_64
1076 /* generate CPU independent (unsigned) long long operations */
1077 static void gen_opl(int op)
1079 int t, a, b, op1, c, i;
1080 int func;
1081 unsigned short reg_iret = REG_IRET;
1082 unsigned short reg_lret = REG_LRET;
1083 SValue tmp;
1085 switch(op) {
1086 case '/':
1087 case TOK_PDIV:
1088 func = TOK___divdi3;
1089 goto gen_func;
1090 case TOK_UDIV:
1091 func = TOK___udivdi3;
1092 goto gen_func;
1093 case '%':
1094 func = TOK___moddi3;
1095 goto gen_mod_func;
1096 case TOK_UMOD:
1097 func = TOK___umoddi3;
1098 gen_mod_func:
1099 #ifdef TCC_ARM_EABI
1100 reg_iret = TREG_R2;
1101 reg_lret = TREG_R3;
1102 #endif
1103 gen_func:
1104 /* call generic long long function */
1105 vpush_global_sym(&func_old_type, func);
1106 vrott(3);
1107 gfunc_call(2);
1108 vpushi(0);
1109 vtop->r = reg_iret;
1110 vtop->r2 = reg_lret;
1111 break;
1112 case '^':
1113 case '&':
1114 case '|':
1115 case '*':
1116 case '+':
1117 case '-':
1118 t = vtop->type.t;
1119 vswap();
1120 lexpand();
1121 vrotb(3);
1122 lexpand();
1123 /* stack: L1 H1 L2 H2 */
1124 tmp = vtop[0];
1125 vtop[0] = vtop[-3];
1126 vtop[-3] = tmp;
1127 tmp = vtop[-2];
1128 vtop[-2] = vtop[-3];
1129 vtop[-3] = tmp;
1130 vswap();
1131 /* stack: H1 H2 L1 L2 */
1132 if (op == '*') {
1133 vpushv(vtop - 1);
1134 vpushv(vtop - 1);
1135 gen_op(TOK_UMULL);
1136 lexpand();
1137 /* stack: H1 H2 L1 L2 ML MH */
1138 for(i=0;i<4;i++)
1139 vrotb(6);
1140 /* stack: ML MH H1 H2 L1 L2 */
1141 tmp = vtop[0];
1142 vtop[0] = vtop[-2];
1143 vtop[-2] = tmp;
1144 /* stack: ML MH H1 L2 H2 L1 */
1145 gen_op('*');
1146 vrotb(3);
1147 vrotb(3);
1148 gen_op('*');
1149 /* stack: ML MH M1 M2 */
1150 gen_op('+');
1151 gen_op('+');
1152 } else if (op == '+' || op == '-') {
1153 /* XXX: add non carry method too (for MIPS or alpha) */
1154 if (op == '+')
1155 op1 = TOK_ADDC1;
1156 else
1157 op1 = TOK_SUBC1;
1158 gen_op(op1);
1159 /* stack: H1 H2 (L1 op L2) */
1160 vrotb(3);
1161 vrotb(3);
1162 gen_op(op1 + 1); /* TOK_xxxC2 */
1163 } else {
1164 gen_op(op);
1165 /* stack: H1 H2 (L1 op L2) */
1166 vrotb(3);
1167 vrotb(3);
1168 /* stack: (L1 op L2) H1 H2 */
1169 gen_op(op);
1170 /* stack: (L1 op L2) (H1 op H2) */
1172 /* stack: L H */
1173 lbuild(t);
1174 break;
1175 case TOK_SAR:
1176 case TOK_SHR:
1177 case TOK_SHL:
1178 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1179 t = vtop[-1].type.t;
1180 vswap();
1181 lexpand();
1182 vrotb(3);
1183 /* stack: L H shift */
1184 c = (int)vtop->c.i;
1185 /* constant: simpler */
1186 /* NOTE: all comments are for SHL. the other cases are
1187 done by swaping words */
1188 vpop();
1189 if (op != TOK_SHL)
1190 vswap();
1191 if (c >= 32) {
1192 /* stack: L H */
1193 vpop();
1194 if (c > 32) {
1195 vpushi(c - 32);
1196 gen_op(op);
1198 if (op != TOK_SAR) {
1199 vpushi(0);
1200 } else {
1201 gv_dup();
1202 vpushi(31);
1203 gen_op(TOK_SAR);
1205 vswap();
1206 } else {
1207 vswap();
1208 gv_dup();
1209 /* stack: H L L */
1210 vpushi(c);
1211 gen_op(op);
1212 vswap();
1213 vpushi(32 - c);
1214 if (op == TOK_SHL)
1215 gen_op(TOK_SHR);
1216 else
1217 gen_op(TOK_SHL);
1218 vrotb(3);
1219 /* stack: L L H */
1220 vpushi(c);
1221 if (op == TOK_SHL)
1222 gen_op(TOK_SHL);
1223 else
1224 gen_op(TOK_SHR);
1225 gen_op('|');
1227 if (op != TOK_SHL)
1228 vswap();
1229 lbuild(t);
1230 } else {
1231 /* XXX: should provide a faster fallback on x86 ? */
1232 switch(op) {
1233 case TOK_SAR:
1234 func = TOK___ashrdi3;
1235 goto gen_func;
1236 case TOK_SHR:
1237 func = TOK___lshrdi3;
1238 goto gen_func;
1239 case TOK_SHL:
1240 func = TOK___ashldi3;
1241 goto gen_func;
1244 break;
1245 default:
1246 /* compare operations */
1247 t = vtop->type.t;
1248 vswap();
1249 lexpand();
1250 vrotb(3);
1251 lexpand();
1252 /* stack: L1 H1 L2 H2 */
1253 tmp = vtop[-1];
1254 vtop[-1] = vtop[-2];
1255 vtop[-2] = tmp;
1256 /* stack: L1 L2 H1 H2 */
1257 /* compare high */
1258 op1 = op;
1259 /* when values are equal, we need to compare low words. since
1260 the jump is inverted, we invert the test too. */
1261 if (op1 == TOK_LT)
1262 op1 = TOK_LE;
1263 else if (op1 == TOK_GT)
1264 op1 = TOK_GE;
1265 else if (op1 == TOK_ULT)
1266 op1 = TOK_ULE;
1267 else if (op1 == TOK_UGT)
1268 op1 = TOK_UGE;
1269 a = 0;
1270 b = 0;
1271 gen_op(op1);
1272 if (op1 != TOK_NE) {
1273 a = gtst(1, 0);
1275 if (op != TOK_EQ) {
1276 /* generate non equal test */
1277 /* XXX: NOT PORTABLE yet */
1278 if (a == 0) {
1279 b = gtst(0, 0);
1280 } else {
1281 #if defined(TCC_TARGET_I386)
1282 b = psym(0x850f, 0);
1283 #elif defined(TCC_TARGET_ARM)
1284 b = ind;
1285 o(0x1A000000 | encbranch(ind, 0, 1));
1286 #elif defined(TCC_TARGET_C67)
1287 tcc_error("not implemented");
1288 #else
1289 #error not supported
1290 #endif
1293 /* compare low. Always unsigned */
1294 op1 = op;
1295 if (op1 == TOK_LT)
1296 op1 = TOK_ULT;
1297 else if (op1 == TOK_LE)
1298 op1 = TOK_ULE;
1299 else if (op1 == TOK_GT)
1300 op1 = TOK_UGT;
1301 else if (op1 == TOK_GE)
1302 op1 = TOK_UGE;
1303 gen_op(op1);
1304 a = gtst(1, a);
1305 gsym(b);
1306 vseti(VT_JMPI, a);
1307 break;
1310 #endif
1312 /* handle integer constant optimizations and various machine
1313 independent opt */
1314 static void gen_opic(int op)
1316 int c1, c2, t1, t2, n;
1317 SValue *v1, *v2;
1318 long long l1, l2;
1319 typedef unsigned long long U;
1321 v1 = vtop - 1;
1322 v2 = vtop;
1323 t1 = v1->type.t & VT_BTYPE;
1324 t2 = v2->type.t & VT_BTYPE;
1326 if (t1 == VT_LLONG)
1327 l1 = v1->c.ll;
1328 else if (v1->type.t & VT_UNSIGNED)
1329 l1 = v1->c.ui;
1330 else
1331 l1 = v1->c.i;
1333 if (t2 == VT_LLONG)
1334 l2 = v2->c.ll;
1335 else if (v2->type.t & VT_UNSIGNED)
1336 l2 = v2->c.ui;
1337 else
1338 l2 = v2->c.i;
1340 /* currently, we cannot do computations with forward symbols */
1341 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1342 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1343 if (c1 && c2) {
1344 switch(op) {
1345 case '+': l1 += l2; break;
1346 case '-': l1 -= l2; break;
1347 case '&': l1 &= l2; break;
1348 case '^': l1 ^= l2; break;
1349 case '|': l1 |= l2; break;
1350 case '*': l1 *= l2; break;
1352 case TOK_PDIV:
1353 case '/':
1354 case '%':
1355 case TOK_UDIV:
1356 case TOK_UMOD:
1357 /* if division by zero, generate explicit division */
1358 if (l2 == 0) {
1359 if (const_wanted)
1360 tcc_error("division by zero in constant");
1361 goto general_case;
1363 switch(op) {
1364 default: l1 /= l2; break;
1365 case '%': l1 %= l2; break;
1366 case TOK_UDIV: l1 = (U)l1 / l2; break;
1367 case TOK_UMOD: l1 = (U)l1 % l2; break;
1369 break;
1370 case TOK_SHL: l1 <<= l2; break;
1371 case TOK_SHR: l1 = (U)l1 >> l2; break;
1372 case TOK_SAR: l1 >>= l2; break;
1373 /* tests */
1374 case TOK_ULT: l1 = (U)l1 < (U)l2; break;
1375 case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
1376 case TOK_EQ: l1 = l1 == l2; break;
1377 case TOK_NE: l1 = l1 != l2; break;
1378 case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
1379 case TOK_UGT: l1 = (U)l1 > (U)l2; break;
1380 case TOK_LT: l1 = l1 < l2; break;
1381 case TOK_GE: l1 = l1 >= l2; break;
1382 case TOK_LE: l1 = l1 <= l2; break;
1383 case TOK_GT: l1 = l1 > l2; break;
1384 /* logical */
1385 case TOK_LAND: l1 = l1 && l2; break;
1386 case TOK_LOR: l1 = l1 || l2; break;
1387 default:
1388 goto general_case;
1390 v1->c.ll = l1;
1391 vtop--;
1392 } else {
1393 /* if commutative ops, put c2 as constant */
1394 if (c1 && (op == '+' || op == '&' || op == '^' ||
1395 op == '|' || op == '*')) {
1396 vswap();
1397 c2 = c1; //c = c1, c1 = c2, c2 = c;
1398 l2 = l1; //l = l1, l1 = l2, l2 = l;
1400 /* Filter out NOP operations like x*1, x-0, x&-1... */
1401 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
1402 op == TOK_PDIV) &&
1403 l2 == 1) ||
1404 ((op == '+' || op == '-' || op == '|' || op == '^' ||
1405 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
1406 l2 == 0) ||
1407 (op == '&' &&
1408 l2 == -1))) {
1409 /* nothing to do */
1410 vtop--;
1411 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
1412 /* try to use shifts instead of muls or divs */
1413 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
1414 n = -1;
1415 while (l2) {
1416 l2 >>= 1;
1417 n++;
1419 vtop->c.ll = n;
1420 if (op == '*')
1421 op = TOK_SHL;
1422 else if (op == TOK_PDIV)
1423 op = TOK_SAR;
1424 else
1425 op = TOK_SHR;
1427 goto general_case;
1428 } else if (c2 && (op == '+' || op == '-') &&
1429 (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
1430 || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
1431 /* symbol + constant case */
1432 if (op == '-')
1433 l2 = -l2;
1434 vtop--;
1435 vtop->c.ll += l2;
1436 } else {
1437 general_case:
1438 if (!nocode_wanted) {
1439 /* call low level op generator */
1440 if (t1 == VT_LLONG || t2 == VT_LLONG)
1441 gen_opl(op);
1442 else
1443 gen_opi(op);
1444 } else {
1445 vtop--;
1451 /* generate a floating point operation with constant propagation */
1452 static void gen_opif(int op)
1454 int c1, c2;
1455 SValue *v1, *v2;
1456 long double f1, f2;
1458 v1 = vtop - 1;
1459 v2 = vtop;
1460 /* currently, we cannot do computations with forward symbols */
1461 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1462 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1463 if (c1 && c2) {
1464 if (v1->type.t == VT_FLOAT) {
1465 f1 = v1->c.f;
1466 f2 = v2->c.f;
1467 } else if (v1->type.t == VT_DOUBLE) {
1468 f1 = v1->c.d;
1469 f2 = v2->c.d;
1470 } else {
1471 f1 = v1->c.ld;
1472 f2 = v2->c.ld;
1475 /* NOTE: we only do constant propagation if finite number (not
1476 NaN or infinity) (ANSI spec) */
1477 if (!ieee_finite(f1) || !ieee_finite(f2))
1478 goto general_case;
1480 switch(op) {
1481 case '+': f1 += f2; break;
1482 case '-': f1 -= f2; break;
1483 case '*': f1 *= f2; break;
1484 case '/':
1485 if (f2 == 0.0) {
1486 if (const_wanted)
1487 tcc_error("division by zero in constant");
1488 goto general_case;
1490 f1 /= f2;
1491 break;
1492 /* XXX: also handles tests ? */
1493 default:
1494 goto general_case;
1496 /* XXX: overflow test ? */
1497 if (v1->type.t == VT_FLOAT) {
1498 v1->c.f = f1;
1499 } else if (v1->type.t == VT_DOUBLE) {
1500 v1->c.d = f1;
1501 } else {
1502 v1->c.ld = f1;
1504 vtop--;
1505 } else {
1506 general_case:
1507 if (!nocode_wanted) {
1508 gen_opf(op);
1509 } else {
1510 vtop--;
1515 static int pointed_size(CType *type)
1517 int align;
1518 return type_size(pointed_type(type), &align);
1521 static void vla_runtime_pointed_size(CType *type)
1523 int align;
1524 vla_runtime_type_size(pointed_type(type), &align);
1527 static inline int is_null_pointer(SValue *p)
1529 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1530 return 0;
1531 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
1532 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||
1533 ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr == 0);
1536 static inline int is_integer_btype(int bt)
1538 return (bt == VT_BYTE || bt == VT_SHORT ||
1539 bt == VT_INT || bt == VT_LLONG);
1542 /* check types for comparison or substraction of pointers */
1543 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
1545 CType *type1, *type2, tmp_type1, tmp_type2;
1546 int bt1, bt2;
1548 /* null pointers are accepted for all comparisons as gcc */
1549 if (is_null_pointer(p1) || is_null_pointer(p2))
1550 return;
1551 type1 = &p1->type;
1552 type2 = &p2->type;
1553 bt1 = type1->t & VT_BTYPE;
1554 bt2 = type2->t & VT_BTYPE;
1555 /* accept comparison between pointer and integer with a warning */
1556 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
1557 if (op != TOK_LOR && op != TOK_LAND )
1558 tcc_warning("comparison between pointer and integer");
1559 return;
1562 /* both must be pointers or implicit function pointers */
1563 if (bt1 == VT_PTR) {
1564 type1 = pointed_type(type1);
1565 } else if (bt1 != VT_FUNC)
1566 goto invalid_operands;
1568 if (bt2 == VT_PTR) {
1569 type2 = pointed_type(type2);
1570 } else if (bt2 != VT_FUNC) {
1571 invalid_operands:
1572 tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
1574 if ((type1->t & VT_BTYPE) == VT_VOID ||
1575 (type2->t & VT_BTYPE) == VT_VOID)
1576 return;
1577 tmp_type1 = *type1;
1578 tmp_type2 = *type2;
1579 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1580 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
1581 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
1582 /* gcc-like error if '-' is used */
1583 if (op == '-')
1584 goto invalid_operands;
1585 else
1586 tcc_warning("comparison of distinct pointer types lacks a cast");
1590 /* generic gen_op: handles types problems */
1591 ST_FUNC void gen_op(int op)
1593 int u, t1, t2, bt1, bt2, t;
1594 CType type1;
1596 t1 = vtop[-1].type.t;
1597 t2 = vtop[0].type.t;
1598 bt1 = t1 & VT_BTYPE;
1599 bt2 = t2 & VT_BTYPE;
1601 if (bt1 == VT_PTR || bt2 == VT_PTR) {
1602 /* at least one operand is a pointer */
1603 /* relationnal op: must be both pointers */
1604 if (op >= TOK_ULT && op <= TOK_LOR) {
1605 check_comparison_pointer_types(vtop - 1, vtop, op);
1606 /* pointers are handled are unsigned */
1607 #ifdef TCC_TARGET_X86_64
1608 t = VT_LLONG | VT_UNSIGNED;
1609 #else
1610 t = VT_INT | VT_UNSIGNED;
1611 #endif
1612 goto std_op;
1614 /* if both pointers, then it must be the '-' op */
1615 if (bt1 == VT_PTR && bt2 == VT_PTR) {
1616 if (op != '-')
1617 tcc_error("cannot use pointers here");
1618 check_comparison_pointer_types(vtop - 1, vtop, op);
1619 /* XXX: check that types are compatible */
1620 if (vtop[-1].type.t & VT_VLA) {
1621 vla_runtime_pointed_size(&vtop[-1].type);
1622 } else {
1623 vpushi(pointed_size(&vtop[-1].type));
1625 vrott(3);
1626 gen_opic(op);
1627 /* set to integer type */
1628 #ifdef TCC_TARGET_X86_64
1629 vtop->type.t = VT_LLONG;
1630 #else
1631 vtop->type.t = VT_INT;
1632 #endif
1633 vswap();
1634 gen_op(TOK_PDIV);
1635 } else {
1636 /* exactly one pointer : must be '+' or '-'. */
1637 if (op != '-' && op != '+')
1638 tcc_error("cannot use pointers here");
1639 /* Put pointer as first operand */
1640 if (bt2 == VT_PTR) {
1641 vswap();
1642 swap(&t1, &t2);
1644 type1 = vtop[-1].type;
1645 type1.t &= ~VT_ARRAY;
1646 if (vtop[-1].type.t & VT_VLA)
1647 vla_runtime_pointed_size(&vtop[-1].type);
1648 else {
1649 u = pointed_size(&vtop[-1].type);
1650 if (u < 0)
1651 tcc_error("unknown array element size");
1652 #ifdef TCC_TARGET_X86_64
1653 vpushll(u);
1654 #else
1655 /* XXX: cast to int ? (long long case) */
1656 vpushi(u);
1657 #endif
1659 gen_op('*');
1660 #ifdef CONFIG_TCC_BCHECK
1661 /* if evaluating constant expression, no code should be
1662 generated, so no bound check */
1663 if (tcc_state->do_bounds_check && !const_wanted) {
1664 /* if bounded pointers, we generate a special code to
1665 test bounds */
1666 if (op == '-') {
1667 vpushi(0);
1668 vswap();
1669 gen_op('-');
1671 gen_bounded_ptr_add();
1672 } else
1673 #endif
1675 gen_opic(op);
1677 /* put again type if gen_opic() swaped operands */
1678 vtop->type = type1;
1680 } else if (is_float(bt1) || is_float(bt2)) {
1681 /* compute bigger type and do implicit casts */
1682 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
1683 t = VT_LDOUBLE;
1684 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
1685 t = VT_DOUBLE;
1686 } else {
1687 t = VT_FLOAT;
1689 /* floats can only be used for a few operations */
1690 if (op != '+' && op != '-' && op != '*' && op != '/' &&
1691 (op < TOK_ULT || op > TOK_GT))
1692 tcc_error("invalid operands for binary operation");
1693 goto std_op;
1694 } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
1695 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
1696 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (t | VT_UNSIGNED))
1697 t |= VT_UNSIGNED;
1698 goto std_op;
1699 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
1700 /* cast to biggest op */
1701 t = VT_LLONG;
1702 /* convert to unsigned if it does not fit in a long long */
1703 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
1704 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
1705 t |= VT_UNSIGNED;
1706 goto std_op;
1707 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
1708 tcc_error("comparison of struct");
1709 } else {
1710 /* integer operations */
1711 t = VT_INT;
1712 /* convert to unsigned if it does not fit in an integer */
1713 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
1714 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
1715 t |= VT_UNSIGNED;
1716 std_op:
1717 /* XXX: currently, some unsigned operations are explicit, so
1718 we modify them here */
1719 if (t & VT_UNSIGNED) {
1720 if (op == TOK_SAR)
1721 op = TOK_SHR;
1722 else if (op == '/')
1723 op = TOK_UDIV;
1724 else if (op == '%')
1725 op = TOK_UMOD;
1726 else if (op == TOK_LT)
1727 op = TOK_ULT;
1728 else if (op == TOK_GT)
1729 op = TOK_UGT;
1730 else if (op == TOK_LE)
1731 op = TOK_ULE;
1732 else if (op == TOK_GE)
1733 op = TOK_UGE;
1735 vswap();
1736 type1.t = t;
1737 gen_cast(&type1);
1738 vswap();
1739 /* special case for shifts and long long: we keep the shift as
1740 an integer */
1741 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
1742 type1.t = VT_INT;
1743 gen_cast(&type1);
1744 if (is_float(t))
1745 gen_opif(op);
1746 else
1747 gen_opic(op);
1748 if (op >= TOK_ULT && op <= TOK_GT) {
1749 /* relationnal op: the result is an int */
1750 vtop->type.t = VT_INT;
1751 } else {
1752 vtop->type.t = t;
1757 #ifndef TCC_TARGET_ARM
1758 /* generic itof for unsigned long long case */
1759 static void gen_cvt_itof1(int t)
1761 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
1762 (VT_LLONG | VT_UNSIGNED)) {
1764 if (t == VT_FLOAT)
1765 vpush_global_sym(&func_old_type, TOK___floatundisf);
1766 #if LDOUBLE_SIZE != 8
1767 else if (t == VT_LDOUBLE)
1768 vpush_global_sym(&func_old_type, TOK___floatundixf);
1769 #endif
1770 else
1771 vpush_global_sym(&func_old_type, TOK___floatundidf);
1772 vrott(2);
1773 gfunc_call(1);
1774 vpushi(0);
1775 vtop->r = reg_fret(t);
1776 } else {
1777 gen_cvt_itof(t);
1780 #endif
1782 /* generic ftoi for unsigned long long case */
1783 static void gen_cvt_ftoi1(int t)
1785 int st;
1787 if (t == (VT_LLONG | VT_UNSIGNED)) {
1788 /* not handled natively */
1789 st = vtop->type.t & VT_BTYPE;
1790 if (st == VT_FLOAT)
1791 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
1792 #if LDOUBLE_SIZE != 8
1793 else if (st == VT_LDOUBLE)
1794 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
1795 #endif
1796 else
1797 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
1798 vrott(2);
1799 gfunc_call(1);
1800 vpushi(0);
1801 vtop->r = REG_IRET;
1802 vtop->r2 = REG_LRET;
1803 } else {
1804 gen_cvt_ftoi(t);
1808 /* force char or short cast */
1809 static void force_charshort_cast(int t)
1811 int bits, dbt;
1812 dbt = t & VT_BTYPE;
1813 /* XXX: add optimization if lvalue : just change type and offset */
1814 if (dbt == VT_BYTE)
1815 bits = 8;
1816 else
1817 bits = 16;
1818 if (t & VT_UNSIGNED) {
1819 vpushi((1 << bits) - 1);
1820 gen_op('&');
1821 } else {
1822 bits = 32 - bits;
1823 vpushi(bits);
1824 gen_op(TOK_SHL);
1825 /* result must be signed or the SAR is converted to an SHL
1826 This was not the case when "t" was a signed short
1827 and the last value on the stack was an unsigned int */
1828 vtop->type.t &= ~VT_UNSIGNED;
1829 vpushi(bits);
1830 gen_op(TOK_SAR);
1834 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
1835 static void gen_cast(CType *type)
1837 int sbt, dbt, sf, df, c, p;
1839 /* special delayed cast for char/short */
1840 /* XXX: in some cases (multiple cascaded casts), it may still
1841 be incorrect */
1842 if (vtop->r & VT_MUSTCAST) {
1843 vtop->r &= ~VT_MUSTCAST;
1844 force_charshort_cast(vtop->type.t);
1847 /* bitfields first get cast to ints */
1848 if (vtop->type.t & VT_BITFIELD) {
1849 gv(RC_INT);
1852 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
1853 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
1855 if (sbt != dbt) {
1856 sf = is_float(sbt);
1857 df = is_float(dbt);
1858 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
1859 p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
1860 if (c) {
1861 /* constant case: we can do it now */
1862 /* XXX: in ISOC, cannot do it if error in convert */
1863 if (sbt == VT_FLOAT)
1864 vtop->c.ld = vtop->c.f;
1865 else if (sbt == VT_DOUBLE)
1866 vtop->c.ld = vtop->c.d;
1868 if (df) {
1869 if ((sbt & VT_BTYPE) == VT_LLONG) {
1870 if (sbt & VT_UNSIGNED)
1871 vtop->c.ld = vtop->c.ull;
1872 else
1873 vtop->c.ld = vtop->c.ll;
1874 } else if(!sf) {
1875 if (sbt & VT_UNSIGNED)
1876 vtop->c.ld = vtop->c.ui;
1877 else
1878 vtop->c.ld = vtop->c.i;
1881 if (dbt == VT_FLOAT)
1882 vtop->c.f = (float)vtop->c.ld;
1883 else if (dbt == VT_DOUBLE)
1884 vtop->c.d = (double)vtop->c.ld;
1885 } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
1886 vtop->c.ull = (unsigned long long)vtop->c.ld;
1887 } else if (sf && dbt == VT_BOOL) {
1888 vtop->c.i = (vtop->c.ld != 0);
1889 } else {
1890 if(sf)
1891 vtop->c.ll = (long long)vtop->c.ld;
1892 else if (sbt == (VT_LLONG|VT_UNSIGNED))
1893 vtop->c.ll = vtop->c.ull;
1894 else if (sbt & VT_UNSIGNED)
1895 vtop->c.ll = vtop->c.ui;
1896 #ifdef TCC_TARGET_X86_64
1897 else if (sbt == VT_PTR)
1899 #endif
1900 else if (sbt != VT_LLONG)
1901 vtop->c.ll = vtop->c.i;
1903 if (dbt == (VT_LLONG|VT_UNSIGNED))
1904 vtop->c.ull = vtop->c.ll;
1905 else if (dbt == VT_BOOL)
1906 vtop->c.i = (vtop->c.ll != 0);
1907 else if (dbt != VT_LLONG) {
1908 int s = 0;
1909 if ((dbt & VT_BTYPE) == VT_BYTE)
1910 s = 24;
1911 else if ((dbt & VT_BTYPE) == VT_SHORT)
1912 s = 16;
1914 if(dbt & VT_UNSIGNED)
1915 vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
1916 else
1917 vtop->c.i = ((int)vtop->c.ll << s) >> s;
1920 } else if (p && dbt == VT_BOOL) {
1921 vtop->r = VT_CONST;
1922 vtop->c.i = 1;
1923 } else if (!nocode_wanted) {
1924 /* non constant case: generate code */
1925 if (sf && df) {
1926 /* convert from fp to fp */
1927 gen_cvt_ftof(dbt);
1928 } else if (df) {
1929 /* convert int to fp */
1930 gen_cvt_itof1(dbt);
1931 } else if (sf) {
1932 /* convert fp to int */
1933 if (dbt == VT_BOOL) {
1934 vpushi(0);
1935 gen_op(TOK_NE);
1936 } else {
1937 /* we handle char/short/etc... with generic code */
1938 if (dbt != (VT_INT | VT_UNSIGNED) &&
1939 dbt != (VT_LLONG | VT_UNSIGNED) &&
1940 dbt != VT_LLONG)
1941 dbt = VT_INT;
1942 gen_cvt_ftoi1(dbt);
1943 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
1944 /* additional cast for char/short... */
1945 vtop->type.t = dbt;
1946 gen_cast(type);
1949 #ifndef TCC_TARGET_X86_64
1950 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
1951 if ((sbt & VT_BTYPE) != VT_LLONG) {
1952 /* scalar to long long */
1953 /* machine independent conversion */
1954 gv(RC_INT);
1955 /* generate high word */
1956 if (sbt == (VT_INT | VT_UNSIGNED)) {
1957 vpushi(0);
1958 gv(RC_INT);
1959 } else {
1960 if (sbt == VT_PTR) {
1961 /* cast from pointer to int before we apply
1962 shift operation, which pointers don't support*/
1963 gen_cast(&int_type);
1965 gv_dup();
1966 vpushi(31);
1967 gen_op(TOK_SAR);
1969 /* patch second register */
1970 vtop[-1].r2 = vtop->r;
1971 vpop();
1973 #else
1974 } else if ((dbt & VT_BTYPE) == VT_LLONG ||
1975 (dbt & VT_BTYPE) == VT_PTR ||
1976 (dbt & VT_BTYPE) == VT_FUNC) {
1977 if ((sbt & VT_BTYPE) != VT_LLONG &&
1978 (sbt & VT_BTYPE) != VT_PTR &&
1979 (sbt & VT_BTYPE) != VT_FUNC) {
1980 /* need to convert from 32bit to 64bit */
1981 int r = gv(RC_INT);
1982 if (sbt != (VT_INT | VT_UNSIGNED)) {
1983 /* x86_64 specific: movslq */
1984 o(0x6348);
1985 o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
1988 #endif
1989 } else if (dbt == VT_BOOL) {
1990 /* scalar to bool */
1991 vpushi(0);
1992 gen_op(TOK_NE);
1993 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
1994 (dbt & VT_BTYPE) == VT_SHORT) {
1995 if (sbt == VT_PTR) {
1996 vtop->type.t = VT_INT;
1997 tcc_warning("nonportable conversion from pointer to char/short");
1999 force_charshort_cast(dbt);
2000 } else if ((dbt & VT_BTYPE) == VT_INT) {
2001 /* scalar to int */
2002 if (sbt == VT_LLONG) {
2003 /* from long long: just take low order word */
2004 lexpand();
2005 vpop();
2007 /* if lvalue and single word type, nothing to do because
2008 the lvalue already contains the real type size (see
2009 VT_LVAL_xxx constants) */
2012 } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
2013 /* if we are casting between pointer types,
2014 we must update the VT_LVAL_xxx size */
2015 vtop->r = (vtop->r & ~VT_LVAL_TYPE)
2016 | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
2018 vtop->type = *type;
2021 /* return type size as known at compile time. Put alignment at 'a' */
2022 ST_FUNC int type_size(CType *type, int *a)
2024 Sym *s;
2025 int bt;
2027 bt = type->t & VT_BTYPE;
2028 if (bt == VT_STRUCT) {
2029 /* struct/union */
2030 s = type->ref;
2031 *a = s->r;
2032 return s->c;
2033 } else if (bt == VT_PTR) {
2034 if (type->t & VT_ARRAY) {
2035 int ts;
2037 s = type->ref;
2038 ts = type_size(&s->type, a);
2040 if (ts < 0 && s->c < 0)
2041 ts = -ts;
2043 return ts * s->c;
2044 } else {
2045 *a = PTR_SIZE;
2046 return PTR_SIZE;
2048 } else if (bt == VT_LDOUBLE) {
2049 *a = LDOUBLE_ALIGN;
2050 return LDOUBLE_SIZE;
2051 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
2052 #ifdef TCC_TARGET_I386
2053 #ifdef TCC_TARGET_PE
2054 *a = 8;
2055 #else
2056 *a = 4;
2057 #endif
2058 #elif defined(TCC_TARGET_ARM)
2059 #ifdef TCC_ARM_EABI
2060 *a = 8;
2061 #else
2062 *a = 4;
2063 #endif
2064 #else
2065 *a = 8;
2066 #endif
2067 return 8;
2068 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
2069 *a = 4;
2070 return 4;
2071 } else if (bt == VT_SHORT) {
2072 *a = 2;
2073 return 2;
2074 } else {
2075 /* char, void, function, _Bool */
2076 *a = 1;
2077 return 1;
2081 /* push type size as known at runtime time on top of value stack. Put
2082 alignment at 'a' */
2083 ST_FUNC void vla_runtime_type_size(CType *type, int *a)
2085 if (type->t & VT_VLA) {
2086 vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
2087 } else {
2088 vpushi(type_size(type, a));
2092 /* return the pointed type of t */
2093 static inline CType *pointed_type(CType *type)
2095 return &type->ref->type;
2098 /* modify type so that its it is a pointer to type. */
2099 ST_FUNC void mk_pointer(CType *type)
2101 Sym *s;
2102 s = sym_push(SYM_FIELD, type, 0, -1);
2103 type->t = VT_PTR | (type->t & ~VT_TYPE);
2104 type->ref = s;
2107 /* compare function types. OLD functions match any new functions */
2108 static int is_compatible_func(CType *type1, CType *type2)
2110 Sym *s1, *s2;
2112 s1 = type1->ref;
2113 s2 = type2->ref;
2114 if (!is_compatible_types(&s1->type, &s2->type))
2115 return 0;
2116 /* check func_call */
2117 if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
2118 return 0;
2119 /* XXX: not complete */
2120 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
2121 return 1;
2122 if (s1->c != s2->c)
2123 return 0;
2124 while (s1 != NULL) {
2125 if (s2 == NULL)
2126 return 0;
2127 if (!is_compatible_parameter_types(&s1->type, &s2->type))
2128 return 0;
2129 s1 = s1->next;
2130 s2 = s2->next;
2132 if (s2)
2133 return 0;
2134 return 1;
2137 /* return true if type1 and type2 are the same. If unqualified is
2138 true, qualifiers on the types are ignored.
2140 - enums are not checked as gcc __builtin_types_compatible_p ()
2142 static int compare_types(CType *type1, CType *type2, int unqualified)
2144 int bt1, t1, t2;
2146 t1 = type1->t & VT_TYPE;
2147 t2 = type2->t & VT_TYPE;
2148 if (unqualified) {
2149 /* strip qualifiers before comparing */
2150 t1 &= ~(VT_CONSTANT | VT_VOLATILE);
2151 t2 &= ~(VT_CONSTANT | VT_VOLATILE);
2153 /* XXX: bitfields ? */
2154 if (t1 != t2)
2155 return 0;
2156 /* test more complicated cases */
2157 bt1 = t1 & VT_BTYPE;
2158 if (bt1 == VT_PTR) {
2159 type1 = pointed_type(type1);
2160 type2 = pointed_type(type2);
2161 return is_compatible_types(type1, type2);
2162 } else if (bt1 == VT_STRUCT) {
2163 return (type1->ref == type2->ref);
2164 } else if (bt1 == VT_FUNC) {
2165 return is_compatible_func(type1, type2);
2166 } else {
2167 return 1;
2171 /* return true if type1 and type2 are exactly the same (including
2172 qualifiers).
2174 static int is_compatible_types(CType *type1, CType *type2)
2176 return compare_types(type1,type2,0);
2179 /* return true if type1 and type2 are the same (ignoring qualifiers).
2181 static int is_compatible_parameter_types(CType *type1, CType *type2)
2183 return compare_types(type1,type2,1);
2186 /* print a type. If 'varstr' is not NULL, then the variable is also
2187 printed in the type */
2188 /* XXX: union */
2189 /* XXX: add array and function pointers */
2190 static void type_to_str(char *buf, int buf_size,
2191 CType *type, const char *varstr)
2193 int bt, v, t;
2194 Sym *s, *sa;
2195 char buf1[256];
2196 const char *tstr;
2198 t = type->t & VT_TYPE;
2199 bt = t & VT_BTYPE;
2200 buf[0] = '\0';
2201 if (t & VT_CONSTANT)
2202 pstrcat(buf, buf_size, "const ");
2203 if (t & VT_VOLATILE)
2204 pstrcat(buf, buf_size, "volatile ");
2205 if (t & VT_UNSIGNED)
2206 pstrcat(buf, buf_size, "unsigned ");
2207 switch(bt) {
2208 case VT_VOID:
2209 tstr = "void";
2210 goto add_tstr;
2211 case VT_BOOL:
2212 tstr = "_Bool";
2213 goto add_tstr;
2214 case VT_BYTE:
2215 tstr = "char";
2216 goto add_tstr;
2217 case VT_SHORT:
2218 tstr = "short";
2219 goto add_tstr;
2220 case VT_INT:
2221 tstr = "int";
2222 goto add_tstr;
2223 case VT_LONG:
2224 tstr = "long";
2225 goto add_tstr;
2226 case VT_LLONG:
2227 tstr = "long long";
2228 goto add_tstr;
2229 case VT_FLOAT:
2230 tstr = "float";
2231 goto add_tstr;
2232 case VT_DOUBLE:
2233 tstr = "double";
2234 goto add_tstr;
2235 case VT_LDOUBLE:
2236 tstr = "long double";
2237 add_tstr:
2238 pstrcat(buf, buf_size, tstr);
2239 break;
2240 case VT_ENUM:
2241 case VT_STRUCT:
2242 if (bt == VT_STRUCT)
2243 tstr = "struct ";
2244 else
2245 tstr = "enum ";
2246 pstrcat(buf, buf_size, tstr);
2247 v = type->ref->v & ~SYM_STRUCT;
2248 if (v >= SYM_FIRST_ANOM)
2249 pstrcat(buf, buf_size, "<anonymous>");
2250 else
2251 pstrcat(buf, buf_size, get_tok_str(v, NULL));
2252 break;
2253 case VT_FUNC:
2254 s = type->ref;
2255 type_to_str(buf, buf_size, &s->type, varstr);
2256 pstrcat(buf, buf_size, "(");
2257 sa = s->next;
2258 while (sa != NULL) {
2259 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
2260 pstrcat(buf, buf_size, buf1);
2261 sa = sa->next;
2262 if (sa)
2263 pstrcat(buf, buf_size, ", ");
2265 pstrcat(buf, buf_size, ")");
2266 goto no_var;
2267 case VT_PTR:
2268 s = type->ref;
2269 pstrcpy(buf1, sizeof(buf1), "*");
2270 if (varstr)
2271 pstrcat(buf1, sizeof(buf1), varstr);
2272 type_to_str(buf, buf_size, &s->type, buf1);
2273 goto no_var;
2275 if (varstr) {
2276 pstrcat(buf, buf_size, " ");
2277 pstrcat(buf, buf_size, varstr);
2279 no_var: ;
2282 /* verify type compatibility to store vtop in 'dt' type, and generate
2283 casts if needed. */
2284 static void gen_assign_cast(CType *dt)
2286 CType *st, *type1, *type2, tmp_type1, tmp_type2;
2287 char buf1[256], buf2[256];
2288 int dbt, sbt;
2290 st = &vtop->type; /* source type */
2291 dbt = dt->t & VT_BTYPE;
2292 sbt = st->t & VT_BTYPE;
2293 if (sbt == VT_VOID)
2294 tcc_error("Cannot assign void value");
2295 if (dt->t & VT_CONSTANT)
2296 tcc_warning("assignment of read-only location");
2297 switch(dbt) {
2298 case VT_PTR:
2299 /* special cases for pointers */
2300 /* '0' can also be a pointer */
2301 if (is_null_pointer(vtop))
2302 goto type_ok;
2303 /* accept implicit pointer to integer cast with warning */
2304 if (is_integer_btype(sbt)) {
2305 tcc_warning("assignment makes pointer from integer without a cast");
2306 goto type_ok;
2308 type1 = pointed_type(dt);
2309 /* a function is implicitely a function pointer */
2310 if (sbt == VT_FUNC) {
2311 if ((type1->t & VT_BTYPE) != VT_VOID &&
2312 !is_compatible_types(pointed_type(dt), st))
2313 tcc_warning("assignment from incompatible pointer type");
2314 goto type_ok;
2316 if (sbt != VT_PTR)
2317 goto error;
2318 type2 = pointed_type(st);
2319 if ((type1->t & VT_BTYPE) == VT_VOID ||
2320 (type2->t & VT_BTYPE) == VT_VOID) {
2321 /* void * can match anything */
2322 } else {
2323 /* exact type match, except for unsigned */
2324 tmp_type1 = *type1;
2325 tmp_type2 = *type2;
2326 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2327 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
2328 if (!is_compatible_types(&tmp_type1, &tmp_type2))
2329 tcc_warning("assignment from incompatible pointer type");
2331 /* check const and volatile */
2332 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
2333 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
2334 tcc_warning("assignment discards qualifiers from pointer target type");
2335 break;
2336 case VT_BYTE:
2337 case VT_SHORT:
2338 case VT_INT:
2339 case VT_LLONG:
2340 if (sbt == VT_PTR || sbt == VT_FUNC) {
2341 tcc_warning("assignment makes integer from pointer without a cast");
2343 /* XXX: more tests */
2344 break;
2345 case VT_STRUCT:
2346 tmp_type1 = *dt;
2347 tmp_type2 = *st;
2348 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2349 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2350 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2351 error:
2352 type_to_str(buf1, sizeof(buf1), st, NULL);
2353 type_to_str(buf2, sizeof(buf2), dt, NULL);
2354 tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
2356 break;
2358 type_ok:
2359 gen_cast(dt);
2362 /* store vtop in lvalue pushed on stack */
2363 ST_FUNC void vstore(void)
2365 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
2367 ft = vtop[-1].type.t;
2368 sbt = vtop->type.t & VT_BTYPE;
2369 dbt = ft & VT_BTYPE;
2370 if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
2371 (sbt == VT_INT && dbt == VT_SHORT))
2372 && !(vtop->type.t & VT_BITFIELD)) {
2373 /* optimize char/short casts */
2374 delayed_cast = VT_MUSTCAST;
2375 vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
2376 /* XXX: factorize */
2377 if (ft & VT_CONSTANT)
2378 tcc_warning("assignment of read-only location");
2379 } else {
2380 delayed_cast = 0;
2381 if (!(ft & VT_BITFIELD))
2382 gen_assign_cast(&vtop[-1].type);
2385 if (sbt == VT_STRUCT) {
2386 /* if structure, only generate pointer */
2387 /* structure assignment : generate memcpy */
2388 /* XXX: optimize if small size */
2389 if (!nocode_wanted) {
2390 size = type_size(&vtop->type, &align);
2392 /* destination */
2393 vswap();
2394 vtop->type.t = VT_PTR;
2395 gaddrof();
2397 /* address of memcpy() */
2398 #ifdef TCC_ARM_EABI
2399 if(!(align & 7))
2400 vpush_global_sym(&func_old_type, TOK_memcpy8);
2401 else if(!(align & 3))
2402 vpush_global_sym(&func_old_type, TOK_memcpy4);
2403 else
2404 #endif
2405 vpush_global_sym(&func_old_type, TOK_memcpy);
2407 vswap();
2408 /* source */
2409 vpushv(vtop - 2);
2410 vtop->type.t = VT_PTR;
2411 gaddrof();
2412 /* type size */
2413 vpushi(size);
2414 gfunc_call(3);
2415 } else {
2416 vswap();
2417 vpop();
2419 /* leave source on stack */
2420 } else if (ft & VT_BITFIELD) {
2421 /* bitfield store handling */
2422 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
2423 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
2424 /* remove bit field info to avoid loops */
2425 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
2427 /* duplicate source into other register */
2428 gv_dup();
2429 vswap();
2430 vrott(3);
2432 if((ft & VT_BTYPE) == VT_BOOL) {
2433 gen_cast(&vtop[-1].type);
2434 vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
2437 /* duplicate destination */
2438 vdup();
2439 vtop[-1] = vtop[-2];
2441 /* mask and shift source */
2442 if((ft & VT_BTYPE) != VT_BOOL) {
2443 if((ft & VT_BTYPE) == VT_LLONG) {
2444 vpushll((1ULL << bit_size) - 1ULL);
2445 } else {
2446 vpushi((1 << bit_size) - 1);
2448 gen_op('&');
2450 vpushi(bit_pos);
2451 gen_op(TOK_SHL);
2452 /* load destination, mask and or with source */
2453 vswap();
2454 if((ft & VT_BTYPE) == VT_LLONG) {
2455 vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
2456 } else {
2457 vpushi(~(((1 << bit_size) - 1) << bit_pos));
2459 gen_op('&');
2460 gen_op('|');
2461 /* store result */
2462 vstore();
2464 /* pop off shifted source from "duplicate source..." above */
2465 vpop();
2467 } else {
2468 #ifdef CONFIG_TCC_BCHECK
2469 /* bound check case */
2470 if (vtop[-1].r & VT_MUSTBOUND) {
2471 vswap();
2472 gbound();
2473 vswap();
2475 #endif
2476 if (!nocode_wanted) {
2477 rc = RC_INT;
2478 if (is_float(ft)) {
2479 rc = RC_FLOAT;
2480 #ifdef TCC_TARGET_X86_64
2481 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
2482 rc = RC_ST0;
2484 #endif
2486 r = gv(rc); /* generate value */
2487 /* if lvalue was saved on stack, must read it */
2488 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
2489 SValue sv;
2490 t = get_reg(RC_INT);
2491 #ifdef TCC_TARGET_X86_64
2492 sv.type.t = VT_PTR;
2493 #else
2494 sv.type.t = VT_INT;
2495 #endif
2496 sv.r = VT_LOCAL | VT_LVAL;
2497 sv.c.ul = vtop[-1].c.ul;
2498 load(t, &sv);
2499 vtop[-1].r = t | VT_LVAL;
2501 store(r, vtop - 1);
2502 #ifndef TCC_TARGET_X86_64
2503 /* two word case handling : store second register at word + 4 */
2504 if ((ft & VT_BTYPE) == VT_LLONG) {
2505 vswap();
2506 /* convert to int to increment easily */
2507 vtop->type.t = VT_INT;
2508 gaddrof();
2509 vpushi(4);
2510 gen_op('+');
2511 vtop->r |= VT_LVAL;
2512 vswap();
2513 /* XXX: it works because r2 is spilled last ! */
2514 store(vtop->r2, vtop - 1);
2516 #endif
2518 vswap();
2519 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
2520 vtop->r |= delayed_cast;
2524 /* post defines POST/PRE add. c is the token ++ or -- */
2525 ST_FUNC void inc(int post, int c)
2527 test_lvalue();
2528 vdup(); /* save lvalue */
2529 if (post) {
2530 gv_dup(); /* duplicate value */
2531 vrotb(3);
2532 vrotb(3);
2534 /* add constant */
2535 vpushi(c - TOK_MID);
2536 gen_op('+');
2537 vstore(); /* store value */
2538 if (post)
2539 vpop(); /* if post op, return saved value */
2542 /* Parse GNUC __attribute__ extension. Currently, the following
2543 extensions are recognized:
2544 - aligned(n) : set data/function alignment.
2545 - packed : force data alignment to 1
2546 - section(x) : generate data/code in this section.
2547 - unused : currently ignored, but may be used someday.
2548 - regparm(n) : pass function parameters in registers (i386 only)
2550 static void parse_attribute(AttributeDef *ad)
2552 int t, n;
2554 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
2555 next();
2556 skip('(');
2557 skip('(');
2558 while (tok != ')') {
2559 if (tok < TOK_IDENT)
2560 expect("attribute name");
2561 t = tok;
2562 next();
2563 switch(t) {
2564 case TOK_SECTION1:
2565 case TOK_SECTION2:
2566 skip('(');
2567 if (tok != TOK_STR)
2568 expect("section name");
2569 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
2570 next();
2571 skip(')');
2572 break;
2573 case TOK_ALIAS1:
2574 case TOK_ALIAS2:
2575 skip('(');
2576 if (tok != TOK_STR)
2577 expect("alias(\"target\")");
2578 ad->alias_target = /* save string as token, for later */
2579 tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
2580 next();
2581 skip(')');
2582 break;
2583 case TOK_ALIGNED1:
2584 case TOK_ALIGNED2:
2585 if (tok == '(') {
2586 next();
2587 n = expr_const();
2588 if (n <= 0 || (n & (n - 1)) != 0)
2589 tcc_error("alignment must be a positive power of two");
2590 skip(')');
2591 } else {
2592 n = MAX_ALIGN;
2594 ad->aligned = n;
2595 break;
2596 case TOK_PACKED1:
2597 case TOK_PACKED2:
2598 ad->packed = 1;
2599 break;
2600 case TOK_WEAK1:
2601 case TOK_WEAK2:
2602 ad->weak = 1;
2603 break;
2604 case TOK_UNUSED1:
2605 case TOK_UNUSED2:
2606 /* currently, no need to handle it because tcc does not
2607 track unused objects */
2608 break;
2609 case TOK_NORETURN1:
2610 case TOK_NORETURN2:
2611 /* currently, no need to handle it because tcc does not
2612 track unused objects */
2613 break;
2614 case TOK_CDECL1:
2615 case TOK_CDECL2:
2616 case TOK_CDECL3:
2617 ad->func_call = FUNC_CDECL;
2618 break;
2619 case TOK_STDCALL1:
2620 case TOK_STDCALL2:
2621 case TOK_STDCALL3:
2622 ad->func_call = FUNC_STDCALL;
2623 break;
2624 #ifdef TCC_TARGET_I386
2625 case TOK_REGPARM1:
2626 case TOK_REGPARM2:
2627 skip('(');
2628 n = expr_const();
2629 if (n > 3)
2630 n = 3;
2631 else if (n < 0)
2632 n = 0;
2633 if (n > 0)
2634 ad->func_call = FUNC_FASTCALL1 + n - 1;
2635 skip(')');
2636 break;
2637 case TOK_FASTCALL1:
2638 case TOK_FASTCALL2:
2639 case TOK_FASTCALL3:
2640 ad->func_call = FUNC_FASTCALLW;
2641 break;
2642 #endif
2643 case TOK_MODE:
2644 skip('(');
2645 switch(tok) {
2646 case TOK_MODE_DI:
2647 ad->mode = VT_LLONG + 1;
2648 break;
2649 case TOK_MODE_HI:
2650 ad->mode = VT_SHORT + 1;
2651 break;
2652 case TOK_MODE_SI:
2653 ad->mode = VT_INT + 1;
2654 break;
2655 default:
2656 tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
2657 break;
2659 next();
2660 skip(')');
2661 break;
2662 case TOK_DLLEXPORT:
2663 ad->func_export = 1;
2664 break;
2665 case TOK_DLLIMPORT:
2666 ad->func_import = 1;
2667 break;
2668 default:
2669 if (tcc_state->warn_unsupported)
2670 tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
2671 /* skip parameters */
2672 if (tok == '(') {
2673 int parenthesis = 0;
2674 do {
2675 if (tok == '(')
2676 parenthesis++;
2677 else if (tok == ')')
2678 parenthesis--;
2679 next();
2680 } while (parenthesis && tok != -1);
2682 break;
2684 if (tok != ',')
2685 break;
2686 next();
2688 skip(')');
2689 skip(')');
2693 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
2694 static void struct_decl(CType *type, int u)
2696 int a, v, size, align, maxalign, c, offset;
2697 int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
2698 Sym *s, *ss, *ass, **ps;
2699 AttributeDef ad;
2700 CType type1, btype;
2702 a = tok; /* save decl type */
2703 next();
2704 if (tok != '{') {
2705 v = tok;
2706 next();
2707 /* struct already defined ? return it */
2708 if (v < TOK_IDENT)
2709 expect("struct/union/enum name");
2710 s = struct_find(v);
2711 if (s) {
2712 if (s->type.t != a)
2713 tcc_error("invalid type");
2714 goto do_decl;
2716 } else {
2717 v = anon_sym++;
2719 type1.t = a;
2720 /* we put an undefined size for struct/union */
2721 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
2722 s->r = 0; /* default alignment is zero as gcc */
2723 /* put struct/union/enum name in type */
2724 do_decl:
2725 type->t = u;
2726 type->ref = s;
2728 if (tok == '{') {
2729 next();
2730 if (s->c != -1)
2731 tcc_error("struct/union/enum already defined");
2732 /* cannot be empty */
2733 c = 0;
2734 /* non empty enums are not allowed */
2735 if (a == TOK_ENUM) {
2736 for(;;) {
2737 v = tok;
2738 if (v < TOK_UIDENT)
2739 expect("identifier");
2740 next();
2741 if (tok == '=') {
2742 next();
2743 c = expr_const();
2745 /* enum symbols have static storage */
2746 ss = sym_push(v, &int_type, VT_CONST, c);
2747 ss->type.t |= VT_STATIC;
2748 if (tok != ',')
2749 break;
2750 next();
2751 c++;
2752 /* NOTE: we accept a trailing comma */
2753 if (tok == '}')
2754 break;
2756 skip('}');
2757 } else {
2758 maxalign = 1;
2759 ps = &s->next;
2760 prevbt = VT_INT;
2761 bit_pos = 0;
2762 offset = 0;
2763 while (tok != '}') {
2764 parse_btype(&btype, &ad);
2765 while (1) {
2766 bit_size = -1;
2767 v = 0;
2768 type1 = btype;
2769 if (tok != ':') {
2770 type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
2771 if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
2772 expect("identifier");
2773 if ((type1.t & VT_BTYPE) == VT_FUNC ||
2774 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
2775 tcc_error("invalid type for '%s'",
2776 get_tok_str(v, NULL));
2778 if (tok == ':') {
2779 next();
2780 bit_size = expr_const();
2781 /* XXX: handle v = 0 case for messages */
2782 if (bit_size < 0)
2783 tcc_error("negative width in bit-field '%s'",
2784 get_tok_str(v, NULL));
2785 if (v && bit_size == 0)
2786 tcc_error("zero width for bit-field '%s'",
2787 get_tok_str(v, NULL));
2789 size = type_size(&type1, &align);
2790 if (ad.aligned) {
2791 if (align < ad.aligned)
2792 align = ad.aligned;
2793 } else if (ad.packed) {
2794 align = 1;
2795 } else if (*tcc_state->pack_stack_ptr) {
2796 if (align > *tcc_state->pack_stack_ptr)
2797 align = *tcc_state->pack_stack_ptr;
2799 lbit_pos = 0;
2800 if (bit_size >= 0) {
2801 bt = type1.t & VT_BTYPE;
2802 if (bt != VT_INT &&
2803 bt != VT_BYTE &&
2804 bt != VT_SHORT &&
2805 bt != VT_BOOL &&
2806 bt != VT_ENUM &&
2807 bt != VT_LLONG)
2808 tcc_error("bitfields must have scalar type");
2809 bsize = size * 8;
2810 if (bit_size > bsize) {
2811 tcc_error("width of '%s' exceeds its type",
2812 get_tok_str(v, NULL));
2813 } else if (bit_size == bsize) {
2814 /* no need for bit fields */
2815 bit_pos = 0;
2816 } else if (bit_size == 0) {
2817 /* XXX: what to do if only padding in a
2818 structure ? */
2819 /* zero size: means to pad */
2820 bit_pos = 0;
2821 } else {
2822 /* we do not have enough room ?
2823 did the type change?
2824 is it a union? */
2825 if ((bit_pos + bit_size) > bsize ||
2826 bt != prevbt || a == TOK_UNION)
2827 bit_pos = 0;
2828 lbit_pos = bit_pos;
2829 /* XXX: handle LSB first */
2830 type1.t |= VT_BITFIELD |
2831 (bit_pos << VT_STRUCT_SHIFT) |
2832 (bit_size << (VT_STRUCT_SHIFT + 6));
2833 bit_pos += bit_size;
2835 prevbt = bt;
2836 } else {
2837 bit_pos = 0;
2839 if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
2840 /* add new memory data only if starting
2841 bit field */
2842 if (lbit_pos == 0) {
2843 if (a == TOK_STRUCT) {
2844 c = (c + align - 1) & -align;
2845 offset = c;
2846 if (size > 0)
2847 c += size;
2848 } else {
2849 offset = 0;
2850 if (size > c)
2851 c = size;
2853 if (align > maxalign)
2854 maxalign = align;
2856 #if 0
2857 printf("add field %s offset=%d",
2858 get_tok_str(v, NULL), offset);
2859 if (type1.t & VT_BITFIELD) {
2860 printf(" pos=%d size=%d",
2861 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
2862 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
2864 printf("\n");
2865 #endif
2867 if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
2868 ass = type1.ref;
2869 while ((ass = ass->next) != NULL) {
2870 ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
2871 *ps = ss;
2872 ps = &ss->next;
2874 } else if (v) {
2875 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
2876 *ps = ss;
2877 ps = &ss->next;
2879 if (tok == ';' || tok == TOK_EOF)
2880 break;
2881 skip(',');
2883 skip(';');
2885 skip('}');
2886 /* store size and alignment */
2887 s->c = (c + maxalign - 1) & -maxalign;
2888 s->r = maxalign;
2893 /* return 0 if no type declaration. otherwise, return the basic type
2894 and skip it.
2896 static int parse_btype(CType *type, AttributeDef *ad)
2898 int t, u, type_found, typespec_found, typedef_found;
2899 Sym *s;
2900 CType type1;
2902 memset(ad, 0, sizeof(AttributeDef));
2903 type_found = 0;
2904 typespec_found = 0;
2905 typedef_found = 0;
2906 t = 0;
2907 while(1) {
2908 switch(tok) {
2909 case TOK_EXTENSION:
2910 /* currently, we really ignore extension */
2911 next();
2912 continue;
2914 /* basic types */
2915 case TOK_CHAR:
2916 u = VT_BYTE;
2917 basic_type:
2918 next();
2919 basic_type1:
2920 if ((t & VT_BTYPE) != 0)
2921 tcc_error("too many basic types");
2922 t |= u;
2923 typespec_found = 1;
2924 break;
2925 case TOK_VOID:
2926 u = VT_VOID;
2927 goto basic_type;
2928 case TOK_SHORT:
2929 u = VT_SHORT;
2930 goto basic_type;
2931 case TOK_INT:
2932 next();
2933 typespec_found = 1;
2934 break;
2935 case TOK_LONG:
2936 next();
2937 if ((t & VT_BTYPE) == VT_DOUBLE) {
2938 #ifndef TCC_TARGET_PE
2939 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2940 #endif
2941 } else if ((t & VT_BTYPE) == VT_LONG) {
2942 t = (t & ~VT_BTYPE) | VT_LLONG;
2943 } else {
2944 u = VT_LONG;
2945 goto basic_type1;
2947 break;
2948 case TOK_BOOL:
2949 u = VT_BOOL;
2950 goto basic_type;
2951 case TOK_FLOAT:
2952 u = VT_FLOAT;
2953 goto basic_type;
2954 case TOK_DOUBLE:
2955 next();
2956 if ((t & VT_BTYPE) == VT_LONG) {
2957 #ifdef TCC_TARGET_PE
2958 t = (t & ~VT_BTYPE) | VT_DOUBLE;
2959 #else
2960 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
2961 #endif
2962 } else {
2963 u = VT_DOUBLE;
2964 goto basic_type1;
2966 break;
2967 case TOK_ENUM:
2968 struct_decl(&type1, VT_ENUM);
2969 basic_type2:
2970 u = type1.t;
2971 type->ref = type1.ref;
2972 goto basic_type1;
2973 case TOK_STRUCT:
2974 case TOK_UNION:
2975 struct_decl(&type1, VT_STRUCT);
2976 goto basic_type2;
2978 /* type modifiers */
2979 case TOK_CONST1:
2980 case TOK_CONST2:
2981 case TOK_CONST3:
2982 t |= VT_CONSTANT;
2983 next();
2984 break;
2985 case TOK_VOLATILE1:
2986 case TOK_VOLATILE2:
2987 case TOK_VOLATILE3:
2988 t |= VT_VOLATILE;
2989 next();
2990 break;
2991 case TOK_SIGNED1:
2992 case TOK_SIGNED2:
2993 case TOK_SIGNED3:
2994 typespec_found = 1;
2995 t |= VT_SIGNED;
2996 next();
2997 break;
2998 case TOK_REGISTER:
2999 case TOK_AUTO:
3000 case TOK_RESTRICT1:
3001 case TOK_RESTRICT2:
3002 case TOK_RESTRICT3:
3003 next();
3004 break;
3005 case TOK_UNSIGNED:
3006 t |= VT_UNSIGNED;
3007 next();
3008 typespec_found = 1;
3009 break;
3011 /* storage */
3012 case TOK_EXTERN:
3013 t |= VT_EXTERN;
3014 next();
3015 break;
3016 case TOK_STATIC:
3017 t |= VT_STATIC;
3018 next();
3019 break;
3020 case TOK_TYPEDEF:
3021 t |= VT_TYPEDEF;
3022 next();
3023 break;
3024 case TOK_INLINE1:
3025 case TOK_INLINE2:
3026 case TOK_INLINE3:
3027 t |= VT_INLINE;
3028 next();
3029 break;
3031 /* GNUC attribute */
3032 case TOK_ATTRIBUTE1:
3033 case TOK_ATTRIBUTE2:
3034 parse_attribute(ad);
3035 if (ad->mode) {
3036 u = ad->mode -1;
3037 t = (t & ~VT_BTYPE) | u;
3039 break;
3040 /* GNUC typeof */
3041 case TOK_TYPEOF1:
3042 case TOK_TYPEOF2:
3043 case TOK_TYPEOF3:
3044 next();
3045 parse_expr_type(&type1);
3046 /* remove all storage modifiers except typedef */
3047 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
3048 goto basic_type2;
3049 default:
3050 if (typespec_found || typedef_found)
3051 goto the_end;
3052 s = sym_find(tok);
3053 if (!s || !(s->type.t & VT_TYPEDEF))
3054 goto the_end;
3055 typedef_found = 1;
3056 t |= (s->type.t & ~VT_TYPEDEF);
3057 type->ref = s->type.ref;
3058 if (s->r) {
3059 /* get attributes from typedef */
3060 if (0 == ad->aligned)
3061 ad->aligned = FUNC_ALIGN(s->r);
3062 if (0 == ad->func_call)
3063 ad->func_call = FUNC_CALL(s->r);
3064 ad->packed |= FUNC_PACKED(s->r);
3066 next();
3067 typespec_found = 1;
3068 break;
3070 type_found = 1;
3072 the_end:
3073 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
3074 tcc_error("signed and unsigned modifier");
3075 if (tcc_state->char_is_unsigned) {
3076 if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
3077 t |= VT_UNSIGNED;
3079 t &= ~VT_SIGNED;
3081 /* long is never used as type */
3082 if ((t & VT_BTYPE) == VT_LONG)
3083 #if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
3084 t = (t & ~VT_BTYPE) | VT_INT;
3085 #else
3086 t = (t & ~VT_BTYPE) | VT_LLONG;
3087 #endif
3088 type->t = t;
3089 return type_found;
3092 /* convert a function parameter type (array to pointer and function to
3093 function pointer) */
3094 static inline void convert_parameter_type(CType *pt)
3096 /* remove const and volatile qualifiers (XXX: const could be used
3097 to indicate a const function parameter */
3098 pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
3099 /* array must be transformed to pointer according to ANSI C */
3100 pt->t &= ~VT_ARRAY;
3101 if ((pt->t & VT_BTYPE) == VT_FUNC) {
3102 mk_pointer(pt);
3106 ST_FUNC void parse_asm_str(CString *astr)
3108 skip('(');
3109 /* read the string */
3110 if (tok != TOK_STR)
3111 expect("string constant");
3112 cstr_new(astr);
3113 while (tok == TOK_STR) {
3114 /* XXX: add \0 handling too ? */
3115 cstr_cat(astr, tokc.cstr->data);
3116 next();
3118 cstr_ccat(astr, '\0');
3121 /* Parse an asm label and return the label
3122 * Don't forget to free the CString in the caller! */
3123 static void asm_label_instr(CString *astr)
3125 next();
3126 parse_asm_str(astr);
3127 skip(')');
3128 #ifdef ASM_DEBUG
3129 printf("asm_alias: \"%s\"\n", (char *)astr->data);
3130 #endif
3133 static void post_type(CType *type, AttributeDef *ad)
3135 int n, l, t1, arg_size, align;
3136 Sym **plast, *s, *first;
3137 AttributeDef ad1;
3138 CType pt;
3140 if (tok == '(') {
3141 /* function declaration */
3142 next();
3143 l = 0;
3144 first = NULL;
3145 plast = &first;
3146 arg_size = 0;
3147 if (tok != ')') {
3148 for(;;) {
3149 /* read param name and compute offset */
3150 if (l != FUNC_OLD) {
3151 if (!parse_btype(&pt, &ad1)) {
3152 if (l) {
3153 tcc_error("invalid type");
3154 } else {
3155 l = FUNC_OLD;
3156 goto old_proto;
3159 l = FUNC_NEW;
3160 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
3161 break;
3162 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
3163 if ((pt.t & VT_BTYPE) == VT_VOID)
3164 tcc_error("parameter declared as void");
3165 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
3166 } else {
3167 old_proto:
3168 n = tok;
3169 if (n < TOK_UIDENT)
3170 expect("identifier");
3171 pt.t = VT_INT;
3172 next();
3174 convert_parameter_type(&pt);
3175 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
3176 *plast = s;
3177 plast = &s->next;
3178 if (tok == ')')
3179 break;
3180 skip(',');
3181 if (l == FUNC_NEW && tok == TOK_DOTS) {
3182 l = FUNC_ELLIPSIS;
3183 next();
3184 break;
3188 /* if no parameters, then old type prototype */
3189 if (l == 0)
3190 l = FUNC_OLD;
3191 skip(')');
3192 /* NOTE: const is ignored in returned type as it has a special
3193 meaning in gcc / C++ */
3194 type->t &= ~VT_CONSTANT;
3195 /* some ancient pre-K&R C allows a function to return an array
3196 and the array brackets to be put after the arguments, such
3197 that "int c()[]" means something like "int[] c()" */
3198 if (tok == '[') {
3199 next();
3200 skip(']'); /* only handle simple "[]" */
3201 type->t |= VT_PTR;
3203 /* we push a anonymous symbol which will contain the function prototype */
3204 ad->func_args = arg_size;
3205 s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
3206 s->next = first;
3207 type->t = VT_FUNC;
3208 type->ref = s;
3209 } else if (tok == '[') {
3210 /* array definition */
3211 next();
3212 if (tok == TOK_RESTRICT1)
3213 next();
3214 n = -1;
3215 t1 = 0;
3216 if (tok != ']') {
3217 if (!local_stack || nocode_wanted)
3218 vpushi(expr_const());
3219 else gexpr();
3220 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3221 n = vtop->c.i;
3222 if (n < 0)
3223 tcc_error("invalid array size");
3224 } else {
3225 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
3226 tcc_error("size of variable length array should be an integer");
3227 t1 = VT_VLA;
3230 skip(']');
3231 /* parse next post type */
3232 post_type(type, ad);
3233 t1 |= type->t & VT_VLA;
3235 if (t1 & VT_VLA) {
3236 loc -= type_size(&int_type, &align);
3237 loc &= -align;
3238 n = loc;
3240 vla_runtime_type_size(type, &align);
3241 gen_op('*');
3242 vset(&int_type, VT_LOCAL|VT_LVAL, loc);
3243 vswap();
3244 vstore();
3246 if (n != -1)
3247 vpop();
3249 /* we push an anonymous symbol which will contain the array
3250 element type */
3251 s = sym_push(SYM_FIELD, type, 0, n);
3252 type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
3253 type->ref = s;
3257 /* Parse a type declaration (except basic type), and return the type
3258 in 'type'. 'td' is a bitmask indicating which kind of type decl is
3259 expected. 'type' should contain the basic type. 'ad' is the
3260 attribute definition of the basic type. It can be modified by
3261 type_decl().
3263 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
3265 Sym *s;
3266 CType type1, *type2;
3267 int qualifiers, storage;
3269 while (tok == '*') {
3270 qualifiers = 0;
3271 redo:
3272 next();
3273 switch(tok) {
3274 case TOK_CONST1:
3275 case TOK_CONST2:
3276 case TOK_CONST3:
3277 qualifiers |= VT_CONSTANT;
3278 goto redo;
3279 case TOK_VOLATILE1:
3280 case TOK_VOLATILE2:
3281 case TOK_VOLATILE3:
3282 qualifiers |= VT_VOLATILE;
3283 goto redo;
3284 case TOK_RESTRICT1:
3285 case TOK_RESTRICT2:
3286 case TOK_RESTRICT3:
3287 goto redo;
3289 mk_pointer(type);
3290 type->t |= qualifiers;
3293 /* XXX: clarify attribute handling */
3294 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3295 parse_attribute(ad);
3297 /* recursive type */
3298 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3299 type1.t = 0; /* XXX: same as int */
3300 if (tok == '(') {
3301 next();
3302 /* XXX: this is not correct to modify 'ad' at this point, but
3303 the syntax is not clear */
3304 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3305 parse_attribute(ad);
3306 type_decl(&type1, ad, v, td);
3307 skip(')');
3308 } else {
3309 /* type identifier */
3310 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
3311 *v = tok;
3312 next();
3313 } else {
3314 if (!(td & TYPE_ABSTRACT))
3315 expect("identifier");
3316 *v = 0;
3319 storage = type->t & VT_STORAGE;
3320 type->t &= ~VT_STORAGE;
3321 if (storage & VT_STATIC) {
3322 int saved_nocode_wanted = nocode_wanted;
3323 nocode_wanted = 1;
3324 post_type(type, ad);
3325 nocode_wanted = saved_nocode_wanted;
3326 } else
3327 post_type(type, ad);
3328 type->t |= storage;
3329 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3330 parse_attribute(ad);
3332 if (!type1.t)
3333 return;
3334 /* append type at the end of type1 */
3335 type2 = &type1;
3336 for(;;) {
3337 s = type2->ref;
3338 type2 = &s->type;
3339 if (!type2->t) {
3340 *type2 = *type;
3341 break;
3344 *type = type1;
3347 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
3348 ST_FUNC int lvalue_type(int t)
3350 int bt, r;
3351 r = VT_LVAL;
3352 bt = t & VT_BTYPE;
3353 if (bt == VT_BYTE || bt == VT_BOOL)
3354 r |= VT_LVAL_BYTE;
3355 else if (bt == VT_SHORT)
3356 r |= VT_LVAL_SHORT;
3357 else
3358 return r;
3359 if (t & VT_UNSIGNED)
3360 r |= VT_LVAL_UNSIGNED;
3361 return r;
3364 /* indirection with full error checking and bound check */
3365 ST_FUNC void indir(void)
3367 if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
3368 if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
3369 return;
3370 expect("pointer");
3372 if ((vtop->r & VT_LVAL) && !nocode_wanted)
3373 gv(RC_INT);
3374 vtop->type = *pointed_type(&vtop->type);
3375 /* Arrays and functions are never lvalues */
3376 if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
3377 && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
3378 vtop->r |= lvalue_type(vtop->type.t);
3379 /* if bound checking, the referenced pointer must be checked */
3380 #ifdef CONFIG_TCC_BCHECK
3381 if (tcc_state->do_bounds_check)
3382 vtop->r |= VT_MUSTBOUND;
3383 #endif
3387 /* pass a parameter to a function and do type checking and casting */
3388 static void gfunc_param_typed(Sym *func, Sym *arg)
3390 int func_type;
3391 CType type;
3393 func_type = func->c;
3394 if (func_type == FUNC_OLD ||
3395 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
3396 /* default casting : only need to convert float to double */
3397 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
3398 type.t = VT_DOUBLE;
3399 gen_cast(&type);
3401 } else if (arg == NULL) {
3402 tcc_error("too many arguments to function");
3403 } else {
3404 type = arg->type;
3405 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
3406 gen_assign_cast(&type);
3410 /* parse an expression of the form '(type)' or '(expr)' and return its
3411 type */
3412 static void parse_expr_type(CType *type)
3414 int n;
3415 AttributeDef ad;
3417 skip('(');
3418 if (parse_btype(type, &ad)) {
3419 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3420 } else {
3421 expr_type(type);
3423 skip(')');
3426 static void parse_type(CType *type)
3428 AttributeDef ad;
3429 int n;
3431 if (!parse_btype(type, &ad)) {
3432 expect("type");
3434 type_decl(type, &ad, &n, TYPE_ABSTRACT);
3437 static void vpush_tokc(int t)
3439 CType type;
3440 type.t = t;
3441 type.ref = 0;
3442 vsetc(&type, VT_CONST, &tokc);
3445 ST_FUNC void unary(void)
3447 int n, t, align, size, r, sizeof_caller;
3448 CType type;
3449 Sym *s;
3450 AttributeDef ad;
3451 static int in_sizeof = 0;
3453 sizeof_caller = in_sizeof;
3454 in_sizeof = 0;
3455 /* XXX: GCC 2.95.3 does not generate a table although it should be
3456 better here */
3457 tok_next:
3458 switch(tok) {
3459 case TOK_EXTENSION:
3460 next();
3461 goto tok_next;
3462 case TOK_CINT:
3463 case TOK_CCHAR:
3464 case TOK_LCHAR:
3465 vpushi(tokc.i);
3466 next();
3467 break;
3468 case TOK_CUINT:
3469 vpush_tokc(VT_INT | VT_UNSIGNED);
3470 next();
3471 break;
3472 case TOK_CLLONG:
3473 vpush_tokc(VT_LLONG);
3474 next();
3475 break;
3476 case TOK_CULLONG:
3477 vpush_tokc(VT_LLONG | VT_UNSIGNED);
3478 next();
3479 break;
3480 case TOK_CFLOAT:
3481 vpush_tokc(VT_FLOAT);
3482 next();
3483 break;
3484 case TOK_CDOUBLE:
3485 vpush_tokc(VT_DOUBLE);
3486 next();
3487 break;
3488 case TOK_CLDOUBLE:
3489 vpush_tokc(VT_LDOUBLE);
3490 next();
3491 break;
3492 case TOK___FUNCTION__:
3493 if (!gnu_ext)
3494 goto tok_identifier;
3495 /* fall thru */
3496 case TOK___FUNC__:
3498 void *ptr;
3499 int len;
3500 /* special function name identifier */
3501 len = strlen(funcname) + 1;
3502 /* generate char[len] type */
3503 type.t = VT_BYTE;
3504 mk_pointer(&type);
3505 type.t |= VT_ARRAY;
3506 type.ref->c = len;
3507 vpush_ref(&type, data_section, data_section->data_offset, len);
3508 ptr = section_ptr_add(data_section, len);
3509 memcpy(ptr, funcname, len);
3510 next();
3512 break;
3513 case TOK_LSTR:
3514 #ifdef TCC_TARGET_PE
3515 t = VT_SHORT | VT_UNSIGNED;
3516 #else
3517 t = VT_INT;
3518 #endif
3519 goto str_init;
3520 case TOK_STR:
3521 /* string parsing */
3522 t = VT_BYTE;
3523 str_init:
3524 if (tcc_state->warn_write_strings)
3525 t |= VT_CONSTANT;
3526 type.t = t;
3527 mk_pointer(&type);
3528 type.t |= VT_ARRAY;
3529 memset(&ad, 0, sizeof(AttributeDef));
3530 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
3531 break;
3532 case '(':
3533 next();
3534 /* cast ? */
3535 if (parse_btype(&type, &ad)) {
3536 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
3537 skip(')');
3538 /* check ISOC99 compound literal */
3539 if (tok == '{') {
3540 /* data is allocated locally by default */
3541 if (global_expr)
3542 r = VT_CONST;
3543 else
3544 r = VT_LOCAL;
3545 /* all except arrays are lvalues */
3546 if (!(type.t & VT_ARRAY))
3547 r |= lvalue_type(type.t);
3548 memset(&ad, 0, sizeof(AttributeDef));
3549 decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
3550 } else {
3551 if (sizeof_caller) {
3552 vpush(&type);
3553 return;
3555 unary();
3556 gen_cast(&type);
3558 } else if (tok == '{') {
3559 /* save all registers */
3560 save_regs(0);
3561 /* statement expression : we do not accept break/continue
3562 inside as GCC does */
3563 block(NULL, NULL, NULL, NULL, 0, 1);
3564 skip(')');
3565 } else {
3566 gexpr();
3567 skip(')');
3569 break;
3570 case '*':
3571 next();
3572 unary();
3573 indir();
3574 break;
3575 case '&':
3576 next();
3577 unary();
3578 /* functions names must be treated as function pointers,
3579 except for unary '&' and sizeof. Since we consider that
3580 functions are not lvalues, we only have to handle it
3581 there and in function calls. */
3582 /* arrays can also be used although they are not lvalues */
3583 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
3584 !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
3585 test_lvalue();
3586 mk_pointer(&vtop->type);
3587 gaddrof();
3588 break;
3589 case '!':
3590 next();
3591 unary();
3592 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3593 CType boolean;
3594 boolean.t = VT_BOOL;
3595 gen_cast(&boolean);
3596 vtop->c.i = !vtop->c.i;
3597 } else if ((vtop->r & VT_VALMASK) == VT_CMP)
3598 vtop->c.i = vtop->c.i ^ 1;
3599 else {
3600 save_regs(1);
3601 vseti(VT_JMP, gtst(1, 0));
3603 break;
3604 case '~':
3605 next();
3606 unary();
3607 vpushi(-1);
3608 gen_op('^');
3609 break;
3610 case '+':
3611 next();
3612 /* in order to force cast, we add zero */
3613 unary();
3614 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
3615 tcc_error("pointer not accepted for unary plus");
3616 vpushi(0);
3617 gen_op('+');
3618 break;
3619 case TOK_SIZEOF:
3620 case TOK_ALIGNOF1:
3621 case TOK_ALIGNOF2:
3622 t = tok;
3623 next();
3624 in_sizeof++;
3625 unary_type(&type); // Perform a in_sizeof = 0;
3626 size = type_size(&type, &align);
3627 if (t == TOK_SIZEOF) {
3628 if (!(type.t & VT_VLA)) {
3629 if (size < 0)
3630 tcc_error("sizeof applied to an incomplete type");
3631 vpushs(size);
3632 } else {
3633 vla_runtime_type_size(&type, &align);
3635 } else {
3636 vpushs(align);
3638 vtop->type.t |= VT_UNSIGNED;
3639 break;
3641 case TOK_builtin_types_compatible_p:
3643 CType type1, type2;
3644 next();
3645 skip('(');
3646 parse_type(&type1);
3647 skip(',');
3648 parse_type(&type2);
3649 skip(')');
3650 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
3651 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
3652 vpushi(is_compatible_types(&type1, &type2));
3654 break;
3655 case TOK_builtin_constant_p:
3657 int saved_nocode_wanted, res;
3658 next();
3659 skip('(');
3660 saved_nocode_wanted = nocode_wanted;
3661 nocode_wanted = 1;
3662 gexpr();
3663 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3664 vpop();
3665 nocode_wanted = saved_nocode_wanted;
3666 skip(')');
3667 vpushi(res);
3669 break;
3670 case TOK_builtin_frame_address:
3672 int level;
3673 CType type;
3674 next();
3675 skip('(');
3676 if (tok != TOK_CINT || tokc.i < 0) {
3677 tcc_error("__builtin_frame_address only takes positive integers");
3679 level = tokc.i;
3680 next();
3681 skip(')');
3682 type.t = VT_VOID;
3683 mk_pointer(&type);
3684 vset(&type, VT_LOCAL, 0); /* local frame */
3685 while (level--) {
3686 mk_pointer(&vtop->type);
3687 indir(); /* -> parent frame */
3690 break;
3691 #ifdef TCC_TARGET_X86_64
3692 case TOK_builtin_va_arg_types:
3694 /* This definition must be synced with stdarg.h */
3695 enum __va_arg_type {
3696 __va_gen_reg, __va_float_reg, __va_stack
3698 CType type;
3699 int bt;
3700 next();
3701 skip('(');
3702 parse_type(&type);
3703 skip(')');
3704 bt = type.t & VT_BTYPE;
3705 if (bt == VT_STRUCT || bt == VT_LDOUBLE) {
3706 vpushi(__va_stack);
3707 } else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
3708 vpushi(__va_float_reg);
3709 } else {
3710 vpushi(__va_gen_reg);
3713 break;
3714 #endif
3715 case TOK_INC:
3716 case TOK_DEC:
3717 t = tok;
3718 next();
3719 unary();
3720 inc(0, t);
3721 break;
3722 case '-':
3723 next();
3724 vpushi(0);
3725 unary();
3726 gen_op('-');
3727 break;
3728 case TOK_LAND:
3729 if (!gnu_ext)
3730 goto tok_identifier;
3731 next();
3732 /* allow to take the address of a label */
3733 if (tok < TOK_UIDENT)
3734 expect("label identifier");
3735 s = label_find(tok);
3736 if (!s) {
3737 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
3738 } else {
3739 if (s->r == LABEL_DECLARED)
3740 s->r = LABEL_FORWARD;
3742 if (!s->type.t) {
3743 s->type.t = VT_VOID;
3744 mk_pointer(&s->type);
3745 s->type.t |= VT_STATIC;
3747 vset(&s->type, VT_CONST | VT_SYM, 0);
3748 vtop->sym = s;
3749 next();
3750 break;
3752 // special qnan , snan and infinity values
3753 case TOK___NAN__:
3754 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
3755 next();
3756 break;
3757 case TOK___SNAN__:
3758 vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
3759 next();
3760 break;
3761 case TOK___INF__:
3762 vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
3763 next();
3764 break;
3766 default:
3767 tok_identifier:
3768 t = tok;
3769 next();
3770 if (t < TOK_UIDENT)
3771 expect("identifier");
3772 s = sym_find(t);
3773 if (!s) {
3774 if (tok != '(')
3775 tcc_error("'%s' undeclared", get_tok_str(t, NULL));
3776 /* for simple function calls, we tolerate undeclared
3777 external reference to int() function */
3778 if (tcc_state->warn_implicit_function_declaration)
3779 tcc_warning("implicit declaration of function '%s'",
3780 get_tok_str(t, NULL));
3781 s = external_global_sym(t, &func_old_type, 0);
3783 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
3784 (VT_STATIC | VT_INLINE | VT_FUNC)) {
3785 /* if referencing an inline function, then we generate a
3786 symbol to it if not already done. It will have the
3787 effect to generate code for it at the end of the
3788 compilation unit. Inline function as always
3789 generated in the text section. */
3790 if (!s->c)
3791 put_extern_sym(s, text_section, 0, 0);
3792 r = VT_SYM | VT_CONST;
3793 } else {
3794 r = s->r;
3796 vset(&s->type, r, s->c);
3797 /* if forward reference, we must point to s */
3798 if (vtop->r & VT_SYM) {
3799 vtop->sym = s;
3800 vtop->c.ul = 0;
3802 break;
3805 /* post operations */
3806 while (1) {
3807 if (tok == TOK_INC || tok == TOK_DEC) {
3808 inc(1, tok);
3809 next();
3810 } else if (tok == '.' || tok == TOK_ARROW) {
3811 int qualifiers;
3812 /* field */
3813 if (tok == TOK_ARROW)
3814 indir();
3815 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
3816 test_lvalue();
3817 gaddrof();
3818 next();
3819 /* expect pointer on structure */
3820 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
3821 expect("struct or union");
3822 s = vtop->type.ref;
3823 /* find field */
3824 tok |= SYM_FIELD;
3825 while ((s = s->next) != NULL) {
3826 if (s->v == tok)
3827 break;
3829 if (!s)
3830 tcc_error("field not found: %s", get_tok_str(tok & ~SYM_FIELD, NULL));
3831 /* add field offset to pointer */
3832 vtop->type = char_pointer_type; /* change type to 'char *' */
3833 vpushi(s->c);
3834 gen_op('+');
3835 /* change type to field type, and set to lvalue */
3836 vtop->type = s->type;
3837 vtop->type.t |= qualifiers;
3838 /* an array is never an lvalue */
3839 if (!(vtop->type.t & VT_ARRAY)) {
3840 vtop->r |= lvalue_type(vtop->type.t);
3841 #ifdef CONFIG_TCC_BCHECK
3842 /* if bound checking, the referenced pointer must be checked */
3843 if (tcc_state->do_bounds_check)
3844 vtop->r |= VT_MUSTBOUND;
3845 #endif
3847 next();
3848 } else if (tok == '[') {
3849 next();
3850 gexpr();
3851 gen_op('+');
3852 indir();
3853 skip(']');
3854 } else if (tok == '(') {
3855 SValue ret;
3856 Sym *sa;
3857 int nb_args;
3859 /* function call */
3860 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
3861 /* pointer test (no array accepted) */
3862 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
3863 vtop->type = *pointed_type(&vtop->type);
3864 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
3865 goto error_func;
3866 } else {
3867 error_func:
3868 expect("function pointer");
3870 } else {
3871 vtop->r &= ~VT_LVAL; /* no lvalue */
3873 /* get return type */
3874 s = vtop->type.ref;
3875 next();
3876 sa = s->next; /* first parameter */
3877 nb_args = 0;
3878 ret.r2 = VT_CONST;
3879 /* compute first implicit argument if a structure is returned */
3880 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
3881 /* get some space for the returned structure */
3882 size = type_size(&s->type, &align);
3883 loc = (loc - size) & -align;
3884 ret.type = s->type;
3885 ret.r = VT_LOCAL | VT_LVAL;
3886 /* pass it as 'int' to avoid structure arg passing
3887 problems */
3888 vseti(VT_LOCAL, loc);
3889 ret.c = vtop->c;
3890 nb_args++;
3891 } else {
3892 ret.type = s->type;
3893 /* return in register */
3894 if (is_float(ret.type.t)) {
3895 ret.r = reg_fret(ret.type.t);
3896 } else {
3897 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
3898 ret.r2 = REG_LRET;
3899 ret.r = REG_IRET;
3901 ret.c.i = 0;
3903 if (tok != ')') {
3904 for(;;) {
3905 expr_eq();
3906 gfunc_param_typed(s, sa);
3907 nb_args++;
3908 if (sa)
3909 sa = sa->next;
3910 if (tok == ')')
3911 break;
3912 skip(',');
3915 if (sa)
3916 tcc_error("too few arguments to function");
3917 skip(')');
3918 if (!nocode_wanted) {
3919 gfunc_call(nb_args);
3920 } else {
3921 vtop -= (nb_args + 1);
3923 /* return value */
3924 vsetc(&ret.type, ret.r, &ret.c);
3925 vtop->r2 = ret.r2;
3926 } else {
3927 break;
3932 ST_FUNC void expr_prod(void)
3934 int t;
3936 unary();
3937 while (tok == '*' || tok == '/' || tok == '%') {
3938 t = tok;
3939 next();
3940 unary();
3941 gen_op(t);
3945 ST_FUNC void expr_sum(void)
3947 int t;
3949 expr_prod();
3950 while (tok == '+' || tok == '-') {
3951 t = tok;
3952 next();
3953 expr_prod();
3954 gen_op(t);
3958 static void expr_shift(void)
3960 int t;
3962 expr_sum();
3963 while (tok == TOK_SHL || tok == TOK_SAR) {
3964 t = tok;
3965 next();
3966 expr_sum();
3967 gen_op(t);
3971 static void expr_cmp(void)
3973 int t;
3975 expr_shift();
3976 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
3977 tok == TOK_ULT || tok == TOK_UGE) {
3978 t = tok;
3979 next();
3980 expr_shift();
3981 gen_op(t);
3985 static void expr_cmpeq(void)
3987 int t;
3989 expr_cmp();
3990 while (tok == TOK_EQ || tok == TOK_NE) {
3991 t = tok;
3992 next();
3993 expr_cmp();
3994 gen_op(t);
3998 static void expr_and(void)
4000 expr_cmpeq();
4001 while (tok == '&') {
4002 next();
4003 expr_cmpeq();
4004 gen_op('&');
4008 static void expr_xor(void)
4010 expr_and();
4011 while (tok == '^') {
4012 next();
4013 expr_and();
4014 gen_op('^');
4018 static void expr_or(void)
4020 expr_xor();
4021 while (tok == '|') {
4022 next();
4023 expr_xor();
4024 gen_op('|');
4028 /* XXX: fix this mess */
4029 static void expr_land_const(void)
4031 expr_or();
4032 while (tok == TOK_LAND) {
4033 next();
4034 expr_or();
4035 gen_op(TOK_LAND);
4039 /* XXX: fix this mess */
4040 static void expr_lor_const(void)
4042 expr_land_const();
4043 while (tok == TOK_LOR) {
4044 next();
4045 expr_land_const();
4046 gen_op(TOK_LOR);
4050 /* only used if non constant */
4051 static void expr_land(void)
4053 int t;
4055 expr_or();
4056 if (tok == TOK_LAND) {
4057 t = 0;
4058 save_regs(1);
4059 for(;;) {
4060 t = gtst(1, t);
4061 if (tok != TOK_LAND) {
4062 vseti(VT_JMPI, t);
4063 break;
4065 next();
4066 expr_or();
4071 static void expr_lor(void)
4073 int t;
4075 expr_land();
4076 if (tok == TOK_LOR) {
4077 t = 0;
4078 save_regs(1);
4079 for(;;) {
4080 t = gtst(0, t);
4081 if (tok != TOK_LOR) {
4082 vseti(VT_JMP, t);
4083 break;
4085 next();
4086 expr_land();
4091 /* XXX: better constant handling */
4092 static void expr_cond(void)
4094 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
4095 SValue sv;
4096 CType type, type1, type2;
4098 if (const_wanted) {
4099 expr_lor_const();
4100 if (tok == '?') {
4101 CType boolean;
4102 int c;
4103 boolean.t = VT_BOOL;
4104 vdup();
4105 gen_cast(&boolean);
4106 c = vtop->c.i;
4107 vpop();
4108 next();
4109 if (tok != ':' || !gnu_ext) {
4110 vpop();
4111 gexpr();
4113 if (!c)
4114 vpop();
4115 skip(':');</