(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
[glibc.git] / linuxthreads / sysdeps / unix / sysv / linux / arm / sysdep-cancel.h
blob019bd549139725cc17c9f8c1d44d64b691b7b0a5
1 /* Copyright (C) 2003 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Phil Blundell <pb@nexus.co.uk>, 2003.
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, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 #include <sysdep.h>
21 #ifndef __ASSEMBLER__
22 # include <linuxthreads/internals.h>
23 #endif
25 #if !defined NOT_IN_libc || defined IS_IN_libpthread
27 /* We push lr onto the stack, so we have to use ldmib instead of ldmia
28 to find the saved arguments. */
29 # ifdef PIC
30 # undef DOARGS_5
31 # undef DOARGS_6
32 # undef DOARGS_7
33 # define DOARGS_5 str r4, [sp, $-4]!; ldr r4, [sp, $8];
34 # define DOARGS_6 mov ip, sp; stmfd sp!, {r4, r5}; ldmib ip, {r4, r5};
35 # define DOARGS_7 mov ip, sp; stmfd sp!, {r4, r5, r6}; ldmib ip, {r4, r5, r6};
36 # endif
38 # undef PSEUDO_RET
39 # define PSEUDO_RET \
40 ldrcc pc, [sp], $4; \
41 ldr lr, [sp], $4; \
42 b PLTJMP(SYSCALL_ERROR)
44 # undef PSEUDO
45 # define PSEUDO(name, syscall_name, args) \
46 .section ".text"; \
47 PSEUDO_PROLOGUE; \
48 ENTRY (name); \
49 SINGLE_THREAD_P_INT; \
50 bne .Lpseudo_cancel; \
51 DO_CALL (syscall_name, args); \
52 cmn r0, $4096; \
53 PSEUDO_RET_MOV; \
54 .Lpseudo_cancel: \
55 MAYBE_SAVE_LR; \
56 DOCARGS_##args; /* save syscall args around CENABLE. */ \
57 CENABLE; \
58 mov ip, r0; /* put mask in safe place. */ \
59 UNDOCARGS_##args; /* restore syscall args. */ \
60 swi SYS_ify (syscall_name); /* do the call. */ \
61 str r0, [sp, $-4]!; /* save syscall return value. */ \
62 mov r0, ip; /* get mask back. */ \
63 CDISABLE; \
64 ldr r0, [sp], $4; /* retrieve return value. */ \
65 UNDOC2ARGS_##args; /* fix register damage. */ \
66 cmn r0, $4096;
68 # define DOCARGS_0
69 # define UNDOCARGS_0
70 # define UNDOC2ARGS_0
72 # define DOCARGS_1 str r0, [sp, #-4]!;
73 # define UNDOCARGS_1 ldr r0, [sp], #4;
74 # define UNDOC2ARGS_1
76 # define DOCARGS_2 str r1, [sp, #-4]!; str r0, [sp, #-4]!;
77 # define UNDOCARGS_2 ldr r0, [sp], #4; ldr r1, [sp], #4;
78 # define UNDOC2ARGS_2
80 # define DOCARGS_3 str r2, [sp, #-4]!; str r1, [sp, #-4]!; str r0, [sp, #-4]!;
81 # define UNDOCARGS_3 ldr r0, [sp], #4; ldr r1, [sp], #4; ldr r2, [sp], #4
82 # define UNDOC2ARGS_3
84 # define DOCARGS_4 stmfd sp!, {r0-r3}
85 # define UNDOCARGS_4 ldmfd sp!, {r0-r3}
86 # define UNDOC2ARGS_4
88 # define DOCARGS_5 stmfd sp!, {r0-r3}
89 # define UNDOCARGS_5 ldmfd sp, {r0-r3}; str r4, [sp, #-4]!; ldr r4, [sp, #24]
90 # define UNDOC2ARGS_5 ldr r4, [sp], #20
92 # ifdef IS_IN_libpthread
93 # define CENABLE bl PLTJMP(__pthread_enable_asynccancel)
94 # define CDISABLE bl PLTJMP(__pthread_disable_asynccancel)
95 # define __local_multiple_threads __pthread_multiple_threads
96 # else
97 # define CENABLE bl PLTJMP(__libc_enable_asynccancel)
98 # define CDISABLE bl PLTJMP(__libc_disable_asynccancel)
99 # define __local_multiple_threads __libc_multiple_threads
100 # endif
102 # ifndef __ASSEMBLER__
103 extern int __local_multiple_threads attribute_hidden;
104 # define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
105 # else
106 # if !defined PIC
107 # define SINGLE_THREAD_P_INT \
108 ldr ip, =__local_multiple_threads; \
109 ldr ip, [ip]; \
110 teq ip, #0;
111 # define SINGLE_THREAD_P SINGLE_THREAD_P_INT
112 # define MAYBE_SAVE_LR \
113 str lr, [sp, $-4]!;
114 # define PSEUDO_RET_MOV \
115 RETINSTR(cc, lr); \
116 b PLTJMP(SYSCALL_ERROR)
117 # define PSEUDO_PROLOGUE
118 # else
119 # define SINGLE_THREAD_P_PIC(reg) \
120 ldr ip, 1b; \
121 ldr reg, 2b; \
122 3: \
123 add ip, pc, ip; \
124 ldr ip, [ip, reg]; \
125 teq ip, #0;
126 # define SINGLE_THREAD_P_INT \
127 str lr, [sp, $-4]!; \
128 SINGLE_THREAD_P_PIC(lr)
129 # define SINGLE_THREAD_P \
130 SINGLE_THREAD_P_INT; \
131 ldr lr, [sp], $4
132 # define PSEUDO_PROLOGUE \
133 1: .word _GLOBAL_OFFSET_TABLE_ - 3f - 8; \
134 2: .word __local_multiple_threads(GOTOFF);
135 # define MAYBE_SAVE_LR /* lr already saved */
136 # define PSEUDO_RET_MOV PSEUDO_RET
137 # endif
138 # endif
140 #elif !defined __ASSEMBLER__
142 /* This code should never be used but we define it anyhow. */
143 # define SINGLE_THREAD_P (1)
145 #endif