1 /* Copyright (C) 2003, 2005 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
22 # include <linuxthreads/internals.h>
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. */
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};
42 b PLTJMP(SYSCALL_ERROR)
45 # define PSEUDO(name, syscall_name, args) \
50 bne .Lpseudo_cancel; \
51 DO_CALL (syscall_name, args); \
56 DOCARGS_##args; /* save syscall args around 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. */ \
64 ldr r0, [sp], $4; /* retrieve return value. */ \
65 UNDOC2ARGS_##args; /* fix register damage. */ \
72 # define DOCARGS_1 str r0, [sp, #-4]!;
73 # define UNDOCARGS_1 ldr r0, [sp], #4;
76 # define DOCARGS_2 str r1, [sp, #-4]!; str r0, [sp, #-4]!;
77 # define UNDOCARGS_2 ldr r0, [sp], #4; ldr r1, [sp], #4;
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
84 # define DOCARGS_4 stmfd sp!, {r0-r3}
85 # define UNDOCARGS_4 ldmfd sp!, {r0-r3}
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
97 # define CENABLE bl PLTJMP(__libc_enable_asynccancel)
98 # define CDISABLE bl PLTJMP(__libc_disable_asynccancel)
99 # define __local_multiple_threads __libc_multiple_threads
102 # ifndef __ASSEMBLER__
103 extern int __local_multiple_threads attribute_hidden
;
104 # define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
107 # define SINGLE_THREAD_P \
108 ldr ip, =__local_multiple_threads; \
111 # define MAYBE_SAVE_LR \
113 # define PSEUDO_RET_MOV \
115 b PLTJMP(SYSCALL_ERROR)
116 # define PSEUDO_PROLOGUE
118 # define SINGLE_THREAD_P \
123 # define PSEUDO_PROLOGUE \
124 1: .word __local_multiple_threads - 2f - 8;
125 # define MAYBE_SAVE_LR /* lr already saved */
126 # define PSEUDO_RET_MOV PSEUDO_RET
130 #elif !defined __ASSEMBLER__
132 /* This code should never be used but we define it anyhow. */
133 # define SINGLE_THREAD_P (1)