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 17 static int32 gNextSlot = TLS_FIRST_FREE_SLOT; 18 19 20 int32 21 tls_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 31 void* 32 tls_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 44 void** 45 tls_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 58 void 59 tls_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