aboutsummaryrefslogtreecommitdiff
path: root/amd64/emit.c
diff options
context:
space:
mode:
authorQuentin Carbonneaux <[email protected]>2022-10-12 20:59:20 +0200
committerQuentin Carbonneaux <[email protected]>2022-10-12 21:12:08 +0200
commit8ecae922997c55f70cd9e19cbf947a520f7ecca3 (patch)
treef75685ee79cc015883b2a60d7a5cbf6c52c751d5 /amd64/emit.c
parent577e93fe6d729b63447faad471fd0f5f2296f667 (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.c12
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: