diff options
author | Quentin Carbonneaux <quentin@c9x.me> | 2023-04-02 14:47:42 +0200 |
---|---|---|
committer | Quentin Carbonneaux <quentin@c9x.me> | 2023-04-02 14:48:52 +0200 |
commit | a9d3e06a57b4a77012efd6e38d67063c914b71b4 (patch) | |
tree | 61eb50a327a4d27ce1ec9ca9f98ce8a5a5524d1e /amd64 | |
parent | 5fee3da6ac3b4995f0d9a6cef3a5e916208cca59 (diff) | |
download | roux-a9d3e06a57b4a77012efd6e38d67063c914b71b4.tar.gz |
amd64_sysv: thread-local support in Oaddr
Thanks to Lassi Pulkkinen for flagging the issue and pointing me to Ulrich Drepper's extensive doc [1]. [1] https://people.redhat.com/drepper/tls.pdf
Diffstat (limited to 'amd64')
-rw-r--r-- | amd64/emit.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/amd64/emit.c b/amd64/emit.c index 9b8bb5d..7b2681e 100644 --- a/amd64/emit.c +++ b/amd64/emit.c @@ -372,6 +372,7 @@ emitins(Ins i, Fn *fn, FILE *f) int64_t val; int o, t0; Ins ineg; + char *sym; switch (i.op) { default: @@ -490,6 +491,22 @@ emitins(Ins i, Fn *fn, FILE *f) * should use movabsq when reading movq */ emitf("mov%k %0, %=", &i, fn, f); break; + case Oaddr: + if (!T.apple + && rtype(i.arg[0]) == RCon + && fn->con[i.arg[0].val].sym.type == SThr) { + /* derive the symbol address from the TCB + * address at offset 0 of %fs */ + assert(isreg(i.to)); + sym = str(fn->con[i.arg[0].val].sym.id); + emitf("movq %%fs:0, %=", &i, fn, f); + fprintf(f, "\tleaq %s%s@tpoff(%%%s), %%%s\n", + sym[0] == '"' ? "" : T.assym, sym, + regtoa(i.to.val, SLong), + regtoa(i.to.val, SLong)); + break; + } + goto Table; case Ocall: /* calls simply have a weird syntax in AT&T * assembly... */ |