xref: /haiku/src/system/libroot/os/arch/x86/tls.c (revision 71452e98334eaac603bf542d159e24788a46bebb)
1 /*
2  * Copyright 2014, Paweł Dziepak, pdziepak@quarnos.org.
3  * Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
4  * Distributed under the terms of the MIT License.
5  */
6 
7 
8 // we don't want to have the inline assembly included here
9 #ifndef _NO_INLINE_ASM
10 #	define _NO_INLINE_ASM 1
11 #endif
12 
13 #include <runtime_loader/runtime_loader.h>
14 
15 #include "support/TLS.h"
16 #include "tls.h"
17 
18 
19 #if !defined(__GNUC__) || (__GNUC__ > 2)
20 
21 struct tls_index {
22 	unsigned long int	module;
23 	unsigned long int	offset;
24 };
25 
26 
27 void* ___tls_get_addr(struct tls_index* ti) __attribute__((__regparm__(1)));
28 
29 #endif	// GCC2
30 
31 
32 static int32 gNextSlot = TLS_FIRST_FREE_SLOT;
33 
34 
35 int32
36 tls_allocate(void)
37 {
38 	int32 next = atomic_add(&gNextSlot, 1);
39 	if (next >= TLS_MAX_KEYS)
40 		return B_NO_MEMORY;
41 
42 	return next;
43 }
44 
45 
46 void *
47 tls_get(int32 index)
48 {
49 	void *ret;
50 	__asm__ __volatile__ (
51 		"movl	%%fs:(, %1, 4), %0"
52 		: "=r" (ret) : "r" (index));
53 	return ret;
54 }
55 
56 
57 void **
58 tls_address(int32 index)
59 {
60 	void **ret;
61 	__asm__ __volatile__ (
62 		"movl	%%fs:0, %0\n\t"
63 		"leal	(%0, %1, 4), %0\n\t"
64 		: "=&r" (ret) : "r" (index));
65 	return ret;
66 }
67 
68 
69 void
70 tls_set(int32 index, void *value)
71 {
72 	__asm__ __volatile__ (
73 		"movl	%1, %%fs:(, %0, 4)"
74 		: : "r" (index), "r" (value));
75 }
76 
77 
78 #if !defined(__GNUC__) || (__GNUC__ > 2)
79 
80 
81 void* __attribute__((__regparm__(1)))
82 ___tls_get_addr(struct tls_index* ti)
83 {
84 	return __gRuntimeLoader->get_tls_address(ti->module, ti->offset);
85 }
86 
87 
88 #endif	// GCC2
89 
90