Commit nios2 port to master.
[glibc.git] / sysdeps / unix / sysv / linux / nios2 / sysdep-cancel.h
blobe2c70ba970ff5eadaeda03606cab22b9b3ad6de2
1 /* Assembler macros with cancellation support, Nios II version.
2 Copyright (C) 2003-2015 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 <http://www.gnu.org/licenses/>. */
19 #include <sysdep.h>
20 #include <tls.h>
21 #ifndef __ASSEMBLER__
22 # include <nptl/pthreadP.h>
23 #endif
25 #if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
27 # undef PSEUDO
28 # define PSEUDO(name, syscall_name, args) \
29 .type __##syscall_name##_nocancel, @function; \
30 .globl __##syscall_name##_nocancel; \
31 __##syscall_name##_nocancel: \
32 cfi_startproc; \
33 DO_CALL (syscall_name, args); \
34 bne r7, zero, SYSCALL_ERROR_LABEL; \
35 ret; \
36 cfi_endproc; \
37 .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
38 ENTRY (name) \
39 SINGLE_THREAD_P(r2); \
40 bne r2, zero, pseudo_cancel; \
41 DO_CALL (syscall_name, args); \
42 bne r7, zero, SYSCALL_ERROR_LABEL; \
43 ret; \
44 pseudo_cancel: \
45 SAVESTK_##args; /* save syscall args and adjust stack */ \
46 SAVEREG(ra, 0); /* save return address */ \
47 SAVEREG(r22, 4); /* save GOT pointer */ \
48 nextpc r22; \
49 1: movhi r2, %hiadj(_gp_got - 1b); \
50 addi r2, r2, %lo(_gp_got - 1b); \
51 add r22, r22, r2; \
52 CENABLE; \
53 callr r3; \
54 stw r2, 8(sp); /* save mask */ \
55 LOADARGS_##args; \
56 movi r2, SYS_ify(syscall_name); \
57 trap; \
58 stw r2, 12(sp); /* save syscall result */ \
59 stw r7, 16(sp); /* save syscall error flag */ \
60 ldw r4, 8(sp); /* pass mask as argument 1 */ \
61 CDISABLE; \
62 callr r3; \
63 ldw r7, 16(sp); /* restore syscall error flag */ \
64 ldw r2, 12(sp); /* restore syscall result */ \
65 ldw ra, 0(sp); /* restore return address */ \
66 ldw r22, 4(sp); /* restore GOT pointer */ \
67 RESTORESTK_##args; \
68 bne r7, zero, SYSCALL_ERROR_LABEL;
71 # undef PSEUDO_END
72 # define PSEUDO_END(sym) \
73 SYSCALL_ERROR_HANDLER \
74 END (sym)
76 #define SAVEREG(REG, LOC) stw REG, LOC(sp); cfi_rel_offset (REG, LOC)
77 #define SAVESTK(X) subi sp, sp, X; cfi_adjust_cfa_offset(X)
78 #define SAVESTK_0 SAVESTK(20)
79 #define SAVEARG_1 SAVEREG(r4, 20)
80 #define SAVESTK_1 SAVESTK(24); SAVEARG_1
81 #define SAVEARG_2 SAVEREG(r5, 24); SAVEARG_1
82 #define SAVESTK_2 SAVESTK(28); SAVEARG_2
83 #define SAVEARG_3 SAVEREG(r6, 28); SAVEARG_2
84 #define SAVESTK_3 SAVESTK(32); SAVEARG_3
85 #define SAVEARG_4 SAVEREG(r7, 32); SAVEARG_3
86 #define SAVESTK_4 SAVESTK(36); SAVEARG_4
87 #define SAVESTK_5 SAVESTK_4
88 #define SAVESTK_6 SAVESTK_5
90 #define LOADARGS_0
91 #define LOADARGS_1 ldw r4, 20(sp)
92 #define LOADARGS_2 LOADARGS_1; ldw r5, 24(sp)
93 #define LOADARGS_3 LOADARGS_2; ldw r6, 28(sp)
94 #define LOADARGS_4 LOADARGS_3; ldw r7, 32(sp)
95 #define LOADARGS_5 LOADARGS_4; ldw r8, 36(sp)
96 #define LOADARGS_6 LOADARGS_5; ldw r9, 40(sp)
98 #define RESTORESTK(X) addi sp, sp, X; cfi_adjust_cfa_offset(-X)
99 #define RESTORESTK_0 RESTORESTK(20)
100 #define RESTORESTK_1 RESTORESTK(24)
101 #define RESTORESTK_2 RESTORESTK(28)
102 #define RESTORESTK_3 RESTORESTK(32)
103 #define RESTORESTK_4 RESTORESTK(36)
104 #define RESTORESTK_5 RESTORESTK(36)
105 #define RESTORESTK_6 RESTORESTK(36)
107 # if IS_IN (libpthread)
108 # define CENABLE ldw r3, %call(__pthread_enable_asynccancel)(r22)
109 # define CDISABLE ldw r3, %call(__pthread_disable_asynccancel)(r22)
110 # elif IS_IN (librt)
111 # define CENABLE ldw r3, %call(__librt_enable_asynccancel)(r22)
112 # define CDISABLE ldw r3, %call(__librt_disable_asynccancel)(r22)
113 # elif IS_IN (libc)
114 # define CENABLE ldw r3, %call(__libc_enable_asynccancel)(r22)
115 # define CDISABLE ldw r3, %call(__libc_disable_asynccancel)(r22)
116 # else
117 # error Unsupported library
118 # endif
120 # ifndef __ASSEMBLER__
121 # define SINGLE_THREAD_P \
122 __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
123 header.multiple_threads) \
124 == 0, 1)
125 # else
126 # define SINGLE_THREAD_P(reg) \
127 ldw reg, MULTIPLE_THREADS_OFFSET(r23)
128 #endif
130 #elif !defined __ASSEMBLER__
132 # define SINGLE_THREAD_P 1
133 # define NO_CANCELLATION 1
135 #endif
137 #ifndef __ASSEMBLER__
138 # define RTLD_SINGLE_THREAD_P \
139 __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
140 header.multiple_threads) == 0, 1)
141 #endif