(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
[glibc.git] / sysdeps / unix / sysv / linux / sh / socket.S
blobf1369eb49bebf06685918843dca97fe159123fcb
1 /* Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
19 #include <sysdep-cancel.h>
20 #include <socketcall.h>
21 #include <tls.h>
23 #define P(a, b) P2(a, b)
24 #define P2(a, b) a##b
26         .text
27 /* The socket-oriented system calls are handled unusally in Linux.
28    They are all gated through the single `socketcall' system call number.
29    `socketcall' takes two arguments: the first is the subcode, specifying
30    which socket function is being called; and the second is a pointer to
31    the arguments to the specific function.
33    The .S files for the other calls just #define socket and #include this.  */
35 #ifndef __socket
36 #define __socket P(__,socket)
37 #endif
39 #define PUSHARGS_1      mov.l r4,@-r15; \
40                         cfi_adjust_cfa_offset (4); \
41                         cfi_rel_offset (r4, 0)
42 #define PUSHARGS_2      mov.l r5,@-r15; \
43                         cfi_adjust_cfa_offset (4); \
44                         cfi_rel_offset (r5, 0); \
45                         PUSHARGS_1
46 #define PUSHARGS_3      mov.l r6,@-r15; \
47                         cfi_adjust_cfa_offset (4); \
48                         cfi_rel_offset (r6, 0); \
49                         PUSHARGS_2
50 #define PUSHARGS_4      mov.l r7,@-r15; \
51                         cfi_adjust_cfa_offset (4); \
52                         cfi_rel_offset (r7, 0); \
53                         PUSHARGS_3
54 #define PUSHARGS_5      PUSHARGS_4      /* Caller has already pushed arg 5 */
55 #define PUSHARGS_6      PUSHARGS_4      /* Caller has already pushed arg 5,6 */
57 #define POPARGS_1       add #4,r15; cfi_adjust_cfa_offset (-4)
58 #define POPARGS_2       add #8,r15; cfi_adjust_cfa_offset (-8)
59 #define POPARGS_3       add #12,r15; cfi_adjust_cfa_offset (-12)
60 #define POPARGS_4       add #16,r15; cfi_adjust_cfa_offset (-16)
61 #define POPARGS_5       POPARGS_4
62 #define POPARGS_6       POPARGS_4
64 #define ADJUSTCFI_1     cfi_adjust_cfa_offset (4); \
65                         cfi_offset (r4, -4)
66 #define ADJUSTCFI_2     cfi_adjust_cfa_offset (8); \
67                         cfi_offset (r4, -4); \
68                         cfi_offset (r5, -8)
69 #define ADJUSTCFI_3     cfi_adjust_cfa_offset (12); \
70                         cfi_offset (r4, -4); \
71                         cfi_offset (r5, -8); \
72                         cfi_offset (r6, -12)
73 #define ADJUSTCFI_4     cfi_adjust_cfa_offset (16); \
74                         cfi_offset (r4, -4); \
75                         cfi_offset (r5, -8); \
76                         cfi_offset (r6, -12); \
77                         cfi_offset (r7, -16)
78 #define ADJUSTCFI_5     ADJUSTCFI_4
79 #define ADJUSTCFI_6     ADJUSTCFI_4
81 #ifndef NARGS
82 /* If we were called with no wrapper, this is really socket().  */
83 #define NARGS 3
84 #endif
86 .globl __socket
87         cfi_startproc
88 ENTRY (__socket)
89         /* This will not work in the case of a socket call being interrupted
90            by a signal.  If the signal handler uses any stack the arguments
91            to socket will be trashed.  The results of a restart of any
92            socket call are then unpredictable.  */
94         /* Push args onto the stack.  */
95         P(PUSHARGS_,NARGS)
97 #if defined NEED_CANCELLATION && defined CENABLE
98         SINGLE_THREAD_P
99         bf .Lsocket_cancel
100 #endif
102         /* Do the system call trap.  */
103         mov #+P(SOCKOP_,socket), r4
104         mov r15, r5
105         mov.l .L1,r3
106         trapa #0x12
108         /* Pop args off the stack */
109         P(POPARGS_,NARGS)
111         mov     r0, r1
112         mov     #-12, r2
113         shad    r2, r1
114         not     r1, r1                  // r1=0 means r0 = -1 to -4095
115         tst     r1, r1                  // i.e. error in linux
116         bf      .Lpseudo_end
117 .Lsyscall_error:
118         SYSCALL_ERROR_HANDLER
119 .Lpseudo_end:
120         /* Successful; return the syscall's value.  */
121         rts
122          nop
124 #if defined NEED_CANCELLATION && defined CENABLE
125 .Lsocket_cancel:
126         /* Enable asynchronous cancellation.  */
127         P(ADJUSTCFI_,NARGS)
128         sts.l pr,@-r15
129         cfi_adjust_cfa_offset (4)
130         cfi_rel_offset (pr, 0)
131         CENABLE
132         lds.l @r15+,pr
133         cfi_adjust_cfa_offset (-4)
134         cfi_restore (pr)
136         /* Do the system call trap.  */
137         mov #+P(SOCKOP_,socket), r4
138         mov r15, r5
139         mov.l .L1,r3
140         trapa #0x12
142         sts.l pr,@-r15
143         cfi_adjust_cfa_offset (4)
144         cfi_rel_offset (pr, 0)
145         mov.l r0,@-r15
146         cfi_adjust_cfa_offset (4)
147         cfi_rel_offset (r0, 0)
148         CDISABLE
149         mov.l @r15+,r0
150         cfi_adjust_cfa_offset (-4)
151         cfi_restore (r0)
152         lds.l @r15+,pr
153         cfi_adjust_cfa_offset (-4)
154         cfi_restore (pr)
156         /* Pop args off the stack */
157         P(POPARGS_,NARGS)
159         mov     r0, r1
160         mov     #-12, r2
161         shad    r2, r1
162         not     r1, r1                  // r1=0 means r0 = -1 to -4095
163         tst     r1, r1                  // i.e. error in linux
164         bf      .Lpseudo_end
165         bra     .Lsyscall_error
166          nop
167 #endif
168         cfi_endproc
170         .align 2
171 .L1:
172         .long   SYS_ify(socketcall)
174 PSEUDO_END (__socket)
176 weak_alias (__socket, socket)