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 | 242 | int op_reg = REG_VALUE(op_r2) << 3; |
| 243 | 243 | |
| 244 | 244 | if ((r & VT_SYM) && (sym->type.t & VT_TLS)) { |
| 245 | + if (opc == 0xdbc0d9) // VT_LDOUBLE | |
| 246 | + o(0xc0d9), opc = 0xdb; | |
| 245 | 247 | o(0x65); /* gs segment prefix */ |
| 246 | 248 | o(opc); |
| 247 | 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 | 194 | /* extract the basename of a file */ |
| 195 | 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 | 198 | while (p > name && !IS_DIRSEP(p[-1])) |
| 199 | 199 | --p; |
| 200 | 200 | return p; |
| @@ -188,6 +188,8 @@ static int load_symofs(int r, SValue *sv, int forstore, int *new_fc) · 187 unmodified lines | ||
| 188 | 188 | greloca(cur_text_section, sv->sym, ind, |
| 189 | 189 | R_RISCV_TPREL_LO12_I, 0); |
| 190 | 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 | 193 | ER(0x33, 0, rr, rr, 4, 0); // add RR, RR, tp |
| 192 | 194 | *new_fc = 0; |
| 193 | 195 | return rr; |
| @@ -3487,7 +3487,7 @@ error: · 3486 unmodified lines | ||
| 3487 | 3487 | } |
| 3488 | 3488 | done: |
| 3489 | 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 | 3493 | /* return type size as known at compile time. Put alignment at 'a' */ |
| @@ -1,50 +1,87 @@ | ||
| 1 | 1 | #include <stdio.h> |
| 2 | 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 | 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); | |
| 12 | − if (tls_init != 42) return (void *)1; | |
| 25 | + CHECK(tls_char, "%d", 42); | |
| 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); | |
| 15 | − if (tls_zero != 0) return (void *)1; | |
| 41 | +static void *thread_func(void *arg) | |
| 42 | +{ | |
| 43 | + (void)arg; | |
| 44 | + long errors = check(); | |
| 16 | 45 | |
| 17 | − tls_init = 100; | |
| 18 | − tls_zero = 200; | |
| 46 | + tls_char = 10; | |
| 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); | |
| 21 | − printf("%d\n", tls_zero); | |
| 60 | + CHECK(tls_char, "%d", 10); | |
| 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 | 77 | int main() |
| 27 | 78 | { |
| 28 | 79 | pthread_t t; |
| 29 | 80 | void *ret; |
| 30 | − int errors = 0; | |
| 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; | |
| 81 | + int errors = check(); | |
| 37 | 82 | |
| 38 | 83 | pthread_create(&t, NULL, thread_func, NULL); |
| 39 | 84 | pthread_join(t, &ret); |
| 40 | 85 | |
| 41 | − if (ret) errors = 1; | |
| 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; | |
| 86 | + return (ret ? 1 : 0) | errors | check(); | |
| 50 | 87 | } |
| @@ -1,8 +1,52 @@ | ||
| 1 | 1 | 42 |
| 2 | +43 | |
| 3 | +44 | |
| 4 | +45 | |
| 2 | 5 | 0 |
| 6 | +46 | |
| 7 | +47 | |
| 8 | +48 | |
| 9 | +0x31 | |
| 10 | +1 | |
| 11 | +50 | |
| 12 | +51 | |
| 13 | +52 | |
| 3 | 14 | 42 |
| 15 | +43 | |
| 16 | +44 | |
| 17 | +45 | |
| 4 | 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 | 37 | 100 |
| 6 | −200 | |
| 38 | +110 | |
| 39 | +120 | |
| 7 | 40 | 42 |
| 41 | +43 | |
| 42 | +44 | |
| 43 | +45 | |
| 8 | 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 | 53 | SKIP += 106_versym.test # no pthread_condattr_setpshared |
| 54 | 54 | SKIP += 114_bound_signal.test # libc problem signal/fork |
| 55 | 55 | SKIP += 116_bound_setjmp2.test # No TLS_FUNC/TLS_VAR in bcheck.c |
| 56 | + SKIP += 144_tls.test # No tls support | |
| 56 | 57 | endif |
| 57 | 58 | ifeq ($(CONFIG_OSX),yes) |
| 58 | 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 | 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 | 1938 | if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) |
| 1936 | 1939 | o(0x66); |
| 1937 | 1940 | if (op == TOK_EQ || op == TOK_NE) |