Home | History | Annotate | Line # | Download | only in string
memcpy.S revision 1.1.4.2
      1 /* $NetBSD: memcpy.S,v 1.1.4.2 2014/08/19 23:45:12 tls Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2014 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Matt Thomas of 3am Software Foundry.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include <machine/asm.h>
     33 
     34 RCSID("$NetBSD: memcpy.S,v 1.1.4.2 2014/08/19 23:45:12 tls Exp $")
     35 
     36 /* LINTSTUB: void *memcpy(void * restrict, const void * restrict, size_t); */
     37 
     38 ENTRY(memcpy)
     39 	mov	x10, x0
     40 	mov	x11, x1
     41 	cbz	x2, .Lmemcpy_ret
     42 
     43 	cmp	x2, #7
     44 	b.ls	.Lmemcpy_last_dword
     45 
     46 	ands	x3, x10, #7
     47 	b.eq	.Lmemcpy_dword_aligned
     48 
     49 /*
     50  * The dst address doesn't have dword alignment.  The src address may or may
     51  * not have the same alignment.  Make dst dword aligned.  Hope src will be
     52  * dword aligned but if it isn't, take advantage of unaligned access.
     53  */
     54 	add	x2, x2, x3		/* add unalignment to length */
     55 	sub	x2, x2, #8		/* now subtract a dword */
     56 
     57 	tbz	x10, #0, .Lmemcpy_hword_aligned
     58 	ldrb	w4, [x11], #1
     59 	strb	w4, [x10], #1
     60 .Lmemcpy_hword_aligned:
     61 	tbz	x10, #1, .Lmemcpy_word_aligned
     62 	ldrh	w4, [x11], #2
     63 	strh	w4, [x10], #2
     64 .Lmemcpy_word_aligned:
     65 	tbz	x10, #2, .Lmemcpy_dword_aligned
     66 	ldr	w4, [x11], #4
     67 	str	w4, [x10], #4
     68 .Lmemcpy_dword_aligned:
     69 	/*
     70 	 * destination is now dword aligned.
     71 	 */
     72 	subs	x2, x2, #32
     73 	b.mi	.Lmemcpy_last_oword
     74 
     75 .Lmemcpy_oword_loop:
     76 	ldp	x4, x5, [x11], #16
     77 	ldp	x6, x7, [x11], #16
     78 	stp	x4, x5, [x10], #16
     79 	stp	x6, x7, [x10], #16
     80 	cbz	x2, .Lmemcpy_ret
     81 	subs	x2, x2, #32
     82 	b.pl	.Lmemcpy_oword_loop
     83 
     84 .Lmemcpy_last_oword:
     85 	/*
     86 	 * We have 31 bytes or less to copy.  First see if we can write a qword
     87 	 */
     88 	tbz	x2, #4, .Lmemcpy_last_qword
     89 	ldp	x4, x5, [x11], #16		/* read word */
     90 	stp	x4, x5, [x10], #16		/* write word */
     91 
     92 .Lmemcpy_last_qword:
     93 	/*
     94 	 * We have 15 bytes or less to copy.  First see if we can write a dword
     95 	 */
     96 	tbz	x2, #3, .Lmemcpy_last_dword
     97 	ldr	x4, [x11], #8		/* read word */
     98 	str	x4, [x10], #8		/* write word */
     99 
    100 .Lmemcpy_last_dword:
    101 	/*
    102 	 * We have 7 bytes or less to copy.  First see if we can write a word
    103 	 */
    104 	tbz	x2, #2, .Lmemcpy_last_word
    105 	ldr	w4, [x11], #4		/* read word */
    106 	str	w4, [x10], #4		/* write word */
    107 
    108 .Lmemcpy_last_word:
    109 	/*
    110 	 * We have 3 bytes or less to copy.  First see if we can write a hword
    111 	 */
    112 	tbz	x2, #1, .Lmemcpy_last_hword
    113 	ldrh	w4, [x11], #2
    114 	strh	w4, [x10], #2
    115 
    116 .Lmemcpy_last_hword:
    117 	/*
    118 	 * We have 1 or none bytes to copy.
    119 	 */
    120 	tbz	x2, #0, .Lmemcpy_ret
    121 	ldrb	w4, [x11]
    122 	strb	w4, [x10]
    123 
    124 .Lmemcpy_ret:
    125 	ret
    126 END(memcpy)
    127