]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libpthread/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libpthread / linuxthreads / sysdeps / unix / sysv / linux / arm / sysdep-cancel.h
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.
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 #include <tls.h>
20 #include <pt-machine.h>
21 #ifndef __ASSEMBLER__
22 # include <linuxthreads/internals.h>
23 #endif
24
25 #if !defined NOT_IN_libc || defined IS_IN_libpthread
26
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
37
38 # undef PSEUDO_RET
39 # define PSEUDO_RET                                                     \
40     ldrcc pc, [sp], $4;                                                 \
41     ldr lr, [sp], $4;                                                   \
42     b PLTJMP(SYSCALL_ERROR)
43
44 # undef PSEUDO
45 # define PSEUDO(name, syscall_name, args)                               \
46   .section ".text";                                                     \
47     PSEUDO_PROLOGUE;                                                    \
48   ENTRY (name);                                                         \
49     SINGLE_THREAD_P;                                                    \
50     bne .Lpseudo_cancel;                                                \
51     DO_CALL (syscall_name, args);                                       \
52     cmn r0, $4096;                                                      \
53     RETINSTR(cc, lr);                                                   \
54     b PLTJMP(SYSCALL_ERROR);                                            \
55   .Lpseudo_cancel:                                                      \
56     str lr, [sp, $-4]!;                                                 \
57     DOCARGS_##args;     /* save syscall args around CENABLE.  */        \
58     CENABLE;                                                            \
59     mov ip, r0;         /* put mask in safe place.  */                  \
60     UNDOCARGS_##args;   /* restore syscall args.  */                    \
61     swi SYS_ify (syscall_name); /* do the call.  */                     \
62     str r0, [sp, $-4]!; /* save syscall return value.  */               \
63     mov r0, ip;         /* get mask back.  */                           \
64     CDISABLE;                                                           \
65     ldr r0, [sp], $4;   /* retrieve return value.  */                   \
66     UNDOC2ARGS_##args;  /* fix register damage.  */                     \
67     cmn r0, $4096;
68
69 # define DOCARGS_0
70 # define UNDOCARGS_0
71 # define UNDOC2ARGS_0
72
73 # define DOCARGS_1      str r0, [sp, #-4]!;
74 # define UNDOCARGS_1    ldr r0, [sp], #4;
75 # define UNDOC2ARGS_1
76
77 # define DOCARGS_2      str r1, [sp, #-4]!; str r0, [sp, #-4]!;
78 # define UNDOCARGS_2    ldr r0, [sp], #4; ldr r1, [sp], #4;
79 # define UNDOC2ARGS_2
80
81 # define DOCARGS_3      str r2, [sp, #-4]!; str r1, [sp, #-4]!; str r0, [sp, #-4]!;
82 # define UNDOCARGS_3    ldr r0, [sp], #4; ldr r1, [sp], #4; ldr r2, [sp], #4
83 # define UNDOC2ARGS_3
84
85 # define DOCARGS_4      stmfd sp!, {r0-r3}
86 # define UNDOCARGS_4    ldmfd sp!, {r0-r3}
87 # define UNDOC2ARGS_4
88
89 # define DOCARGS_5      stmfd sp!, {r0-r3}
90 # define UNDOCARGS_5    ldmfd sp, {r0-r3}; str r4, [sp, #-4]!; ldr r4, [sp, #24]
91 # define UNDOC2ARGS_5   ldr r4, [sp], #20
92
93 # ifdef IS_IN_libpthread
94 #  define CENABLE       bl PLTJMP(__pthread_enable_asynccancel)
95 #  define CDISABLE      bl PLTJMP(__pthread_disable_asynccancel)
96 #  define __local_multiple_threads __pthread_multiple_threads
97 # else
98 #  define CENABLE       bl PLTJMP(__libc_enable_asynccancel)
99 #  define CDISABLE      bl PLTJMP(__libc_disable_asynccancel)
100 #  define __local_multiple_threads __libc_multiple_threads
101 # endif
102
103 # ifndef __ASSEMBLER__
104 extern int __local_multiple_threads attribute_hidden;
105 #  define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
106 # else
107 #  if !defined __PIC__
108 #   define SINGLE_THREAD_P                                              \
109   ldr ip, =__local_multiple_threads;                                    \
110   ldr ip, [ip];                                                         \
111   teq ip, #0;
112 #   define PSEUDO_PROLOGUE
113 #  else
114 #   define SINGLE_THREAD_P                                              \
115   ldr ip, 1b;                                                           \
116 2:                                                                      \
117   ldr ip, [pc, ip];                                                     \
118   teq ip, #0;
119 #   define PSEUDO_PROLOGUE                                              \
120   1:  .word __local_multiple_threads - 2f - 8;
121 #  endif
122 # endif
123
124 #elif !defined __ASSEMBLER__
125
126 /* This code should never be used but we define it anyhow.  */
127 # define SINGLE_THREAD_P (1)
128
129 #endif