memset.S revision bd7fe1d3c4c8877ac53839169851621249289bd7
1/* 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> 31#include "libc_events.h" 32 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 40ENTRY(__memset_chk) 41 .cfi_startproc 42 cmp r2, r3 43 bls .L_done 44 45 // Preserve lr for backtrace. 46 .save {lr} 47 push {lr} 48 .cfi_def_cfa_offset 4 49 .cfi_rel_offset lr, 0 50 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 61 .cfi_endproc 62END(__memset_chk) 63 64ENTRY(bzero) 65 .cfi_startproc 66 mov r2, r1 67 mov r1, #0 68 69.L_done: 70 // Fall through to memset... 71 .cfi_endproc 72END(bzero) 73 74/* memset() returns its first argument. */ 75ENTRY(memset) 76 .cfi_startproc 77 # The neon memset only wins for less than 132. 78 cmp r2, #132 79 bhi 11f 80 81 .save {r0} 82 stmfd sp!, {r0} 83 .cfi_def_cfa_offset 4 84 .cfi_rel_offset r0, 0 85 86 vdup.8 q0, r1 87 88 /* make sure we have at least 32 bytes to write */ 89 subs r2, r2, #32 90 blo 2f 91 vmov q1, q0 92 931: /* The main loop writes 32 bytes at a time */ 94 subs r2, r2, #32 95 vst1.8 {d0 - d3}, [r0]! 96 bhs 1b 97 982: /* less than 32 left */ 99 add r2, r2, #32 100 tst r2, #0x10 101 beq 3f 102 103 // writes 16 bytes, 128-bits aligned 104 vst1.8 {d0, d1}, [r0]! 1053: /* write up to 15-bytes (count in r2) */ 106 movs ip, r2, lsl #29 107 bcc 1f 108 vst1.8 {d0}, [r0]! 1091: bge 2f 110 vst1.32 {d0[0]}, [r0]! 1112: movs ip, r2, lsl #31 112 strmib r1, [r0], #1 113 strcsb r1, [r0], #1 114 strcsb r1, [r0], #1 115 ldmfd sp!, {r0} 116 bx lr 11711: 118 /* compute the offset to align the destination 119 * offset = (4-(src&3))&3 = -src & 3 120 */ 121 122 .save {r0, r4-r7, lr} 123 stmfd sp!, {r0, r4-r7, lr} 124 .cfi_def_cfa_offset 24 125 .cfi_rel_offset r0, 0 126 .cfi_rel_offset r4, 4 127 .cfi_rel_offset r5, 8 128 .cfi_rel_offset r6, 12 129 .cfi_rel_offset r7, 16 130 .cfi_rel_offset lr, 20 131 132 rsb r3, r0, #0 133 ands r3, r3, #3 134 cmp r3, r2 135 movhi r3, r2 136 137 /* splat r1 */ 138 mov r1, r1, lsl #24 139 orr r1, r1, r1, lsr #8 140 orr r1, r1, r1, lsr #16 141 142 movs r12, r3, lsl #31 143 strcsb r1, [r0], #1 /* can't use strh (alignment unknown) */ 144 strcsb r1, [r0], #1 145 strmib r1, [r0], #1 146 subs r2, r2, r3 147 ldmlsfd sp!, {r0, r4-r7, lr} /* return */ 148 bxls lr 149 150 /* align the destination to a cache-line */ 151 mov r12, r1 152 mov lr, r1 153 mov r4, r1 154 mov r5, r1 155 mov r6, r1 156 mov r7, r1 157 158 rsb r3, r0, #0 159 ands r3, r3, #0x1C 160 beq 3f 161 cmp r3, r2 162 andhi r3, r2, #0x1C 163 sub r2, r2, r3 164 165 /* conditionally writes 0 to 7 words (length in r3) */ 166 movs r3, r3, lsl #28 167 stmcsia r0!, {r1, lr} 168 stmcsia r0!, {r1, lr} 169 stmmiia r0!, {r1, lr} 170 movs r3, r3, lsl #2 171 strcs r1, [r0], #4 172 1733: 174 subs r2, r2, #32 175 mov r3, r1 176 bmi 2f 1771: subs r2, r2, #32 178 stmia r0!, {r1,r3,r4,r5,r6,r7,r12,lr} 179 bhs 1b 1802: add r2, r2, #32 181 182 /* conditionally stores 0 to 31 bytes */ 183 movs r2, r2, lsl #28 184 stmcsia r0!, {r1,r3,r12,lr} 185 stmmiia r0!, {r1, lr} 186 movs r2, r2, lsl #2 187 strcs r1, [r0], #4 188 strmih r1, [r0], #2 189 movs r2, r2, lsl #2 190 strcsb r1, [r0] 191 ldmfd sp!, {r0, r4-r7, lr} 192 bx lr 193 .cfi_endproc 194END(memset) 195 196 .data 197error_string: 198 .string "memset buffer overflow" 199