blob: 12c68d6a99174529de7733389089c59b76df426c [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>
Elliott Hughes851e68a2014-02-19 16:53:20 -080030#include <private/bionic_asm.h>
31#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)
43 cmp r2, r3
Christopher Ferris5f45d582013-08-07 13:09:51 -070044 bls .L_done
45
46 // Preserve lr for backtrace.
Christopher Ferrisbd7fe1d2013-08-20 11:20:48 -070047 .save {lr}
Christopher Ferris5f45d582013-08-07 13:09:51 -070048 push {lr}
49 .cfi_def_cfa_offset 4
50 .cfi_rel_offset lr, 0
Christopher Ferris59a13c12013-08-01 13:13:33 -070051
52 ldr r0, error_message
53 ldr r1, error_code
541:
55 add r0, pc
56 bl __fortify_chk_fail
57error_code:
58 .word BIONIC_EVENT_MEMSET_BUFFER_OVERFLOW
59error_message:
60 .word error_string-(1b+8)
Christopher Ferris59a13c12013-08-01 13:13:33 -070061END(__memset_chk)
62
Christopher Ferris04954a42013-02-26 01:30:00 -080063ENTRY(bzero)
Christopher Ferris796cbe22013-04-08 18:35:30 -070064 mov r2, r1
65 mov r1, #0
Christopher Ferris5f45d582013-08-07 13:09:51 -070066.L_done:
Christopher Ferris04954a42013-02-26 01:30:00 -080067 // Fall through to memset...
68END(bzero)
69
70ENTRY(memset)
Christopher Ferrisbd7fe1d2013-08-20 11:20:48 -070071 .save {r0}
Christopher Ferris04954a42013-02-26 01:30:00 -080072 stmfd sp!, {r0}
Christopher Ferris5f45d582013-08-07 13:09:51 -070073 .cfi_def_cfa_offset 4
74 .cfi_rel_offset r0, 0
Christopher Ferris04954a42013-02-26 01:30:00 -080075
Christopher Ferris796cbe22013-04-08 18:35:30 -070076 // The new algorithm is slower for copies < 16 so use the old
77 // neon code in that case.
Christopher Ferris04954a42013-02-26 01:30:00 -080078 cmp r2, #16
Christopher Ferris5f45d582013-08-07 13:09:51 -070079 blo .L_set_less_than_16_unknown_align
Christopher Ferris04954a42013-02-26 01:30:00 -080080
Christopher Ferris796cbe22013-04-08 18:35:30 -070081 // Use strd which requires an even and odd register so move the
82 // values so that:
83 // r0 and r1 contain the memset value
84 // r2 is the number of bytes to set
85 // r3 is the destination pointer
86 mov r3, r0
Christopher Ferris04954a42013-02-26 01:30:00 -080087
Christopher Ferris796cbe22013-04-08 18:35:30 -070088 // Copy the byte value in every byte of r1.
89 mov r1, r1, lsl #24
90 orr r1, r1, r1, lsr #8
91 orr r1, r1, r1, lsr #16
Christopher Ferris04954a42013-02-26 01:30:00 -080092
Christopher Ferris5f45d582013-08-07 13:09:51 -070093.L_check_alignment:
Christopher Ferris796cbe22013-04-08 18:35:30 -070094 // Align destination to a double word to avoid the strd crossing
95 // a cache line boundary.
96 ands ip, r3, #7
Christopher Ferris5f45d582013-08-07 13:09:51 -070097 bne .L_do_double_word_align
Christopher Ferris04954a42013-02-26 01:30:00 -080098
Christopher Ferris5f45d582013-08-07 13:09:51 -070099.L_double_word_aligned:
Christopher Ferris796cbe22013-04-08 18:35:30 -0700100 mov r0, r1
Christopher Ferris04954a42013-02-26 01:30:00 -0800101
Christopher Ferris796cbe22013-04-08 18:35:30 -0700102 subs r2, #64
Christopher Ferris5f45d582013-08-07 13:09:51 -0700103 blo .L_set_less_than_64
Christopher Ferris04954a42013-02-26 01:30:00 -0800104
Christopher Ferris796cbe22013-04-08 18:35:30 -07001051: // Main loop sets 64 bytes at a time.
106 .irp offset, #0, #8, #16, #24, #32, #40, #48, #56
107 strd r0, r1, [r3, \offset]
108 .endr
Christopher Ferris04954a42013-02-26 01:30:00 -0800109
Christopher Ferris796cbe22013-04-08 18:35:30 -0700110 add r3, #64
111 subs r2, #64
112 bge 1b
113
Christopher Ferris5f45d582013-08-07 13:09:51 -0700114.L_set_less_than_64:
Christopher Ferris796cbe22013-04-08 18:35:30 -0700115 // Restore r2 to the count of bytes left to set.
116 add r2, #64
117 lsls ip, r2, #27
Christopher Ferris5f45d582013-08-07 13:09:51 -0700118 bcc .L_set_less_than_32
Christopher Ferris796cbe22013-04-08 18:35:30 -0700119 // Set 32 bytes.
120 .irp offset, #0, #8, #16, #24
121 strd r0, r1, [r3, \offset]
122 .endr
123 add r3, #32
124
Christopher Ferris5f45d582013-08-07 13:09:51 -0700125.L_set_less_than_32:
126 bpl .L_set_less_than_16
Christopher Ferris796cbe22013-04-08 18:35:30 -0700127 // Set 16 bytes.
128 .irp offset, #0, #8
129 strd r0, r1, [r3, \offset]
130 .endr
131 add r3, #16
132
Christopher Ferris5f45d582013-08-07 13:09:51 -0700133.L_set_less_than_16:
Christopher Ferris796cbe22013-04-08 18:35:30 -0700134 // Less than 16 bytes to set.
135 lsls ip, r2, #29
Christopher Ferris5f45d582013-08-07 13:09:51 -0700136 bcc .L_set_less_than_8
Christopher Ferris796cbe22013-04-08 18:35:30 -0700137
138 // Set 8 bytes.
139 strd r0, r1, [r3], #8
140
Christopher Ferris5f45d582013-08-07 13:09:51 -0700141.L_set_less_than_8:
142 bpl .L_set_less_than_4
Christopher Ferris796cbe22013-04-08 18:35:30 -0700143 // Set 4 bytes
144 str r1, [r3], #4
145
Christopher Ferris5f45d582013-08-07 13:09:51 -0700146.L_set_less_than_4:
Christopher Ferris796cbe22013-04-08 18:35:30 -0700147 lsls ip, r2, #31
148 it ne
149 strbne r1, [r3], #1
150 itt cs
151 strbcs r1, [r3], #1
152 strbcs r1, [r3]
153
154 ldmfd sp!, {r0}
155 bx lr
156
Christopher Ferris5f45d582013-08-07 13:09:51 -0700157.L_do_double_word_align:
Christopher Ferris796cbe22013-04-08 18:35:30 -0700158 rsb ip, ip, #8
159 sub r2, r2, ip
160 movs r0, ip, lsl #31
161 it mi
162 strbmi r1, [r3], #1
163 itt cs
164 strbcs r1, [r3], #1
165 strbcs r1, [r3], #1
166
167 // Dst is at least word aligned by this point.
168 cmp ip, #4
Christopher Ferris5f45d582013-08-07 13:09:51 -0700169 blo .L_double_word_aligned
Christopher Ferris796cbe22013-04-08 18:35:30 -0700170 str r1, [r3], #4
Christopher Ferris5f45d582013-08-07 13:09:51 -0700171 b .L_double_word_aligned
Christopher Ferris796cbe22013-04-08 18:35:30 -0700172
Christopher Ferris5f45d582013-08-07 13:09:51 -0700173.L_set_less_than_16_unknown_align:
Christopher Ferris796cbe22013-04-08 18:35:30 -0700174 // Set up to 15 bytes.
175 vdup.8 d0, r1
Christopher Ferris04954a42013-02-26 01:30:00 -0800176 movs ip, r2, lsl #29
177 bcc 1f
178 vst1.8 {d0}, [r0]!
1791: bge 2f
180 vst1.32 {d0[0]}, [r0]!
1812: movs ip, r2, lsl #31
Christopher Ferris796cbe22013-04-08 18:35:30 -0700182 it mi
183 strbmi r1, [r0], #1
184 itt cs
185 strbcs r1, [r0], #1
186 strbcs r1, [r0], #1
Christopher Ferris04954a42013-02-26 01:30:00 -0800187 ldmfd sp!, {r0}
188 bx lr
189END(memset)
Christopher Ferris59a13c12013-08-01 13:13:33 -0700190
191 .data
192error_string:
Elliott Hughes68b67112013-10-15 17:17:05 -0700193 .string "memset: prevented write past end of buffer"