summary refs log tree commit diff
path: root/test
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin@c9x.me>2022-10-12 20:59:20 +0200
committerQuentin Carbonneaux <quentin@c9x.me>2022-10-12 21:12:08 +0200
commit8ecae922997c55f70cd9e19cbf947a520f7ecca3 (patch)
treef75685ee79cc015883b2a60d7a5cbf6c52c751d5 /test
parent577e93fe6d729b63447faad471fd0f5f2296f667 (diff)
downloadroux-8ecae922997c55f70cd9e19cbf947a520f7ecca3.tar.gz
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 'test')
-rw-r--r--test/tls.ssa30
1 files changed, 30 insertions, 0 deletions
diff --git a/test/tls.ssa b/test/tls.ssa
new file mode 100644
index 0000000..e990663
--- /dev/null
+++ b/test/tls.ssa
@@ -0,0 +1,30 @@
+thread data $i = align 4 {w 42}
+data $fmt = align 1 {b "i%d==%d\n", b 0}
+
+export
+function w $main() {
+@start
+	%pthr =l alloc8 8
+	%rval =l alloc8 8
+	call $pthread_create(l %pthr, l 0, l $thread, l 0)
+	%t =l load %pthr
+	call $pthread_join(l %t, l %rval)
+	%i0 =w loadw thread $i
+	call $printf(l $fmt, ..., w 0, w %i0)
+	%i1 =w load %rval
+	call $printf(l $fmt, ..., w 1, w %i1)
+	ret 0
+}
+
+function l $thread(l %arg) {
+@start
+	%i3 =l add thread $i, 3
+	storeb 24, %i3
+	%ret =l loadsw thread $i
+	ret %ret
+}
+
+# >>> output
+# i0==42
+# i1==402653226
+# <<<