This fixes and activates the asm test that's part of tcctest.c also on x86-64, requiring a small fix for the 'm' constraint.
Unified · Split
| @@ -1366,7 +1366,11 @@ ST_FUNC void subst_asm_operand(CString *add_str, · 1365 unmodified lines | ||
| 1366 | 1366 | snprintf(buf, sizeof(buf), "%d", (int)sv->c.i); |
| 1367 | 1367 | cstr_cat(add_str, buf, -1); |
| 1368 | 1368 | } else if ((r & VT_VALMASK) == VT_LOCAL) { |
| 1369 | +#ifdef TCC_TARGET_X86_64 | |
| 1370 | + snprintf(buf, sizeof(buf), "%d(%%rbp)", (int)sv->c.i); | |
| 1371 | +#else | |
| 1369 | 1372 | snprintf(buf, sizeof(buf), "%d(%%ebp)", (int)sv->c.i); |
| 1373 | +#endif | |
| 1370 | 1374 | cstr_cat(add_str, buf, -1); |
| 1371 | 1375 | } else if (r & VT_LVAL) { |
| 1372 | 1376 | reg = r & VT_VALMASK; |
| @@ -2411,24 +2411,24 @@ void local_label_test(void) · 2410 unmodified lines | ||
| 2411 | 2411 | } |
| 2412 | 2412 | |
| 2413 | 2413 | /* inline assembler test */ |
| 2414 | −#ifdef __i386__ | |
| 2414 | +#if defined(__i386__) || defined(__x86_64__) | |
| 2415 | 2415 | |
| 2416 | 2416 | /* from linux kernel */ |
| 2417 | 2417 | static char * strncat1(char * dest,const char * src,size_t count) |
| 2418 | 2418 | { |
| 2419 | −int d0, d1, d2, d3; | |
| 2419 | +long d0, d1, d2, d3; | |
| 2420 | 2420 | __asm__ __volatile__( |
| 2421 | 2421 | "repne\n\t" |
| 2422 | 2422 | "scasb\n\t" |
| 2423 | − "decl %1\n\t" | |
| 2424 | − "movl %8,%3\n" | |
| 2425 | − "1:\tdecl %3\n\t" | |
| 2423 | + "dec %1\n\t" | |
| 2424 | + "mov %8,%3\n" | |
| 2425 | + "1:\tdec %3\n\t" | |
| 2426 | 2426 | "js 2f\n\t" |
| 2427 | 2427 | "lodsb\n\t" |
| 2428 | 2428 | "stosb\n\t" |
| 2429 | 2429 | "testb %%al,%%al\n\t" |
| 2430 | 2430 | "jne 1b\n" |
| 2431 | − "2:\txorl %2,%2\n\t" | |
| 2431 | + "2:\txor %2,%2\n\t" | |
| 2432 | 2432 | "stosb" |
| 2433 | 2433 | : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) |
| 2434 | 2434 | : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count) |
| @@ -2438,18 +2438,18 @@ return dest; · 3 unmodified lines | ||
| 2438 | 2438 | |
| 2439 | 2439 | static char * strncat2(char * dest,const char * src,size_t count) |
| 2440 | 2440 | { |
| 2441 | −int d0, d1, d2, d3; | |
| 2441 | +long d0, d1, d2, d3; | |
| 2442 | 2442 | __asm__ __volatile__( |
| 2443 | 2443 | "repne scasb\n\t" /* one-line repne prefix + string op */ |
| 2444 | − "decl %1\n\t" | |
| 2445 | − "movl %8,%3\n" | |
| 2446 | − "1:\tdecl %3\n\t" | |
| 2444 | + "dec %1\n\t" | |
| 2445 | + "mov %8,%3\n" | |
| 2446 | + "1:\tdec %3\n\t" | |
| 2447 | 2447 | "js 2f\n\t" |
| 2448 | 2448 | "lodsb\n\t" |
| 2449 | 2449 | "stosb\n\t" |
| 2450 | 2450 | "testb %%al,%%al\n\t" |
| 2451 | 2451 | "jne 1b\n" |
| 2452 | − "2:\txorl %2,%2\n\t" | |
| 2452 | + "2:\txor %2,%2\n\t" | |
| 2453 | 2453 | "stosb" |
| 2454 | 2454 | : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) |
| 2455 | 2455 | : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count) |
| @@ -2459,7 +2459,7 @@ return dest; · 3 unmodified lines | ||
| 2459 | 2459 | |
| 2460 | 2460 | static inline void * memcpy1(void * to, const void * from, size_t n) |
| 2461 | 2461 | { |
| 2462 | −int d0, d1, d2; | |
| 2462 | +long d0, d1, d2; | |
| 2463 | 2463 | __asm__ __volatile__( |
| 2464 | 2464 | "rep ; movsl\n\t" |
| 2465 | 2465 | "testb $2,%b4\n\t" |
| @@ -2477,7 +2477,7 @@ return (to); · 11 unmodified lines | ||
| 2477 | 2477 | |
| 2478 | 2478 | static inline void * memcpy2(void * to, const void * from, size_t n) |
| 2479 | 2479 | { |
| 2480 | −int d0, d1, d2; | |
| 2480 | +long d0, d1, d2; | |
| 2481 | 2481 | __asm__ __volatile__( |
| 2482 | 2482 | "rep movsl\n\t" /* one-line rep prefix + string op */ |
| 2483 | 2483 | "testb $2,%b4\n\t" |
| @@ -2516,14 +2516,28 @@ static __inline__ __const__ unsigned int swab32(unsigned int x) · 32 unmodified lines | ||
| 2516 | 2516 | static __inline__ unsigned long long mul64(unsigned int a, unsigned int b) |
| 2517 | 2517 | { |
| 2518 | 2518 | unsigned long long res; |
| 2519 | +#ifdef __x86_64__ | |
| 2520 | + /* Using the A constraint is wrong (it means rdx:rax, which is too large) | |
| 2521 | + but still test the 32bit->64bit mull. */ | |
| 2522 | + unsigned int resh, resl; | |
| 2523 | + __asm__("mull %2" : "=a" (resl), "=d" (resh) : "a" (a), "r" (b)); | |
| 2524 | + res = ((unsigned long long)resh << 32) | resl; | |
| 2525 | +#else | |
| 2519 | 2526 | __asm__("mull %2" : "=A" (res) : "a" (a), "r" (b)); |
| 2527 | +#endif | |
| 2520 | 2528 | return res; |
| 2521 | 2529 | } |
| 2522 | 2530 | |
| 2523 | 2531 | static __inline__ unsigned long long inc64(unsigned long long a) |
| 2524 | 2532 | { |
| 2525 | 2533 | unsigned long long res; |
| 2534 | +#ifdef __x86_64__ | |
| 2535 | + /* Using the A constraint is wrong, and increments are tested | |
| 2536 | + elsewere. */ | |
| 2537 | + res = a + 1; | |
| 2538 | +#else | |
| 2526 | 2539 | __asm__("addl $1, %%eax ; adcl $0, %%edx" : "=A" (res) : "A" (a)); |
| 2540 | +#endif | |
| 2527 | 2541 | return res; |
| 2528 | 2542 | } |
| 2529 | 2543 | |