| // Copyright 2014 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| #ifdef GOOS_windows | |
| // Offset of the TEB's ThreadLocalStoragePointer field, which points to the | |
| // array of module TLS blocks indexed by _tls_index. | |
| #ifdef GOARCH_386 | |
| #define TEB_ThreadLocalStoragePointer 0x2c | |
| #else | |
| #define TEB_ThreadLocalStoragePointer 0x58 | |
| #endif | |
| #endif | |
| #ifdef GOARCH_arm | |
| #define LR R14 | |
| #endif | |
| #ifdef GOARCH_amd64 | |
| #ifdef GOOS_windows | |
| // get_tls loads the address of the current thread's g slot into r. | |
| // It clobbers R11; r must differ from R11. | |
| #define get_tls(r) \ | |
| MOVL _tls_index(SB), r /* 32-bit TLS index, zero-extended to 64 bits. */ \ | |
| MOVQ TEB_ThreadLocalStoragePointer(GS), R11 /* R11 is volatile in the host ABI. */ \ | |
| MOVQ (R11)(r*8), r \ | |
| MOVQ runtime·tls_g(SB), R11 \ | |
| LEAQ (r)(R11*1), r | |
| #else | |
| #define get_tls(r) MOVQ TLS, r | |
| #endif | |
| #define g(r) 0(r)(TLS*1) | |
| #endif | |
| #ifdef GOARCH_386 | |
| #ifdef GOOS_windows | |
| // get_tls2 lets callers preserve AX or load the TLS address into AX. | |
| // r and scratch must differ; scratch is clobbered. | |
| #define get_tls2(r, scratch) \ | |
| MOVL _tls_index(SB), r \ | |
| MOVL TEB_ThreadLocalStoragePointer(FS), scratch \ | |
| MOVL (scratch)(r*4), r \ | |
| MOVL runtime·tls_g(SB), scratch \ | |
| LEAL (r)(scratch*1), r | |
| #define get_tls(r) get_tls2(r, AX) | |
| #else | |
| #define get_tls(r) MOVL TLS, r | |
| #define get_tls2(r, scratch) MOVL TLS, r | |
| #endif | |
| #define g(r) 0(r)(TLS*1) | |
| #endif |