blob: 701310c1fc5e03b56b378666acbc2b19d03da161 [file] [log] [blame]
Christopher Ferris04954a42013-02-26 01:30:00 -08001/*
Christopher Ferris796cbe22013-04-08 18:35:30 -07002 * Copyright (C) 2013 The Android Open Source Project
Christopher Ferris04954a42013-02-26 01:30:00 -08003 * 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>
Elliott Hugheseb847bc2013-10-09 15:50:50 -070031#include "private/libc_events.h"
Christopher Ferris04954a42013-02-26 01:30:00 -080032
Christopher Ferris59a13c12013-08-01 13:13:33 -070033 /*
34 * Optimized memset() for ARM.
Christopher Ferris04954a42013-02-26 01:30:00 -080035 *
36 * memset() returns its first argument.
Christopher Ferris59a13c12013-08-01 13:13:33 -070037 */
Christopher Ferris04954a42013-02-26 01:30:00 -080038
Christopher Ferris796cbe22013-04-08 18:35:30 -070039 .fpu neon
40 .syntax unified
Christopher Ferris04954a42013-02-26 01:30:00 -080041
Christopher Ferris59a13c12013-08-01 13:13:33 -070042ENTRY(__memset_chk)
Christopher Ferris5f45d582013-08-07 13:09:51 -070043 .cfi_startproc
Christopher Ferris59a13c12013-08-01 13:13:33 -070044 cmp r2, r3
Christopher Ferris5f45d582013-08-07 13:09:51 -070045 bls .L_done
46
47 // Preserve lr for backtrace.
Christopher Ferrisbd7fe1d2013-08-20 11:20:48 -070048 .save {lr}
Christopher Ferris5f45d582013-08-07 13:09:51 -070049 push {lr}
50 .cfi_def_cfa_offset 4
51 .cfi_rel_offset lr, 0
Christopher Ferris59a13c12013-08-01 13:13:33 -070052
53 ldr r0, error_message
54 ldr r1, error_code
551:
56 add r0, pc
57 bl __fortify_chk_fail
58error_code:
59 .word BIONIC_EVENT_MEMSET_BUFFER_OVERFLOW
60error_message:
61 .word error_string-(1b+8)
62
Christopher Ferris5f45d582013-08-07 13:09:51 -070063 .cfi_endproc
Christopher Ferris59a13c12013-08-01 13:13:33 -070064END(__memset_chk)
65
Christopher Ferris04954a42013-02-26 01:30:00 -080066ENTRY(bzero)
Christopher Ferris5f45d582013-08-07 13:09:51 -070067 .cfi_startproc
Christopher Ferris796cbe22013-04-08 18:35:30 -070068 mov r2, r1
69 mov r1, #0
Christopher Ferris5f45d582013-08-07 13:09:51 -070070.L_done:
Christopher Ferris04954a42013-02-26 01:30:00 -080071 // Fall through to memset...
Christopher Ferris5f45d582013-08-07 13:09:51 -070072 .cfi_endproc
Christopher Ferris04954a42013-02-26 01:30:00 -080073END(bzero)
74
75ENTRY(memset)
Christopher Ferris5f45d582013-08-07 13:09:51 -070076 .cfi_startproc
Christopher Ferrisbd7fe1d2013-08-20 11:20:48 -070077 .save {r0}
Christopher Ferris04954a42013-02-26 01:30:00 -080078 stmfd sp!, {r0}
Christopher Ferris5f45d582013-08-07 13:09:51 -070079 .cfi_def_cfa_offset 4
80 .cfi_rel_offset r0, 0
Christopher Ferris04954a42013-02-26 01:30:00 -080081
Christopher Ferris796cbe22013-04-08 18:35:30 -070082 // The new algorithm is slower for copies < 16 so use the old
83 // neon code in that case.
Christopher Ferris04954a42013-02-26 01:30:00 -080084 cmp r2, #16
Christopher Ferris5f45d582013-08-07 13:09:51 -070085 blo .L_set_less_than_16_unknown_align
Christopher Ferris04954a42013-02-26 01:30:00 -080086
Christopher Ferris796cbe22013-04-08 18:35:30 -070087 // Use strd which requires an even and odd register so move the
88 // values so that:
89 // r0 and r1 contain the memset value
90 // r2 is the number of bytes to set
91 // r3 is the destination pointer
92 mov r3, r0
Christopher Ferris04954a42013-02-26 01:30:00 -080093
Christopher Ferris796cbe22013-04-08 18:35:30 -070094 // Copy the byte value in every byte of r1.
95 mov r1, r1, lsl #24
96 orr r1, r1, r1, lsr #8
97 orr r1, r1, r1, lsr #16
Christopher Ferris04954a42013-02-26 01:30:00 -080098
Christopher Ferris5f45d582013-08-07 13:09:51 -070099.L_check_alignment:
Christopher Ferris796cbe22013-04-08 18:35:30 -0700100 // Align destination to a double word to avoid the strd crossing
101 // a cache line boundary.
102 ands ip, r3, #7
Christopher Ferris5f45d582013-08-07 13:09:51 -0700103 bne .L_do_double_word_align
Christopher Ferris04954a42013-02-26 01:30:00 -0800104
Christopher Ferris5f45d582013-08-07 13:09:51 -0700105.L_double_word_aligned:
Christopher Ferris796cbe22013-04-08 18:35:30 -0700106 mov r0, r1
Christopher Ferris04954a42013-02-26 01:30:00 -0800107
Christopher Ferris796cbe22013-04-08 18:35:30 -0700108 subs r2, #64
Christopher Ferris5f45d582013-08-07 13:09:51 -0700109 blo .L_set_less_than_64
Christopher Ferris04954a42013-02-26 01:30:00 -0800110
Christopher Ferris796cbe22013-04-08 18:35:30 -07001111: // Main loop sets 64 bytes at a time.
112 .irp offset, #0, #8, #16, #24, #32, #40, #48, #56
113 strd r0, r1, [r3, \offset]
114 .endr
Christopher Ferris04954a42013-02-26 01:30:00 -0800115
Christopher Ferris796cbe22013-04-08 18:35:30 -0700116 add r3, #64
117 subs r2, #64
118 bge 1b
119
Christopher Ferris5f45d582013-08-07 13:09:51 -0700120.L_set_less_than_64:
Christopher Ferris796cbe22013-04-08 18:35:30 -0700121 // Restore r2 to the count of bytes left to set.
122 add r2, #64
123 lsls ip, r2, #27
Christopher Ferris5f45d582013-08-07 13:09:51 -0700124 bcc .L_set_less_than_32
Christopher Ferris796cbe22013-04-08 18:35:30 -0700125 // Set 32 bytes.
126 .irp offset, #0, #8, #16, #24
127 strd r0, r1, [r3, \offset]
128 .endr
129 add r3, #32
130
Christopher Ferris5f45d582013-08-07 13:09:51 -0700131.L_set_less_than_32:
132 bpl .L_set_less_than_16
Christopher Ferris796cbe22013-04-08 18:35:30 -0700133 // Set 16 bytes.
134 .irp offset, #0, #8
135 strd r0, r1, [r3, \offset]
136 .endr
137 add r3, #16
138
Christopher Ferris5f45d582013-08-07 13:09:51 -0700139.L_set_less_than_16:
Christopher Ferris796cbe22013-04-08 18:35:30 -0700140 // Less than 16 bytes to set.
141 lsls ip, r2, #29
Christopher Ferris5f45d582013-08-07 13:09:51 -0700142 bcc .L_set_less_than_8
Christopher Ferris796cbe22013-04-08 18:35:30 -0700143
144 // Set 8 bytes.
145 strd r0, r1, [r3], #8
146
Christopher Ferris5f45d582013-08-07 13:09:51 -0700147.L_set_less_than_8:
148 bpl .L_set_less_than_4
Christopher Ferris796cbe22013-04-08 18:35:30 -0700149 // Set 4 bytes
150 str r1, [r3], #4
151
Christopher Ferris5f45d582013-08-07 13:09:51 -0700152.L_set_less_than_4:
Christopher Ferris796cbe22013-04-08 18:35:30 -0700153 lsls ip, r2, #31
154 it ne
155 strbne r1, [r3], #1
156 itt cs
157 strbcs r1, [r3], #1
158 strbcs r1, [r3]
159
160 ldmfd sp!, {r0}
161 bx lr
162
Christopher Ferris5f45d582013-08-07 13:09:51 -0700163.L_do_double_word_align:
Christopher Ferris796cbe22013-04-08 18:35:30 -0700164 rsb ip, ip, #8
165 sub r2, r2, ip
166 movs r0, ip, lsl #31
167 it mi
168 strbmi r1, [r3], #1
169 itt cs
170 strbcs r1, [r3], #1
171 strbcs r1, [r3], #1
172
173 // Dst is at least word aligned by this point.
174 cmp ip, #4
Christopher Ferris5f45d582013-08-07 13:09:51 -0700175 blo .L_double_word_aligned
Christopher Ferris796cbe22013-04-08 18:35:30 -0700176 str r1, [r3], #4
Christopher Ferris5f45d582013-08-07 13:09:51 -0700177 b .L_double_word_aligned
Christopher Ferris796cbe22013-04-08 18:35:30 -0700178
Christopher Ferris5f45d582013-08-07 13:09:51 -0700179.L_set_less_than_16_unknown_align:
Christopher Ferris796cbe22013-04-08 18:35:30 -0700180 // Set up to 15 bytes.
181 vdup.8 d0, r1
Christopher Ferris04954a42013-02-26 01:30:00 -0800182 movs ip, r2, lsl #29
183 bcc 1f
184 vst1.8 {d0}, [r0]!
1851: bge 2f
186 vst1.32 {d0[0]}, [r0]!
1872: movs ip, r2, lsl #31
Christopher Ferris796cbe22013-04-08 18:35:30 -0700188 it mi
189 strbmi r1, [r0], #1
190 itt cs
191 strbcs r1, [r0], #1
192 strbcs r1, [r0], #1
Christopher Ferris04954a42013-02-26 01:30:00 -0800193 ldmfd sp!, {r0}
194 bx lr
Christopher Ferris5f45d582013-08-07 13:09:51 -0700195 .cfi_endproc
Christopher Ferris04954a42013-02-26 01:30:00 -0800196END(memset)
Christopher Ferris59a13c12013-08-01 13:13:33 -0700197
198 .data
199error_string:
Elliott Hughes68b67112013-10-15 17:17:05 -0700200 .string "memset: prevented write past end of buffer"