Update copyright dates with scripts/update-copyrights
[glibc.git] / sysdeps / i386 / nptl / tcb-access.h
blob28f0a5625f589e0d5853d638bdcd158d27090827
1 /* THREAD_* accessors. i386 version.
2 Copyright (C) 2002-2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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 <https://www.gnu.org/licenses/>. */
19 /* Read member of the thread descriptor directly. */
20 #define THREAD_GETMEM(descr, member) \
21 ({ __typeof (descr->member) __value; \
22 _Static_assert (sizeof (__value) == 1 \
23 || sizeof (__value) == 4 \
24 || sizeof (__value) == 8, \
25 "size of per-thread data"); \
26 if (sizeof (__value) == 1) \
27 asm volatile ("movb %%gs:%P2,%b0" \
28 : "=q" (__value) \
29 : "0" (0), "i" (offsetof (struct pthread, member))); \
30 else if (sizeof (__value) == 4) \
31 asm volatile ("movl %%gs:%P1,%0" \
32 : "=r" (__value) \
33 : "i" (offsetof (struct pthread, member))); \
34 else /* 8 */ \
35 { \
36 asm volatile ("movl %%gs:%P1,%%eax\n\t" \
37 "movl %%gs:%P2,%%edx" \
38 : "=A" (__value) \
39 : "i" (offsetof (struct pthread, member)), \
40 "i" (offsetof (struct pthread, member) + 4)); \
41 } \
42 __value; })
44 /* THREAD_GETMEM already forces a read. */
45 #define THREAD_GETMEM_VOLATILE(descr, member) THREAD_GETMEM (descr, member)
47 /* Same as THREAD_GETMEM, but the member offset can be non-constant. */
48 #define THREAD_GETMEM_NC(descr, member, idx) \
49 ({ __typeof (descr->member[0]) __value; \
50 _Static_assert (sizeof (__value) == 1 \
51 || sizeof (__value) == 4 \
52 || sizeof (__value) == 8, \
53 "size of per-thread data"); \
54 if (sizeof (__value) == 1) \
55 asm volatile ("movb %%gs:%P2(%3),%b0" \
56 : "=q" (__value) \
57 : "0" (0), "i" (offsetof (struct pthread, member[0])), \
58 "r" (idx)); \
59 else if (sizeof (__value) == 4) \
60 asm volatile ("movl %%gs:%P1(,%2,4),%0" \
61 : "=r" (__value) \
62 : "i" (offsetof (struct pthread, member[0])), \
63 "r" (idx)); \
64 else /* 8 */ \
65 { \
66 asm volatile ("movl %%gs:%P1(,%2,8),%%eax\n\t" \
67 "movl %%gs:4+%P1(,%2,8),%%edx" \
68 : "=&A" (__value) \
69 : "i" (offsetof (struct pthread, member[0])), \
70 "r" (idx)); \
71 } \
72 __value; })
76 /* Set member of the thread descriptor directly. */
77 #define THREAD_SETMEM(descr, member, value) \
78 ({ \
79 _Static_assert (sizeof (descr->member) == 1 \
80 || sizeof (descr->member) == 4 \
81 || sizeof (descr->member) == 8, \
82 "size of per-thread data"); \
83 if (sizeof (descr->member) == 1) \
84 asm volatile ("movb %b0,%%gs:%P1" : \
85 : "iq" (value), \
86 "i" (offsetof (struct pthread, member))); \
87 else if (sizeof (descr->member) == 4) \
88 asm volatile ("movl %0,%%gs:%P1" : \
89 : "ir" (value), \
90 "i" (offsetof (struct pthread, member))); \
91 else /* 8 */ \
92 { \
93 asm volatile ("movl %%eax,%%gs:%P1\n\t" \
94 "movl %%edx,%%gs:%P2" : \
95 : "A" ((uint64_t) cast_to_integer (value)), \
96 "i" (offsetof (struct pthread, member)), \
97 "i" (offsetof (struct pthread, member) + 4)); \
98 }})
101 /* Same as THREAD_SETMEM, but the member offset can be non-constant. */
102 #define THREAD_SETMEM_NC(descr, member, idx, value) \
103 ({ \
104 _Static_assert (sizeof (descr->member[0]) == 1 \
105 || sizeof (descr->member[0]) == 4 \
106 || sizeof (descr->member[0]) == 8, \
107 "size of per-thread data"); \
108 if (sizeof (descr->member[0]) == 1) \
109 asm volatile ("movb %b0,%%gs:%P1(%2)" : \
110 : "iq" (value), \
111 "i" (offsetof (struct pthread, member)), \
112 "r" (idx)); \
113 else if (sizeof (descr->member[0]) == 4) \
114 asm volatile ("movl %0,%%gs:%P1(,%2,4)" : \
115 : "ir" (value), \
116 "i" (offsetof (struct pthread, member)), \
117 "r" (idx)); \
118 else /* 8 */ \
120 asm volatile ("movl %%eax,%%gs:%P1(,%2,8)\n\t" \
121 "movl %%edx,%%gs:4+%P1(,%2,8)" : \
122 : "A" ((uint64_t) cast_to_integer (value)), \
123 "i" (offsetof (struct pthread, member)), \
124 "r" (idx)); \