Bad assumption make bad things happen: long d3; asm(..."1:\tdec %3\n\t" : ... "=&c" (d3) Which wants 'dec RDI' but did 'dec EDI' on _WIN64. Also: - tcctest.c: enable more asm tests for win64 - configure: show errors if any with 'gcc conftest.c' - tccgen.c: remove decl0(x, y, z)
Unified · Split
| @@ -357,7 +357,7 @@ fi · 356 unmodified lines | ||
| 357 | 357 | |
| 358 | 358 | if test -z "$cross_prefix" ; then |
| 359 | 359 | CONFTEST=./conftest$EXESUF |
| 360 | − if ! $cc -o $CONFTEST $source_path/conftest.c 2>/dev/null ; then | |
| 360 | + if ! $cc -o $CONFTEST $source_path/conftest.c ; then | |
| 361 | 361 | echo "configure: error: '$cc' failed to compile conftest.c." |
| 362 | 362 | else |
| 363 | 363 | cc_name="$($CONFTEST compiler)" |
| @@ -130,8 +130,7 @@ static void init_putv(init_params *p, CType *type, unsigned long c); · 129 unmodified lines | ||
| 130 | 130 | static void decl_initializer(init_params *p, CType *type, unsigned long c, int flags); |
| 131 | 131 | static void block(int is_expr); |
| 132 | 132 | static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope); |
| 133 | −static void decl(int l); | |
| 134 | −static int decl0(int l, int is_for_loop_init, Sym *); | |
| 133 | +static int decl(int l); | |
| 135 | 134 | static void expr_eq(void); |
| 136 | 135 | static void vpush_type_size(CType *type, int *a); |
| 137 | 136 | static int is_compatible_unqualified_types(CType *type1, CType *type2); |
| @@ -6881,7 +6880,7 @@ again: · 6743 unmodified lines | ||
| 6881 | 6880 | skip('('); |
| 6882 | 6881 | if (tok != ';') { |
| 6883 | 6882 | /* c99 for-loop init decl? */ |
| 6884 | − if (!decl0(VT_LOCAL, 1, NULL)) { | |
| 6883 | + if (!decl(VT_JMP)) { | |
| 6885 | 6884 | /* no, regular for-loop init expr */ |
| 6886 | 6885 | gexpr(); |
| 6887 | 6886 | vpop(); |
| @@ -7795,7 +7794,7 @@ static void decl_initializer(init_params *p, CType *type, unsigned long c, int f · 907 unmodified lines | ||
| 7795 | 7794 | is put in the value stack. If 'has_init' is 2, a special parsing |
| 7796 | 7795 | is done to handle string constants. */ |
| 7797 | 7796 | static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, |
| 7798 | − int has_init, int v, int scope) | |
| 7797 | + int has_init, int v, int global) | |
| 7799 | 7798 | { |
| 7800 | 7799 | int size, align, addr; |
| 7801 | 7800 | TokenString *init_str = NULL; |
| @@ -7932,7 +7931,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 130 unmodified lines | ||
| 7932 | 7931 | } |
| 7933 | 7932 | } else { |
| 7934 | 7933 | sym = NULL; |
| 7935 | − if (v && scope == VT_CONST) { | |
| 7934 | + if (v && global) { | |
| 7936 | 7935 | /* see if the symbol was already defined */ |
| 7937 | 7936 | sym = sym_find(v); |
| 7938 | 7937 | if (sym) { |
| @@ -8198,9 +8197,10 @@ static void free_inline_functions(TCCState *s) · 259 unmodified lines | ||
| 8198 | 8197 | dynarray_reset(&s->inline_fns, &s->nb_inline_fns); |
| 8199 | 8198 | } |
| 8200 | 8199 | |
| 8201 | −/* 'l' is VT_LOCAL or VT_CONST to define default storage type, or VT_CMP | |
| 8202 | − if parsing old style parameter decl list (and FUNC_SYM is set then) */ | |
| 8203 | −static int decl0(int l, int is_for_loop_init, Sym *func_sym) | |
| 8200 | +/* 'l' is VT_LOCAL or VT_CONST to define default storage type | |
| 8201 | + or VT_CMP if parsing old style parameter list | |
| 8202 | + or VT_JMP if parsing c99 for decl: for (int i = 0, ...) */ | |
| 8203 | +static int decl(int l) | |
| 8204 | 8204 | { |
| 8205 | 8205 | int v, has_init, r, oldint; |
| 8206 | 8206 | CType type, btype; |
| @@ -8236,7 +8236,7 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) · 29 unmodified lines | ||
| 8236 | 8236 | |
| 8237 | 8237 | oldint = 0; |
| 8238 | 8238 | if (!parse_btype(&btype, &adbase, l == VT_LOCAL)) { |
| 8239 | − if (is_for_loop_init) | |
| 8239 | + if (l == VT_JMP) | |
| 8240 | 8240 | return 0; |
| 8241 | 8241 | /* skip redundant ';' if not in old parameter decl scope */ |
| 8242 | 8242 | if (tok == ';' && l != VT_CMP) { |
| @@ -8288,13 +8288,15 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) · 45 unmodified lines | ||
| 8288 | 8288 | } |
| 8289 | 8289 | #endif |
| 8290 | 8290 | if ((type.t & VT_BTYPE) == VT_FUNC) { |
| 8291 | − if ((type.t & VT_STATIC) && (l == VT_LOCAL)) | |
| 8291 | + if ((type.t & VT_STATIC) && (l != VT_CONST)) | |
| 8292 | 8292 | tcc_error("function without file scope cannot be static"); |
| 8293 | 8293 | /* if old style function prototype, we accept a |
| 8294 | 8294 | declaration list */ |
| 8295 | 8295 | sym = type.ref; |
| 8296 | − if (sym->f.func_type == FUNC_OLD && l == VT_CONST) | |
| 8297 | − decl0(VT_CMP, 0, sym); | |
| 8296 | + if (sym->f.func_type == FUNC_OLD && l == VT_CONST) { | |
| 8297 | + func_vt = type; | |
| 8298 | + decl(VT_CMP); | |
| 8299 | + } | |
| 8298 | 8300 | #if defined TCC_TARGET_MACHO || defined TARGETOS_ANDROID |
| 8299 | 8301 | if (sym->f.func_alwinl |
| 8300 | 8302 | && ((type.t & (VT_EXTERN | VT_INLINE)) |
| @@ -8388,12 +8390,12 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) · 87 unmodified lines | ||
| 8388 | 8390 | } else { |
| 8389 | 8391 | if (l == VT_CMP) { |
| 8390 | 8392 | /* find parameter in function parameter list */ |
| 8391 | − for (sym = func_sym->next; sym; sym = sym->next) | |
| 8393 | + for (sym = func_vt.ref->next; sym; sym = sym->next) | |
| 8392 | 8394 | if ((sym->v & ~SYM_FIELD) == v) |
| 8393 | 8395 | goto found; |
| 8394 | 8396 | tcc_error("declaration for parameter '%s' but no such parameter", |
| 8395 | 8397 | get_tok_str(v, NULL)); |
| 8396 | −found: | |
| 8398 | + found: | |
| 8397 | 8399 | if (type.t & VT_STORAGE) /* 'register' is okay */ |
| 8398 | 8400 | tcc_error("storage class specified for '%s'", |
| 8399 | 8401 | get_tok_str(v, NULL)); |
| @@ -8460,20 +8462,20 @@ found: · 60 unmodified lines | ||
| 8460 | 8462 | esym->st_value, esym->st_size, 1); |
| 8461 | 8463 | } |
| 8462 | 8464 | } else { |
| 8463 | − if (type.t & VT_STATIC) | |
| 8465 | + if (l == VT_CONST || (type.t & VT_STATIC)) | |
| 8464 | 8466 | r |= VT_CONST; |
| 8465 | 8467 | else |
| 8466 | − r |= l; | |
| 8468 | + r |= VT_LOCAL; | |
| 8467 | 8469 | if (has_init) |
| 8468 | 8470 | next(); |
| 8469 | 8471 | else if (l == VT_CONST) |
| 8470 | 8472 | /* uninitialized global variables may be overridden */ |
| 8471 | 8473 | type.t |= VT_EXTERN; |
| 8472 | − decl_initializer_alloc(&type, &ad, r, has_init, v, l); | |
| 8474 | + decl_initializer_alloc(&type, &ad, r, has_init, v, l == VT_CONST); | |
| 8473 | 8475 | } |
| 8474 | 8476 | } |
| 8475 | 8477 | if (tok != ',') { |
| 8476 | − if (is_for_loop_init) | |
| 8478 | + if (l == VT_JMP) | |
| 8477 | 8479 | return 1; |
| 8478 | 8480 | skip(';'); |
| 8479 | 8481 | break; |
| @@ -8485,11 +8487,6 @@ found: · 5 unmodified lines | ||
| 8485 | 8487 | return 0; |
| 8486 | 8488 | } |
| 8487 | 8489 | |
| 8488 | −static void decl(int l) | |
| 8489 | −{ | |
| 8490 | − decl0(l, 0, NULL); | |
| 8491 | −} | |
| 8492 | − | |
| 8493 | 8490 | /* ------------------------------------------------------------------------- */ |
| 8494 | 8491 | #undef gjmp_addr |
| 8495 | 8492 | #undef gjmp |
| @@ -3251,10 +3251,12 @@ void local_label_test(void) · 3250 unmodified lines | ||
| 3251 | 3251 | /* inline assembler test */ |
| 3252 | 3252 | #if defined(__i386__) || defined(__x86_64__) |
| 3253 | 3253 | |
| 3254 | +typedef __SIZE_TYPE__ word; | |
| 3255 | + | |
| 3254 | 3256 | /* from linux kernel */ |
| 3255 | 3257 | static char * strncat1(char * dest,const char * src,size_t count) |
| 3256 | 3258 | { |
| 3257 | −long d0, d1, d2, d3; | |
| 3259 | +word d0, d1, d2, d3; | |
| 3258 | 3260 | __asm__ __volatile__( |
| 3259 | 3261 | "repne\n\t" |
| 3260 | 3262 | "scasb\n\t" |
| @@ -3276,7 +3278,7 @@ return dest; · 15 unmodified lines | ||
| 3276 | 3278 | |
| 3277 | 3279 | static char * strncat2(char * dest,const char * src,size_t count) |
| 3278 | 3280 | { |
| 3279 | −long d0, d1, d2, d3; | |
| 3281 | +word d0, d1, d2, d3; | |
| 3280 | 3282 | __asm__ __volatile__( |
| 3281 | 3283 | "repne scasb\n\t" /* one-line repne prefix + string op */ |
| 3282 | 3284 | "dec %1\n\t" |
| @@ -3297,7 +3299,7 @@ return dest; · 14 unmodified lines | ||
| 3297 | 3299 | |
| 3298 | 3300 | static inline void * memcpy1(void * to, const void * from, size_t n) |
| 3299 | 3301 | { |
| 3300 | −size_t d0, d1, d2; | |
| 3302 | +word d0, d1, d2; | |
| 3301 | 3303 | __asm__ __volatile__( |
| 3302 | 3304 | "rep ; movsl\n\t" |
| 3303 | 3305 | "testb $2,%b4\n\t" |
| @@ -3308,14 +3310,14 @@ __asm__ __volatile__( · 4 unmodified lines | ||
| 3308 | 3310 | "movsb\n" |
| 3309 | 3311 | "2:" |
| 3310 | 3312 | : "=&c" (d0), "=&D" (d1), "=&S" (d2) |
| 3311 | − :"0" (n/4), "q" (n),"1" ((size_t) to),"2" ((size_t) from) | |
| 3313 | + :"0" (n/4), "q" (n),"1" ((word) to),"2" ((word) from) | |
| 3312 | 3314 | : "memory"); |
| 3313 | 3315 | return (to); |
| 3314 | 3316 | } |
| 3315 | 3317 | |
| 3316 | 3318 | static inline void * memcpy2(void * to, const void * from, size_t n) |
| 3317 | 3319 | { |
| 3318 | −size_t d0, d1, d2; | |
| 3320 | +word d0, d1, d2; | |
| 3319 | 3321 | __asm__ __volatile__( |
| 3320 | 3322 | "rep movsl\n\t" /* one-line rep prefix + string op */ |
| 3321 | 3323 | "testb $2,%b4\n\t" |
| @@ -3326,7 +3328,7 @@ __asm__ __volatile__( · 4 unmodified lines | ||
| 3326 | 3328 | "movsb\n" |
| 3327 | 3329 | "2:" |
| 3328 | 3330 | : "=&c" (d0), "=&D" (d1), "=&S" (d2) |
| 3329 | − :"0" (n/4), "q" (n),"1" ((size_t) to),"2" ((size_t) from) | |
| 3331 | + :"0" (n/4), "q" (n),"1" ((word) to),"2" ((word) from) | |
| 3330 | 3332 | : "memory"); |
| 3331 | 3333 | return (to); |
| 3332 | 3334 | } |
| @@ -3395,12 +3397,12 @@ struct struct123 { · 62 unmodified lines | ||
| 3395 | 3397 | int b; |
| 3396 | 3398 | }; |
| 3397 | 3399 | struct struct1231 { |
| 3398 | − unsigned long addr; | |
| 3400 | + word addr; | |
| 3399 | 3401 | }; |
| 3400 | 3402 | |
| 3401 | −unsigned long mconstraint_test(struct struct1231 *r) | |
| 3403 | +word mconstraint_test(struct struct1231 *r) | |
| 3402 | 3404 | { |
| 3403 | − unsigned long ret; | |
| 3405 | + word ret; | |
| 3404 | 3406 | unsigned int a[2]; |
| 3405 | 3407 | a[0] = 0; |
| 3406 | 3408 | __asm__ volatile ("lea %2,%0; movl 4(%0),%k0; addl %2,%k0; movl $51,%2; movl $52,4%2; movl $63,%1" |
| @@ -3422,11 +3424,11 @@ int fls64(unsigned long long x) · 15 unmodified lines | ||
| 3422 | 3424 | |
| 3423 | 3425 | void other_constraints_test(void) |
| 3424 | 3426 | { |
| 3425 | − unsigned long ret; | |
| 3427 | + word ret; | |
| 3426 | 3428 | int var; |
| 3427 | −#if !defined(_WIN64) && CC_NAME != CC_clang | |
| 3429 | +#if CC_NAME != CC_clang | |
| 3428 | 3430 | __asm__ volatile ("mov %P1,%0" : "=r" (ret) : "p" (&var)); |
| 3429 | − printf ("oc1: %d\n", ret == (unsigned long)&var); | |
| 3431 | + printf ("oc1: %d\n", ret == (word)&var); | |
| 3430 | 3432 | #endif |
| 3431 | 3433 | } |
| 3432 | 3434 | |
| @@ -3510,6 +3512,7 @@ void asm_local_label_diff (void) · 77 unmodified lines | ||
| 3510 | 3512 | printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]); |
| 3511 | 3513 | } |
| 3512 | 3514 | #endif |
| 3515 | +#endif | |
| 3513 | 3516 | |
| 3514 | 3517 | /* This checks that static local variables are available from assembler. */ |
| 3515 | 3518 | void asm_local_statics (void) |
| @@ -3518,7 +3521,6 @@ void asm_local_statics (void) · 2 unmodified lines | ||
| 3518 | 3521 | asm("incl %0" : "+m" (localint)); |
| 3519 | 3522 | printf ("asm_local_statics: %d\n", localint); |
| 3520 | 3523 | } |
| 3521 | −#endif | |
| 3522 | 3524 | |
| 3523 | 3525 | static |
| 3524 | 3526 | unsigned int set; |
| @@ -3533,7 +3535,7 @@ void fancy_copy2 (unsigned *in, unsigned *out) · 8 unmodified lines | ||
| 3533 | 3535 | asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory"); |
| 3534 | 3536 | } |
| 3535 | 3537 | |
| 3536 | −#if defined __x86_64__ && !defined _WIN64 | |
| 3538 | +#if defined __x86_64__ | |
| 3537 | 3539 | void clobber_r12(void) |
| 3538 | 3540 | { |
| 3539 | 3541 | asm volatile("mov $1, %%r12" ::: "r12"); |
| @@ -3542,9 +3544,9 @@ void clobber_r12(void) · 2 unmodified lines | ||
| 3542 | 3544 | |
| 3543 | 3545 | void test_high_clobbers_really(void) |
| 3544 | 3546 | { |
| 3545 | −#if defined __x86_64__ && !defined _WIN64 | |
| 3546 | − register long val asm("r12"); | |
| 3547 | − long val2; | |
| 3547 | +#if defined __x86_64__ | |
| 3548 | + register word val asm("r12"); | |
| 3549 | + word val2; | |
| 3548 | 3550 | /* This tests if asm clobbers correctly save/restore callee saved |
| 3549 | 3551 | registers if they are clobbered and if it's the high 8 x86-64 |
| 3550 | 3552 | registers. This is fragile for GCC as the constraints do not |
| @@ -3558,8 +3560,8 @@ void test_high_clobbers_really(void) · 7 unmodified lines | ||
| 3558 | 3560 | |
| 3559 | 3561 | void test_high_clobbers(void) |
| 3560 | 3562 | { |
| 3561 | −#if defined __x86_64__ && !defined _WIN64 | |
| 3562 | − long x1, x2; | |
| 3563 | +#if defined __x86_64__ | |
| 3564 | + word x1, x2; | |
| 3563 | 3565 | asm volatile("mov %%r12,%0" :: "m" (x1)); /* save r12 */ |
| 3564 | 3566 | test_high_clobbers_really(); |
| 3565 | 3567 | asm volatile("mov %%r12,%0" :: "m" (x2)); /* new r12 */ |
| @@ -3625,7 +3627,7 @@ void trace_console(long len, long len2) · 59 unmodified lines | ||
| 3625 | 3627 | |
| 3626 | 3628 | void test_asm_dead_code(void) |
| 3627 | 3629 | { |
| 3628 | − long rdi; | |
| 3630 | + word rdi; | |
| 3629 | 3631 | /* Try to make sure that xdi contains a zero, and hence will |
| 3630 | 3632 | lead to a segfault if the next asm is evaluated without |
| 3631 | 3633 | arguments being set up. */ |
| @@ -3727,12 +3729,12 @@ void asm_test(void) · 95 unmodified lines | ||
| 3727 | 3729 | char buf[128]; |
| 3728 | 3730 | unsigned int val, val2; |
| 3729 | 3731 | struct struct123 s1; |
| 3730 | − struct struct1231 s2 = { (unsigned long)&s1 }; | |
| 3732 | + struct struct1231 s2 = { (word)&s1 }; | |
| 3731 | 3733 | /* Hide the outer base_func, but check later that the inline |
| 3732 | 3734 | asm block gets the outer one. */ |
| 3733 | 3735 | int base_func = 42; |
| 3734 | 3736 | void override_func3 (void); |
| 3735 | − unsigned long asmret; | |
| 3737 | + word asmret; | |
| 3736 | 3738 | #ifdef BOOL_ISOC99 |
| 3737 | 3739 | _Bool somebool; |
| 3738 | 3740 | #endif |
| @@ -3783,8 +3785,8 @@ void asm_test(void) · 44 unmodified lines | ||
| 3783 | 3785 | printf("asmstr: %s\n", get_asm_string()); |
| 3784 | 3786 | asm_local_label_diff(); |
| 3785 | 3787 | #endif |
| 3786 | − asm_local_statics(); | |
| 3787 | 3788 | #endif |
| 3789 | + asm_local_statics(); | |
| 3788 | 3790 | #ifndef __clang__ |
| 3789 | 3791 | /* clang can't deal with the type change */ |
| 3790 | 3792 | /* Check that we can also load structs of appropriate layout |