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
16struct tls_index {
17	unsigned long int	module;
18	unsigned long int	offset;
19};
20
21
22void* ___tls_get_addr(struct tls_index* ti) __attribute__((__regparm__(1)));
23
24#endif	// GCC2
25
26
27static int32 gNextSlot = TLS_FIRST_FREE_SLOT;
28
29
30int32
31tls_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
41void *
42tls_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
52void **
53tls_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
64void
65tls_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
76void* __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