20c924fc5a40c7c97689b85465d5eeda68e8c686
[jlayton/glibc.git] / ports / sysdeps / tile / tls-macros.h
1 /* Copyright (C) 2011-2014 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library.  If not, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #ifdef __tilegx__
20 #define TLS_GD_OFFSET(x)                        \
21   "moveli r0, hw1_last_tls_gd(" #x ")\n\t"      \
22   "shl16insli r0, r0, hw0_tls_gd(" #x ")\n\t"   \
23   "addi r0, %1, tls_add(" #x ")\n\t"
24 #else
25 #define TLS_GD_OFFSET(x)                        \
26   "auli r0, %1, tls_gd_ha16(" #x ")\n\t"        \
27   "addli r0, r0, tls_gd_lo16(" #x ")\n\t"
28 #endif
29
30 #define TLS_GD(x)                                               \
31   ({                                                            \
32     int *__retval;                                              \
33     extern char _GLOBAL_OFFSET_TABLE_[];                        \
34                                                                 \
35     asm (TLS_GD_OFFSET(x)                                       \
36          "jal tls_gd_call(" #x ")\n\t"                          \
37          "addi %0, r0, tls_gd_add(" #x ")" :                    \
38          "=&r" (__retval) : "r" (_GLOBAL_OFFSET_TABLE_) :       \
39          "r0", "r25", "r26", "r27", "r28", "r29");              \
40     __retval; })
41
42 /* No special support for LD mode. */
43 #define TLS_LD TLS_GD
44
45 #ifdef __tilegx__
46 #define TLS_IE_OFFSET(x)                        \
47   "moveli %0, hw1_last_tls_ie(" #x ")\n\t"      \
48   "shl16insli %0, %0, hw0_tls_ie(" #x ")\n\t"   \
49   "addi %0, %1, tls_add(" #x ")\n\t"
50 #define LD_TLS "ld_tls"
51 #else
52 #define TLS_IE_OFFSET(x)                        \
53   "auli %0, %1, tls_ie_ha16(" #x ")\n\t"        \
54   "addli %0, %0, tls_ie_lo16(" #x ")\n\t"
55 #define LD_TLS "lw_tls"
56 #endif
57
58 #define TLS_IE(x)                                               \
59   ({                                                            \
60     int *__retval;                                              \
61     extern char _GLOBAL_OFFSET_TABLE_[];                        \
62                                                                 \
63     asm (TLS_IE_OFFSET(x)                                       \
64          LD_TLS " %0, %0, tls_ie_load(" #x ")\n\t"              \
65          "add %0, %0, tp" :                                     \
66          "=&r" (__retval) : "r" (_GLOBAL_OFFSET_TABLE_));       \
67     __retval; })
68
69 #ifdef __tilegx__
70 #define _TLS_LE(x)                              \
71   "moveli %0, hw1_last_tls_le(" #x ")\n\t"      \
72   "shl16insli %0, %0, hw0_tls_le(" #x ")\n\t"   \
73   "add %0, %0, tp"
74 #else
75 #define _TLS_LE(x)                              \
76   "auli %0, tp, tls_le_ha16(" #x ")\n\t"        \
77   "addli %0, %0, tls_le_lo16(" #x ")\n\t"
78 #endif
79
80 #define TLS_LE(x)                               \
81   ({                                            \
82     int *__retval;                              \
83     asm (_TLS_LE(x) : "=r" (__retval));         \
84     __retval; })