⛏️ index : haiku.git

/*
 * Copyright 2014, PaweΕ‚ Dziepak, pdziepak@quarnos.org.
 * Copyright 2003, Axel DΓΆrfler, axeld@pinc-software.de. All rights reserved.
 * Distributed under the terms of the MIT License.
 */


#include <runtime_loader/runtime_loader.h>

#include "support/TLS.h"
#include "tls.h"


#if !defined(__GNUC__) || (__GNUC__ > 2)

struct tls_index {
	unsigned long int	module;
	unsigned long int	offset;
};


void* ___tls_get_addr(struct tls_index* ti) __attribute__((__regparm__(1)));

#endif	// GCC2


static int32 gNextSlot = TLS_FIRST_FREE_SLOT;


int32
tls_allocate(void)
{
	int32 next = atomic_add(&gNextSlot, 1);
	if (next >= TLS_MAX_KEYS)
		return B_NO_MEMORY;

	return next;
}


void *
tls_get(int32 index)
{
	void *ret;
	__asm__ __volatile__ (
		"movl	%%fs:(, %1, 4), %0"
		: "=r" (ret) : "r" (index));
	return ret;
}


void **
tls_address(int32 index)
{
	void **ret;
	__asm__ __volatile__ (
		"movl	%%fs:0, %0\n\t"
		"leal	(%0, %1, 4), %0\n\t"
		: "=&r" (ret) : "r" (index));
	return ret;
}


void
tls_set(int32 index, void *value)
{
	__asm__ __volatile__ (
		"movl	%1, %%fs:(, %0, 4)"
		: : "r" (index), "r" (value));
}


#if !defined(__GNUC__) || (__GNUC__ > 2)


void* __attribute__((__regparm__(1)))
___tls_get_addr(struct tls_index* ti)
{
	return __gRuntimeLoader->get_tls_address(ti->module, ti->offset);
}


#endif	// GCC2