blob: f6be66a035d24ae8141c21f481311cba2e6ff0a4 [file] [log] [blame]
Christopher Ferris7c83a1e2013-02-26 01:30:00 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <machine/cpu-features.h>
30#include <machine/asm.h>
Christopher Ferris59a13c12013-08-01 13:13:33 -070031#include "libc_events.h"
Christopher Ferris7c83a1e2013-02-26 01:30:00 -080032
33/*
34 * This code assumes it is running on a processor that supports all arm v7
35 * instructions and that supports neon instructions.
36 */
37
38 .fpu neon
39
Christopher Ferris59a13c12013-08-01 13:13:33 -070040ENTRY(__memset_chk)
Christopher Ferris5f45d582013-08-07 13:09:51 -070041 .cfi_startproc
Christopher Ferris59a13c12013-08-01 13:13:33 -070042 cmp r2, r3
Christopher Ferris5f45d582013-08-07 13:09:51 -070043 bls .L_done
44
45 // Preserve lr for backtrace.
46 push {lr}
Christopher Ferrisa57c9c02013-08-21 09:41:12 -070047 .save {lr}
Christopher Ferris5f45d582013-08-07 13:09:51 -070048 .cfi_def_cfa_offset 4
49 .cfi_rel_offset lr, 0
Christopher Ferris59a13c12013-08-01 13:13:33 -070050
51 ldr r0, error_message
52 ldr r1, error_code
531:
54 add r0, pc
55 bl __fortify_chk_fail
56error_code:
57 .word BIONIC_EVENT_MEMSET_BUFFER_OVERFLOW
58error_message:
59 .word error_string-(1b+8)
60
Christopher Ferris5f45d582013-08-07 13:09:51 -070061 .cfi_endproc
Christopher Ferris59a13c12013-08-01 13:13:33 -070062END(__memset_chk)
63
Christopher Ferris7c83a1e2013-02-26 01:30:00 -080064ENTRY(bzero)
Christopher Ferris5f45d582013-08-07 13:09:51 -070065 .cfi_startproc
Christopher Ferris7c83a1e2013-02-26 01:30:00 -080066 mov r2, r1
67 mov r1, #0
Christopher Ferris59a13c12013-08-01 13:13:33 -070068
Christopher Ferris5f45d582013-08-07 13:09:51 -070069.L_done:
Christopher Ferris59a13c12013-08-01 13:13:33 -070070 // Fall through to memset...
Christopher Ferris5f45d582013-08-07 13:09:51 -070071 .cfi_endproc
Christopher Ferris7c83a1e2013-02-26 01:30:00 -080072END(bzero)
73
74/* memset() returns its first argument. */
75ENTRY(memset)
Christopher Ferris5f45d582013-08-07 13:09:51 -070076 .cfi_startproc
Christopher Ferrisa57c9c02013-08-21 09:41:12 -070077
Christopher Ferris7c83a1e2013-02-26 01:30:00 -080078 # The neon memset only wins for less than 132.
79 cmp r2, #132
Christopher Ferrisa57c9c02013-08-21 09:41:12 -070080 bhi __memset_large_copy
Christopher Ferris7c83a1e2013-02-26 01:30:00 -080081
Christopher Ferris7c83a1e2013-02-26 01:30:00 -080082 stmfd sp!, {r0}
Christopher Ferrisa57c9c02013-08-21 09:41:12 -070083 .save {r0}
Christopher Ferris5f45d582013-08-07 13:09:51 -070084 .cfi_def_cfa_offset 4
85 .cfi_rel_offset r0, 0
Christopher Ferris7c83a1e2013-02-26 01:30:00 -080086
87 vdup.8 q0, r1
88
89 /* make sure we have at least 32 bytes to write */
90 subs r2, r2, #32
91 blo 2f
92 vmov q1, q0
93
941: /* The main loop writes 32 bytes at a time */
95 subs r2, r2, #32
96 vst1.8 {d0 - d3}, [r0]!
97 bhs 1b
98
992: /* less than 32 left */
100 add r2, r2, #32
101 tst r2, #0x10
102 beq 3f
103
104 // writes 16 bytes, 128-bits aligned
105 vst1.8 {d0, d1}, [r0]!
1063: /* write up to 15-bytes (count in r2) */
107 movs ip, r2, lsl #29
108 bcc 1f
109 vst1.8 {d0}, [r0]!
1101: bge 2f
111 vst1.32 {d0[0]}, [r0]!
1122: movs ip, r2, lsl #31
113 strmib r1, [r0], #1
114 strcsb r1, [r0], #1
115 strcsb r1, [r0], #1
116 ldmfd sp!, {r0}
117 bx lr
Christopher Ferrisa57c9c02013-08-21 09:41:12 -0700118
119 .cfi_endproc
120END(memset)
121
Nick Kralevich32bbf8a2013-10-02 16:54:58 -0700122ENTRY_PRIVATE(__memset_large_copy)
Christopher Ferrisa57c9c02013-08-21 09:41:12 -0700123 .cfi_startproc
124
Christopher Ferris7c83a1e2013-02-26 01:30:00 -0800125 /* compute the offset to align the destination
126 * offset = (4-(src&3))&3 = -src & 3
127 */
Christopher Ferris7c83a1e2013-02-26 01:30:00 -0800128 stmfd sp!, {r0, r4-r7, lr}
Christopher Ferrisa57c9c02013-08-21 09:41:12 -0700129 .save {r0, r4-r7, lr}
Christopher Ferris5f45d582013-08-07 13:09:51 -0700130 .cfi_def_cfa_offset 24
131 .cfi_rel_offset r0, 0
132 .cfi_rel_offset r4, 4
133 .cfi_rel_offset r5, 8
134 .cfi_rel_offset r6, 12
135 .cfi_rel_offset r7, 16
136 .cfi_rel_offset lr, 20
137
Christopher Ferris7c83a1e2013-02-26 01:30:00 -0800138 rsb r3, r0, #0
139 ands r3, r3, #3
140 cmp r3, r2
141 movhi r3, r2
142
143 /* splat r1 */
144 mov r1, r1, lsl #24
145 orr r1, r1, r1, lsr #8
146 orr r1, r1, r1, lsr #16
147
148 movs r12, r3, lsl #31
149 strcsb r1, [r0], #1 /* can't use strh (alignment unknown) */
150 strcsb r1, [r0], #1
151 strmib r1, [r0], #1
152 subs r2, r2, r3
153 ldmlsfd sp!, {r0, r4-r7, lr} /* return */
154 bxls lr
155
156 /* align the destination to a cache-line */
157 mov r12, r1
158 mov lr, r1
159 mov r4, r1
160 mov r5, r1
161 mov r6, r1
162 mov r7, r1
163
164 rsb r3, r0, #0
165 ands r3, r3, #0x1C
166 beq 3f
167 cmp r3, r2
168 andhi r3, r2, #0x1C
169 sub r2, r2, r3
170
171 /* conditionally writes 0 to 7 words (length in r3) */
172 movs r3, r3, lsl #28
173 stmcsia r0!, {r1, lr}
174 stmcsia r0!, {r1, lr}
175 stmmiia r0!, {r1, lr}
176 movs r3, r3, lsl #2
177 strcs r1, [r0], #4
178
1793:
180 subs r2, r2, #32
181 mov r3, r1
182 bmi 2f
1831: subs r2, r2, #32
184 stmia r0!, {r1,r3,r4,r5,r6,r7,r12,lr}
185 bhs 1b
1862: add r2, r2, #32
187
188 /* conditionally stores 0 to 31 bytes */
189 movs r2, r2, lsl #28
190 stmcsia r0!, {r1,r3,r12,lr}
191 stmmiia r0!, {r1, lr}
192 movs r2, r2, lsl #2
193 strcs r1, [r0], #4
194 strmih r1, [r0], #2
195 movs r2, r2, lsl #2
196 strcsb r1, [r0]
197 ldmfd sp!, {r0, r4-r7, lr}
198 bx lr
Christopher Ferris5f45d582013-08-07 13:09:51 -0700199 .cfi_endproc
Christopher Ferrisa57c9c02013-08-21 09:41:12 -0700200END(__memset_large_copy)
Christopher Ferris59a13c12013-08-01 13:13:33 -0700201
202 .data
203error_string:
204 .string "memset buffer overflow"