tccgen.c: remove VT_TLS in gen_cast libtcc.c: remove warning for gcc 16 i386-gen.c: fix gen_modrm for VT_LDOUBLE riscv64-gen.c: add fc to TLS address x86_64-gen.c: add TLS prefix in gen_opf tests2/144_tls.c/tests2/144_tls.expect: updated test case tests/tests2/Makefile skip TLS test for BSD
Unified · Split
| @@ -242,6 +242,8 @@ static void gen_modrm(int opc, int op_r2, int r, Sym *sym, int c) · 241 unmodified lines | |||
| 242 | int op_reg = REG_VALUE(op_r2) << 3; | 242 | int op_reg = REG_VALUE(op_r2) << 3; |
| 243 | 243 | ||
| 244 | if ((r & VT_SYM) && (sym->type.t & VT_TLS)) { | 244 | if ((r & VT_SYM) && (sym->type.t & VT_TLS)) { |
| 245 | if (opc == 0xdbc0d9) // VT_LDOUBLE | ||
| 246 | o(0xc0d9), opc = 0xdb; | ||
| 245 | o(0x65); /* gs segment prefix */ | 247 | o(0x65); /* gs segment prefix */ |
| 246 | o(opc); | 248 | o(opc); |
| 247 | oad(0x05 | op_reg, c); | 249 | oad(0x05 | op_reg, c); |
| @@ -194,7 +194,7 @@ ST_FUNC char *pstrncpy(char *out, size_t buf_size, const char *s, size_t num) · 193 unmodified lines | |||
| 194 | /* extract the basename of a file */ | 194 | /* extract the basename of a file */ |
| 195 | PUB_FUNC char *tcc_basename(const char *name) | 195 | PUB_FUNC char *tcc_basename(const char *name) |
| 196 | { | 196 | { |
| 197 | char *p = strchr(name, 0); | 197 | char *p = (char *)strchr(name, 0); |
| 198 | while (p > name && !IS_DIRSEP(p[-1])) | 198 | while (p > name && !IS_DIRSEP(p[-1])) |
| 199 | --p; | 199 | --p; |
| 200 | return p; | 200 | return p; |
| @@ -188,6 +188,8 @@ static int load_symofs(int r, SValue *sv, int forstore, int *new_fc) · 187 unmodified lines | |||
| 188 | greloca(cur_text_section, sv->sym, ind, | 188 | greloca(cur_text_section, sv->sym, ind, |
| 189 | R_RISCV_TPREL_LO12_I, 0); | 189 | R_RISCV_TPREL_LO12_I, 0); |
| 190 | EI(0x13, 0, rr, rr, 0); // addi RR, RR, 0 %tprel_lo(sym) | 190 | EI(0x13, 0, rr, rr, 0); // addi RR, RR, 0 %tprel_lo(sym) |
| 191 | if (fc) | ||
| 192 | EI(0x13, 0, rr, rr, fc); // addi RR, RR, fc | ||
| 191 | ER(0x33, 0, rr, rr, 4, 0); // add RR, RR, tp | 193 | ER(0x33, 0, rr, rr, 4, 0); // add RR, RR, tp |
| 192 | *new_fc = 0; | 194 | *new_fc = 0; |
| 193 | return rr; | 195 | return rr; |
| @@ -3487,7 +3487,7 @@ error: · 3486 unmodified lines | |||
| 3487 | } | 3487 | } |
| 3488 | done: | 3488 | done: |
| 3489 | vtop->type = *type; | 3489 | vtop->type = *type; |
| 3490 | vtop->type.t &= ~ ( VT_CONSTANT | VT_VOLATILE | VT_ARRAY ); | 3490 | vtop->type.t &= ~ ( VT_CONSTANT | VT_VOLATILE | VT_ARRAY | VT_TLS ); |
| 3491 | } | 3491 | } |
| 3492 | 3492 | ||
| 3493 | /* return type size as known at compile time. Put alignment at 'a' */ | 3493 | /* return type size as known at compile time. Put alignment at 'a' */ |
| @@ -1,50 +1,87 @@ | |||
| 1 | #include <stdio.h> | 1 | #include <stdio.h> |
| 2 | #include <pthread.h> | 2 | #include <pthread.h> |
| 3 | 3 | ||
| 4 | __thread int tls_init = 42; | 4 | #define CHECK(var,fmt,val) printf(fmt "\n",var); if (var != val) errors = 1 |
| 5 | |||
| 6 | typedef enum { tls_a, tls_b, tls_c } tls_enum_type; | ||
| 7 | typedef struct { int tls_d, tls_e, tls_f; } tls_struct_type; | ||
| 8 | |||
| 9 | __thread char tls_char = 42; | ||
| 10 | __thread short tls_short = 43; | ||
| 11 | __thread int tls_init = 44; | ||
| 12 | __thread long long tls_long_long = 45; | ||
| 5 | __thread int tls_zero; | 13 | __thread int tls_zero; |
| 14 | __thread float tls_float = 46.0; | ||
| 15 | __thread double tls_double = 47.0; | ||
| 16 | __thread long double tls_long_double = 48.0; | ||
| 17 | __thread int *tls_ptr = (int *)49; | ||
| 18 | __thread tls_enum_type tls_enum = tls_b; | ||
| 19 | __thread tls_struct_type tls_struct = { 50, 51, 52 }; | ||
| 6 | 20 | ||
| 7 | static void *thread_func(void *arg) | 21 | static int check(void) |
| 8 | { | 22 | { |
| 9 | (void)arg; | 23 | int errors = 0; |
| 10 | 24 | ||
| 11 | printf("%d\n", tls_init); | 25 | CHECK(tls_char, "%d", 42); |
| 12 | if (tls_init != 42) return (void *)1; | 26 | CHECK(tls_short, "%d", 43); |
| 27 | CHECK(tls_init, "%d", 44); | ||
| 28 | CHECK(tls_long_long, "%lld", 45); | ||
| 29 | CHECK(tls_zero, "%d", 0); | ||
| 30 | CHECK(tls_float, "%g", 46.0); | ||
| 31 | CHECK(tls_double, "%g", 47.0); | ||
| 32 | CHECK(tls_long_double, "%Lg", 48.0); | ||
| 33 | CHECK(tls_ptr, "%p", (int *)49); | ||
| 34 | CHECK(tls_enum, "%d", tls_b); | ||
| 35 | CHECK(tls_struct.tls_d, "%d", 50); | ||
| 36 | CHECK(tls_struct.tls_e, "%d", 51); | ||
| 37 | CHECK(tls_struct.tls_f, "%d", 52); | ||
| 38 | return errors; | ||
| 39 | } | ||
| 13 | 40 | ||
| 14 | printf("%d\n", tls_zero); | 41 | static void *thread_func(void *arg) |
| 15 | if (tls_zero != 0) return (void *)1; | 42 | { |
| 43 | (void)arg; | ||
| 44 | long errors = check(); | ||
| 16 | 45 | ||
| 17 | tls_init = 100; | 46 | tls_char = 10; |
| 18 | tls_zero = 200; | 47 | tls_short = 20; |
| 48 | tls_init = 30; | ||
| 49 | tls_long_long = 40; | ||
| 50 | tls_zero = 50; | ||
| 51 | tls_float = 60.0; | ||
| 52 | tls_double = 70.0; | ||
| 53 | tls_long_double = 80.0; | ||
| 54 | tls_ptr = (int *)90; | ||
| 55 | tls_enum = tls_c; | ||
| 56 | tls_struct.tls_d = 100; | ||
| 57 | tls_struct.tls_e = 110; | ||
| 58 | tls_struct.tls_f = 120; | ||
| 19 | 59 | ||
| 20 | printf("%d\n", tls_init); | 60 | CHECK(tls_char, "%d", 10); |
| 21 | printf("%d\n", tls_zero); | 61 | CHECK(tls_short, "%d", 20); |
| 62 | CHECK(tls_init, "%d", 30); | ||
| 63 | CHECK(tls_long_long, "%lld", 40); | ||
| 64 | CHECK(tls_zero, "%d", 50); | ||
| 65 | CHECK(tls_float, "%g", 60.0); | ||
| 66 | CHECK(tls_double, "%g", 70.0); | ||
| 67 | CHECK(tls_long_double, "%Lg", 80.0); | ||
| 68 | CHECK(tls_enum, "%d", tls_c); | ||
| 69 | CHECK(tls_ptr, "%p", (int *)90); | ||
| 70 | CHECK(tls_struct.tls_d, "%d", 100); | ||
| 71 | CHECK(tls_struct.tls_e, "%d", 110); | ||
| 72 | CHECK(tls_struct.tls_f, "%d", 120); | ||
| 22 | 73 | ||
| 23 | return (void *)0; | 74 | return (void *)errors; |
| 24 | } | 75 | } |
| 25 | 76 | ||
| 26 | int main() | 77 | int main() |
| 27 | { | 78 | { |
| 28 | pthread_t t; | 79 | pthread_t t; |
| 29 | void *ret; | 80 | void *ret; |
| 30 | int errors = 0; | 81 | int errors = check(); |
| 31 | |||
| 32 | printf("%d\n", tls_init); | ||
| 33 | if (tls_init != 42) errors = 1; | ||
| 34 | |||
| 35 | printf("%d\n", tls_zero); | ||
| 36 | if (tls_zero != 0) errors = 1; | ||
| 37 | 82 | ||
| 38 | pthread_create(&t, NULL, thread_func, NULL); | 83 | pthread_create(&t, NULL, thread_func, NULL); |
| 39 | pthread_join(t, &ret); | 84 | pthread_join(t, &ret); |
| 40 | 85 | ||
| 41 | if (ret) errors = 1; | 86 | return (ret ? 1 : 0) | errors | check(); |
| 42 | |||
| 43 | printf("%d\n", tls_init); | ||
| 44 | if (tls_init != 42) errors = 1; | ||
| 45 | |||
| 46 | printf("%d\n", tls_zero); | ||
| 47 | if (tls_zero != 0) errors = 1; | ||
| 48 | |||
| 49 | return errors; | ||
| 50 | } | 87 | } |
| @@ -1,8 +1,52 @@ | |||
| 1 | 42 | 1 | 42 |
| 2 | 43 | ||
| 3 | 44 | ||
| 4 | 45 | ||
| 2 | 0 | 5 | 0 |
| 6 | 46 | ||
| 7 | 47 | ||
| 8 | 48 | ||
| 9 | 0x31 | ||
| 10 | 1 | ||
| 11 | 50 | ||
| 12 | 51 | ||
| 13 | 52 | ||
| 3 | 42 | 14 | 42 |
| 15 | 43 | ||
| 16 | 44 | ||
| 17 | 45 | ||
| 4 | 0 | 18 | 0 |
| 19 | 46 | ||
| 20 | 47 | ||
| 21 | 48 | ||
| 22 | 0x31 | ||
| 23 | 1 | ||
| 24 | 50 | ||
| 25 | 51 | ||
| 26 | 52 | ||
| 27 | 10 | ||
| 28 | 20 | ||
| 29 | 30 | ||
| 30 | 40 | ||
| 31 | 50 | ||
| 32 | 60 | ||
| 33 | 70 | ||
| 34 | 80 | ||
| 35 | 2 | ||
| 36 | 0x5a | ||
| 5 | 100 | 37 | 100 |
| 6 | 200 | 38 | 110 |
| 39 | 120 | ||
| 7 | 42 | 40 | 42 |
| 41 | 43 | ||
| 42 | 44 | ||
| 43 | 45 | ||
| 8 | 0 | 44 | 0 |
| 45 | 46 | ||
| 46 | 47 | ||
| 47 | 48 | ||
| 48 | 0x31 | ||
| 49 | 1 | ||
| 50 | 50 | ||
| 51 | 51 | ||
| 52 | 52 | ||
| @@ -53,6 +53,7 @@ ifneq (,$(filter OpenBSD FreeBSD NetBSD,$(TARGETOS))) · 52 unmodified lines | |||
| 53 | SKIP += 106_versym.test # no pthread_condattr_setpshared | 53 | SKIP += 106_versym.test # no pthread_condattr_setpshared |
| 54 | SKIP += 114_bound_signal.test # libc problem signal/fork | 54 | SKIP += 114_bound_signal.test # libc problem signal/fork |
| 55 | SKIP += 116_bound_setjmp2.test # No TLS_FUNC/TLS_VAR in bcheck.c | 55 | SKIP += 116_bound_setjmp2.test # No TLS_FUNC/TLS_VAR in bcheck.c |
| 56 | SKIP += 144_tls.test # No tls support | ||
| 56 | endif | 57 | endif |
| 57 | ifeq ($(CONFIG_OSX),yes) | 58 | ifeq ($(CONFIG_OSX),yes) |
| 58 | SKIP += 144_tls.test # TLS runtime not supported on Mach-O | 59 | SKIP += 144_tls.test # TLS runtime not supported on Mach-O |
| @@ -1932,6 +1932,9 @@ void gen_opf(int op) · 1931 unmodified lines | |||
| 1932 | } | 1932 | } |
| 1933 | assert(!(vtop[-1].r & VT_LVAL)); | 1933 | assert(!(vtop[-1].r & VT_LVAL)); |
| 1934 | 1934 | ||
| 1935 | if ((vtop->r & VT_SYM) && (vtop->sym->type.t & VT_TLS)) | ||
| 1936 | o(0x64); /* fs segment prefix */ | ||
| 1937 | |||
| 1935 | if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) | 1938 | if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) |
| 1936 | o(0x66); | 1939 | o(0x66); |
| 1937 | if (op == TOK_EQ || op == TOK_NE) | 1940 | if (op == TOK_EQ || op == TOK_NE) |