1/*
2 * Copyright 2019-2021, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6#include <runtime_loader/runtime_loader.h>
7
8#include "support/TLS.h"
9#include "tls.h"
10
11
12struct tls_index {
13	unsigned long ti_module;
14	unsigned long ti_offset;
15};
16
17extern "C" void* __tls_get_addr(struct tls_index* ti);
18
19// TODO: use std::atomic<int> here like x86_64
20static int32 gNextSlot = TLS_FIRST_FREE_SLOT;
21
22
23static inline void**
24get_tls()
25{
26	void** tls;
27	__asm__ __volatile__ ("mv	%0, tp" : "=r" (tls));
28	return tls;
29}
30
31
32int32
33tls_allocate(void)
34{
35	if (gNextSlot < TLS_MAX_KEYS) {
36		int32 next = gNextSlot++;
37		if (next < TLS_MAX_KEYS)
38			return next;
39	}
40
41	return B_NO_MEMORY;
42}
43
44
45void *
46tls_get(int32 index)
47{
48	return get_tls()[index];
49}
50
51
52void **
53tls_address(int32 index)
54{
55	return get_tls() + index;
56}
57
58
59void
60tls_set(int32 index, void *value)
61{
62	get_tls()[index] = value;
63}
64
65
66void*
67__tls_get_addr(struct tls_index* ti)
68{
69	return __gRuntimeLoader->get_tls_address(ti->ti_module, ti->ti_offset);
70}
71