xref: /haiku/src/system/libroot/os/arch/x86/tls.c (revision 4a55cc230cf7566cadcbb23b1928eefff8aea9a2)
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 #include <runtime_loader/runtime_loader.h>
9 
10 #include "support/TLS.h"
11 #include "tls.h"
12 
13 
14 #if !defined(__GNUC__) || (__GNUC__ > 2)
15 
16 struct tls_index {
17 	unsigned long int	module;
18 	unsigned long int	offset;
19 };
20 
21 
22 void* ___tls_get_addr(struct tls_index* ti) __attribute__((__regparm__(1)));
23 
24 #endif	// GCC2
25 
26 
27 static int32 gNextSlot = TLS_FIRST_FREE_SLOT;
28 
29 
30 int32
31 tls_allocate(void)
32 {
33 	int32 next = atomic_add(&gNextSlot, 1);
34 	if (next >= TLS_MAX_KEYS)
35 		return B_NO_MEMORY;
36 
37 	return next;
38 }
39 
40 
41 void *
42 tls_get(int32 index)
43 {
44 	void *ret;
45 	__asm__ __volatile__ (
46 		"movl	%%fs:(, %1, 4), %0"
47 		: "=r" (ret) : "r" (index));
48 	return ret;
49 }
50 
51 
52 void **
53 tls_address(int32 index)
54 {
55 	void **ret;
56 	__asm__ __volatile__ (
57 		"movl	%%fs:0, %0\n\t"
58 		"leal	(%0, %1, 4), %0\n\t"
59 		: "=&r" (ret) : "r" (index));
60 	return ret;
61 }
62 
63 
64 void
65 tls_set(int32 index, void *value)
66 {
67 	__asm__ __volatile__ (
68 		"movl	%1, %%fs:(, %0, 4)"
69 		: : "r" (index), "r" (value));
70 }
71 
72 
73 #if !defined(__GNUC__) || (__GNUC__ > 2)
74 
75 
76 void* __attribute__((__regparm__(1)))
77 ___tls_get_addr(struct tls_index* ti)
78 {
79 	return __gRuntimeLoader->get_tls_address(ti->module, ti->offset);
80 }
81 
82 
83 #endif	// GCC2
84 
85