diff options
| author | Quentin Carbonneaux <[email protected]> | 2022-10-12 20:59:20 +0200 |
|---|---|---|
| committer | Quentin Carbonneaux <[email protected]> | 2022-10-12 21:12:08 +0200 |
| commit | 8ecae922997c55f70cd9e19cbf947a520f7ecca3 (patch) | |
| tree | f75685ee79cc015883b2a60d7a5cbf6c52c751d5 /amd64/emit.c | |
| parent | 577e93fe6d729b63447faad471fd0f5f2296f667 (diff) | |
thread-local storage for amd64_apple
It is quite similar to arm64_apple.
Probably, the call that needs to be
generated also provides extra
invariants on top of the regular
abi, but I have not checked that.
Clang generates code that is a bit
neater than qbe's because, on x86,
a load can be fused in a call
instruction! We do not bother with
supporting these since we expect
only sporadic use of the feature.
For reference, here is what clang
might output for a store to the
second entry of a thread-local
array of ints:
movq _x@TLVP(%rip), %rdi
callq *(%rdi)
movl %ecx, 4(%rax)
Diffstat (limited to 'amd64/emit.c')
| -rw-r--r-- | amd64/emit.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/amd64/emit.c b/amd64/emit.c index 84714e8..37dd1e9 100644 --- a/amd64/emit.c +++ b/amd64/emit.c @@ -167,9 +167,12 @@ emitcon(Con *con, FILE *f) case CAddr: l = str(con->label); p = l[0] == '"' ? "" : T.assym; - if (con->reloc == RelThr) - fprintf(f, "%%fs:%s%s@tpoff", p, l); - else + if (con->reloc == RelThr) { + if (T.apple) + fprintf(f, "%s%s@TLVP", p, l); + else + fprintf(f, "%%fs:%s%s@tpoff", p, l); + } else fprintf(f, "%s%s", p, l); if (con->bits.i) fprintf(f, "%+"PRId64, con->bits.i); @@ -340,7 +343,8 @@ Next: case RCon: off = fn->con[ref.val]; emitcon(&off, f); - if (off.type == CAddr && off.reloc != RelThr) + if (off.type == CAddr) + if (off.reloc != RelThr || T.apple) fprintf(f, "(%%rip)"); break; case RTmp: |
