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