OSDN Git Service

Replace FSF snail mail address with URLs
[uclinux-h8/uClibc.git] / libc / sysdeps / linux / arm / mmap64.S
1 /* Copyright (C) 2000 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
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.
8
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.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <http://www.gnu.org/licenses/>.  */
17
18 #include <_lfs_64.h>
19 #define _ERRNO_H
20 #include <bits/errno.h>
21 #include <sys/syscall.h>
22 #include <bits/arm_asm.h>
23
24 #ifdef __NR_mmap2
25
26 /* The mmap2 system call takes six arguments, all in registers.  */
27 .text
28 .global mmap64
29 .type mmap64,%function
30 .align 2
31
32 #ifdef __ARM_EABI__
33 #if defined(THUMB1_ONLY)
34 .thumb_func
35 mmap64:
36 #ifdef __ARMEB__
37 /* Offsets are after pushing 3 words.  */
38 # define LOW_OFFSET  12 + 8 + 4
39 # define HIGH_OFFSET 12 + 8 + 0
40 #else
41 # define LOW_OFFSET  12 + 8 + 0
42 # define HIGH_OFFSET 12 + 8 + 4
43 #endif
44         push    {r4, r5, r6}
45         ldr     r6, [sp, $LOW_OFFSET]
46         ldr     r5, [sp, $HIGH_OFFSET]
47         lsl     r4, r6, #20             @ check that offset is page-aligned
48         bne     .Linval
49         lsr     r4, r5, #12             @ check for overflow
50         bne     .Linval
51         @ compose page offset
52         lsr     r6, r6, #12
53         lsl     r5, r5, #20
54         orr     r5, r5, r6
55         ldr     r4, [sp, #8]            @ load fd
56         DO_CALL (mmap2)
57         ldr     r1, =0xfffff000
58         cmp     r0, r1
59         bcs     .Lerror
60         bx      lr
61 .Linval:
62         ldr     r0, =-EINVAL
63         pop     {r4, r5, r6}
64 .Lerror:
65         push    {r3, lr}
66         bl      __syscall_error
67         POP_RET
68 .pool
69 #else /* !THUMB1_ONLY */
70 mmap64:
71 #ifdef __ARMEB__
72 # define LOW_OFFSET      8 + 4
73 /* The initial + 4 is for the stack postdecrement.  */
74 # define HIGH_OFFSET 4 + 8 + 0
75 #else
76 # define LOW_OFFSET      8 + 0
77 # define HIGH_OFFSET 4 + 8 + 4
78 #endif
79         ldr     ip, [sp, $LOW_OFFSET]
80         str     r5, [sp, #-4]!
81         ldr     r5, [sp, $HIGH_OFFSET]
82         str     r4, [sp, #-4]!
83         movs    r4, ip, lsl $20         @ check that offset is page-aligned
84         mov     ip, ip, lsr $12
85         IT(t, eq)
86         moveqs  r4, r5, lsr $12         @ check for overflow
87         bne     .Linval
88         ldr     r4, [sp, $8]            @ load fd
89         orr     r5, ip, r5, lsl $20     @ compose page offset
90         DO_CALL (mmap2)
91         cmn     r0, $4096
92         ldmfd   sp!, {r4, r5}
93         IT(t, cc)
94 #if defined(__USE_BX__)
95         bxcc    lr
96 #else
97         movcc   pc, lr
98 #endif
99         b       __syscall_error
100 .Linval:
101         mov     r0, $-EINVAL
102         ldmfd   sp!, {r4, r5}
103         b       __syscall_error
104 #endif
105 #else /* !__ARM_EABI__ */
106 mmap64:
107         stmfd   sp!, {r4, r5, lr}
108         ldr     r5, [sp, $16]
109         ldr     r4, [sp, $12]
110         movs    ip, r5, lsl $20         @ check that offset is page-aligned
111         bne     .Linval
112         ldr     ip, [sp, $20]
113         mov     r5, r5, lsr $12
114         orr     r5, r5, ip, lsl $20     @ compose page offset
115         movs    ip, ip, lsr $12
116         bne     .Linval                 @ check for overflow
117         mov     ip, r0
118         DO_CALL (mmap2)
119         cmn     r0, $4096
120         ldmccfd sp!, {r4, r5, pc}
121         cmn     r0, $ENOSYS
122         ldmnefd sp!, {r4, r5, lr}
123         bne     __error
124         /* The current kernel does not support mmap2.  Fall back to plain
125            mmap if the offset is small enough.  */
126         ldr     r5, [sp, $20]
127         mov     r0, ip                  @ first arg was clobbered
128         teq     r5, $0
129         ldmeqfd sp!, {r4, r5, lr}
130         beq     HIDDEN_JUMPTARGET(mmap)
131 .Linval:
132         mov     r0, $-EINVAL
133         ldmfd   sp!, {r4, r5, lr}
134         b       __error
135
136 __error:
137         b       __syscall_error
138 #endif
139 .size mmap64,.-mmap64
140
141 #endif