Add stpcpy assembler version.

For generic, continue to use the C version of the code.

Bug: 13746695

(cherry picked from commit 7d849ac378515efa1522e538e6e1d3b546cae97d)

Change-Id: Iae44785f37f9bb59103ab78fb9f74c92f8a95c7f
diff --git a/libc/arch-arm/cortex-a15/bionic/strcpy.S b/libc/arch-arm/cortex-a15/bionic/strcpy.S
index 2cfdb19..951face 100644
--- a/libc/arch-arm/cortex-a15/bionic/strcpy.S
+++ b/libc/arch-arm/cortex-a15/bionic/strcpy.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2014 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,432 +25,6 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-/*
- * Copyright (c) 2013 ARM Ltd
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the company may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
 
-#include <private/bionic_asm.h>
-
-    .syntax unified
-
-    .thumb
-    .thumb_func
-
-    .macro m_push
-    push    {r0, r4, r5, lr}
-    .cfi_def_cfa_offset 16
-    .cfi_rel_offset r0, 0
-    .cfi_rel_offset r4, 4
-    .cfi_rel_offset r5, 8
-    .cfi_rel_offset lr, 12
-    .endm // m_push
-
-    .macro m_pop
-    pop     {r0, r4, r5, pc}
-    .endm // m_pop
-
-    .macro m_copy_byte reg, cmd, label
-    ldrb    \reg, [r1], #1
-    strb    \reg, [r0], #1
-    \cmd    \reg, \label
-    .endm // m_copy_byte
-
-ENTRY(strcpy)
-    // For short copies, hard-code checking the first 8 bytes since this
-    // new code doesn't win until after about 8 bytes.
-    m_push
-    m_copy_byte reg=r2, cmd=cbz, label=.Lstrcpy_finish
-    m_copy_byte reg=r3, cmd=cbz, label=.Lstrcpy_finish
-    m_copy_byte reg=r4, cmd=cbz, label=.Lstrcpy_finish
-    m_copy_byte reg=r5, cmd=cbz, label=.Lstrcpy_finish
-    m_copy_byte reg=r2, cmd=cbz, label=.Lstrcpy_finish
-    m_copy_byte reg=r3, cmd=cbz, label=.Lstrcpy_finish
-    m_copy_byte reg=r4, cmd=cbz, label=.Lstrcpy_finish
-    m_copy_byte reg=r5, cmd=cbnz, label=.Lstrcpy_continue
-
-.Lstrcpy_finish:
-    m_pop
-
-.Lstrcpy_continue:
-    pld     [r1, #0]
-    ands    r3, r0, #7
-    beq     .Lstrcpy_check_src_align
-
-    // Align to a double word (64 bits).
-    rsb     r3, r3, #8
-    lsls    ip, r3, #31
-    beq     .Lstrcpy_align_to_32
-
-    ldrb    r2, [r1], #1
-    strb    r2, [r0], #1
-    cbz     r2, .Lstrcpy_complete
-
-.Lstrcpy_align_to_32:
-    bcc     .Lstrcpy_align_to_64
-
-    ldrb    r2, [r1], #1
-    strb    r2, [r0], #1
-    cbz     r2, .Lstrcpy_complete
-    ldrb    r2, [r1], #1
-    strb    r2, [r0], #1
-    cbz     r2, .Lstrcpy_complete
-
-.Lstrcpy_align_to_64:
-    tst     r3, #4
-    beq     .Lstrcpy_check_src_align
-    ldr     r2, [r1], #4
-
-    sub     ip, r2, #0x01010101
-    bic     ip, ip, r2
-    ands    ip, ip, #0x80808080
-    bne     .Lstrcpy_zero_in_first_register
-    str     r2, [r0], #4
-
-.Lstrcpy_check_src_align:
-    // At this point dst is aligned to a double word, check if src
-    // is also aligned to a double word.
-    ands    r3, r1, #7
-    bne     .Lstrcpy_unaligned_copy
-
-    .p2align 2
-.Lstrcpy_mainloop:
-    ldrd    r2, r3, [r1], #8
-
-    pld     [r1, #64]
-
-    sub     ip, r2, #0x01010101
-    bic     ip, ip, r2
-    ands    ip, ip, #0x80808080
-    bne     .Lstrcpy_zero_in_first_register
-
-    sub     ip, r3, #0x01010101
-    bic     ip, ip, r3
-    ands    ip, ip, #0x80808080
-    bne     .Lstrcpy_zero_in_second_register
-
-    strd    r2, r3, [r0], #8
-    b       .Lstrcpy_mainloop
-
-.Lstrcpy_complete:
-    m_pop
-
-.Lstrcpy_zero_in_first_register:
-    lsls    lr, ip, #17
-    bne     .Lstrcpy_copy1byte
-    bcs     .Lstrcpy_copy2bytes
-    lsls    ip, ip, #1
-    bne     .Lstrcpy_copy3bytes
-
-.Lstrcpy_copy4bytes:
-    // Copy 4 bytes to the destiniation.
-    str     r2, [r0]
-    m_pop
-
-.Lstrcpy_copy1byte:
-    strb    r2, [r0]
-    m_pop
-
-.Lstrcpy_copy2bytes:
-    strh    r2, [r0]
-    m_pop
-
-.Lstrcpy_copy3bytes:
-    strh    r2, [r0], #2
-    lsr     r2, #16
-    strb    r2, [r0]
-    m_pop
-
-.Lstrcpy_zero_in_second_register:
-    lsls    lr, ip, #17
-    bne     .Lstrcpy_copy5bytes
-    bcs     .Lstrcpy_copy6bytes
-    lsls    ip, ip, #1
-    bne     .Lstrcpy_copy7bytes
-
-    // Copy 8 bytes to the destination.
-    strd    r2, r3, [r0]
-    m_pop
-
-.Lstrcpy_copy5bytes:
-    str     r2, [r0], #4
-    strb    r3, [r0]
-    m_pop
-
-.Lstrcpy_copy6bytes:
-    str     r2, [r0], #4
-    strh    r3, [r0]
-    m_pop
-
-.Lstrcpy_copy7bytes:
-    str     r2, [r0], #4
-    strh    r3, [r0], #2
-    lsr     r3, #16
-    strb    r3, [r0]
-    m_pop
-
-.Lstrcpy_unaligned_copy:
-    // Dst is aligned to a double word, while src is at an unknown alignment.
-    // There are 7 different versions of the unaligned copy code
-    // to prevent overreading the src. The mainloop of every single version
-    // will store 64 bits per loop. The difference is how much of src can
-    // be read without potentially crossing a page boundary.
-    tbb     [pc, r3]
-.Lstrcpy_unaligned_branchtable:
-    .byte 0
-    .byte ((.Lstrcpy_unalign7 - .Lstrcpy_unaligned_branchtable)/2)
-    .byte ((.Lstrcpy_unalign6 - .Lstrcpy_unaligned_branchtable)/2)
-    .byte ((.Lstrcpy_unalign5 - .Lstrcpy_unaligned_branchtable)/2)
-    .byte ((.Lstrcpy_unalign4 - .Lstrcpy_unaligned_branchtable)/2)
-    .byte ((.Lstrcpy_unalign3 - .Lstrcpy_unaligned_branchtable)/2)
-    .byte ((.Lstrcpy_unalign2 - .Lstrcpy_unaligned_branchtable)/2)
-    .byte ((.Lstrcpy_unalign1 - .Lstrcpy_unaligned_branchtable)/2)
-
-    .p2align 2
-    // Can read 7 bytes before possibly crossing a page.
-.Lstrcpy_unalign7:
-    ldr     r2, [r1], #4
-
-    sub     ip, r2, #0x01010101
-    bic     ip, ip, r2
-    ands    ip, ip, #0x80808080
-    bne     .Lstrcpy_zero_in_first_register
-
-    ldrb    r3, [r1]
-    cbz     r3, .Lstrcpy_unalign7_copy5bytes
-    ldrb    r4, [r1, #1]
-    cbz     r4, .Lstrcpy_unalign7_copy6bytes
-    ldrb    r5, [r1, #2]
-    cbz     r5, .Lstrcpy_unalign7_copy7bytes
-
-    ldr     r3, [r1], #4
-    pld     [r1, #64]
-
-    lsrs    ip, r3, #24
-    strd    r2, r3, [r0], #8
-    beq     .Lstrcpy_unalign_return
-    b       .Lstrcpy_unalign7
-
-.Lstrcpy_unalign7_copy5bytes:
-    str     r2, [r0], #4
-    strb    r3, [r0]
-.Lstrcpy_unalign_return:
-    m_pop
-
-.Lstrcpy_unalign7_copy6bytes:
-    str     r2, [r0], #4
-    strb    r3, [r0], #1
-    strb    r4, [r0], #1
-    m_pop
-
-.Lstrcpy_unalign7_copy7bytes:
-    str     r2, [r0], #4
-    strb    r3, [r0], #1
-    strb    r4, [r0], #1
-    strb    r5, [r0], #1
-    m_pop
-
-    .p2align 2
-    // Can read 6 bytes before possibly crossing a page.
-.Lstrcpy_unalign6:
-    ldr     r2, [r1], #4
-
-    sub     ip, r2, #0x01010101
-    bic     ip, ip, r2
-    ands    ip, ip, #0x80808080
-    bne     .Lstrcpy_zero_in_first_register
-
-    ldrb    r4, [r1]
-    cbz     r4, .Lstrcpy_unalign_copy5bytes
-    ldrb    r5, [r1, #1]
-    cbz     r5, .Lstrcpy_unalign_copy6bytes
-
-    ldr     r3, [r1], #4
-    pld     [r1, #64]
-
-    tst     r3, #0xff0000
-    beq     .Lstrcpy_copy7bytes
-    lsrs    ip, r3, #24
-    strd    r2, r3, [r0], #8
-    beq     .Lstrcpy_unalign_return
-    b       .Lstrcpy_unalign6
-
-    .p2align 2
-    // Can read 5 bytes before possibly crossing a page.
-.Lstrcpy_unalign5:
-    ldr     r2, [r1], #4
-
-    sub     ip, r2, #0x01010101
-    bic     ip, ip, r2
-    ands    ip, ip, #0x80808080
-    bne     .Lstrcpy_zero_in_first_register
-
-    ldrb    r4, [r1]
-    cbz     r4, .Lstrcpy_unalign_copy5bytes
-
-    ldr     r3, [r1], #4
-
-    pld     [r1, #64]
-
-    sub     ip, r3, #0x01010101
-    bic     ip, ip, r3
-    ands    ip, ip, #0x80808080
-    bne     .Lstrcpy_zero_in_second_register
-
-    strd    r2, r3, [r0], #8
-    b       .Lstrcpy_unalign5
-
-.Lstrcpy_unalign_copy5bytes:
-    str     r2, [r0], #4
-    strb    r4, [r0]
-    m_pop
-
-.Lstrcpy_unalign_copy6bytes:
-    str     r2, [r0], #4
-    strb    r4, [r0], #1
-    strb    r5, [r0]
-    m_pop
-
-    .p2align 2
-    // Can read 4 bytes before possibly crossing a page.
-.Lstrcpy_unalign4:
-    ldr     r2, [r1], #4
-
-    sub     ip, r2, #0x01010101
-    bic     ip, ip, r2
-    ands    ip, ip, #0x80808080
-    bne     .Lstrcpy_zero_in_first_register
-
-    ldr     r3, [r1], #4
-    pld     [r1, #64]
-
-    sub     ip, r3, #0x01010101
-    bic     ip, ip, r3
-    ands    ip, ip, #0x80808080
-    bne     .Lstrcpy_zero_in_second_register
-
-    strd    r2, r3, [r0], #8
-    b       .Lstrcpy_unalign4
-
-    .p2align 2
-    // Can read 3 bytes before possibly crossing a page.
-.Lstrcpy_unalign3:
-    ldrb    r2, [r1]
-    cbz     r2, .Lstrcpy_unalign3_copy1byte
-    ldrb    r3, [r1, #1]
-    cbz     r3, .Lstrcpy_unalign3_copy2bytes
-    ldrb    r4, [r1, #2]
-    cbz     r4, .Lstrcpy_unalign3_copy3bytes
-
-    ldr     r2, [r1], #4
-    ldr     r3, [r1], #4
-
-    pld     [r1, #64]
-
-    lsrs    lr, r2, #24
-    beq     .Lstrcpy_copy4bytes
-
-    sub     ip, r3, #0x01010101
-    bic     ip, ip, r3
-    ands    ip, ip, #0x80808080
-    bne     .Lstrcpy_zero_in_second_register
-
-    strd    r2, r3, [r0], #8
-    b       .Lstrcpy_unalign3
-
-.Lstrcpy_unalign3_copy1byte:
-    strb    r2, [r0]
-    m_pop
-
-.Lstrcpy_unalign3_copy2bytes:
-    strb    r2, [r0], #1
-    strb    r3, [r0]
-    m_pop
-
-.Lstrcpy_unalign3_copy3bytes:
-    strb    r2, [r0], #1
-    strb    r3, [r0], #1
-    strb    r4, [r0]
-    m_pop
-
-    .p2align 2
-    // Can read 2 bytes before possibly crossing a page.
-.Lstrcpy_unalign2:
-    ldrb    r2, [r1]
-    cbz     r2, .Lstrcpy_unalign_copy1byte
-    ldrb    r4, [r1, #1]
-    cbz     r4, .Lstrcpy_unalign_copy2bytes
-
-    ldr     r2, [r1], #4
-    ldr     r3, [r1], #4
-    pld     [r1, #64]
-
-    tst     r2, #0xff0000
-    beq     .Lstrcpy_copy3bytes
-    lsrs    ip, r2, #24
-    beq     .Lstrcpy_copy4bytes
-
-    sub     ip, r3, #0x01010101
-    bic     ip, ip, r3
-    ands    ip, ip, #0x80808080
-    bne     .Lstrcpy_zero_in_second_register
-
-    strd    r2, r3, [r0], #8
-    b       .Lstrcpy_unalign2
-
-    .p2align 2
-    // Can read 1 byte before possibly crossing a page.
-.Lstrcpy_unalign1:
-    ldrb    r2, [r1]
-    cbz     r2, .Lstrcpy_unalign_copy1byte
-
-    ldr     r2, [r1], #4
-    ldr     r3, [r1], #4
-
-    pld     [r1, #64]
-
-    sub     ip, r2, #0x01010101
-    bic     ip, ip, r2
-    ands    ip, ip, #0x80808080
-    bne     .Lstrcpy_zero_in_first_register
-
-    sub     ip, r3, #0x01010101
-    bic     ip, ip, r3
-    ands    ip, ip, #0x80808080
-    bne     .Lstrcpy_zero_in_second_register
-
-    strd    r2, r3, [r0], #8
-    b       .Lstrcpy_unalign1
-
-.Lstrcpy_unalign_copy1byte:
-    strb    r2, [r0]
-    m_pop
-
-.Lstrcpy_unalign_copy2bytes:
-    strb    r2, [r0], #1
-    strb    r4, [r0]
-    m_pop
-END(strcpy)
+#define STRCPY
+#include "string_copy.S"