1/*
2 * Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#ifndef _NO_INLINE_ASM
8#	define _NO_INLINE_ASM 1
9#endif
10
11#include <support/TLS.h>
12#include <tls.h>
13
14#include <assert.h>
15
16
17static int32 gNextSlot = TLS_FIRST_FREE_SLOT;
18
19
20int32
21tls_allocate(void)
22{
23	int32 next = atomic_add(&gNextSlot, 1);
24	if (next >= TLS_MAX_KEYS)
25		return B_NO_MEMORY;
26
27	return next;
28}
29
30
31void*
32tls_get(int32 _index)
33{
34	int64 index = _index;
35	void* ret;
36
37	__asm__ __volatile__ (
38		"movq	%%fs:(, %%rdi, 8), %%rax"
39		: "=a" (ret) : "D" (index));
40	return ret;
41}
42
43
44void**
45tls_address(int32 _index)
46{
47	int64 index = _index;
48	void** ret;
49
50	__asm__ __volatile__ (
51		"movq	%%fs:0, %%rax\n\t"
52		"leaq	(%%rax, %%rdi, 8), %%rax\n\t"
53		: "=a" (ret) : "D" (index));
54	return ret;
55}
56
57
58void
59tls_set(int32 _index, void* value)
60{
61	int64 index = _index;
62	__asm__ __volatile__ (
63		"movq	%%rsi, %%fs:(, %%rdi, 8)"
64		: : "D" (index), "S" (value));
65}
66