OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [newlib-1.17.0/] [newlib/] [libc/] [machine/] [m68k/] [memcpy.S] - Diff between revs 148 and 158

Only display areas with differences | Details | Blame | View Log

Rev 148 Rev 158
/* a-memcpy.s -- memcpy, optimised for m68k asm
/* a-memcpy.s -- memcpy, optimised for m68k asm
 *
 *
 * Copyright (c) 2007 mocom software GmbH & Co KG)
 * Copyright (c) 2007 mocom software GmbH & Co KG)
 *
 *
 * The authors hereby grant permission to use, copy, modify, distribute,
 * The authors hereby grant permission to use, copy, modify, distribute,
 * and license this software and its documentation for any purpose, provided
 * and license this software and its documentation for any purpose, provided
 * that existing copyright notices are retained in all copies and that this
 * that existing copyright notices are retained in all copies and that this
 * notice is included verbatim in any distributions. No written agreement,
 * notice is included verbatim in any distributions. No written agreement,
 * license, or royalty fee is required for any of the authorized uses.
 * license, or royalty fee is required for any of the authorized uses.
 * Modifications to this software may be copyrighted by their authors
 * Modifications to this software may be copyrighted by their authors
 * and need not follow the licensing terms described here, provided that
 * and need not follow the licensing terms described here, provided that
 * the new terms are clearly indicated on the first page of each file where
 * the new terms are clearly indicated on the first page of each file where
 * they apply.
 * they apply.
 */
 */
#include "m68kasm.h"
#include "m68kasm.h"
        .text
        .text
        .align  4
        .align  4
        .globl  SYM(memcpy)
        .globl  SYM(memcpy)
        .type   SYM(memcpy), @function
        .type   SYM(memcpy), @function
/*   memcpy, optimised
/*   memcpy, optimised
 *
 *
 *   strategy:
 *   strategy:
 *       - no argument testing (the original memcpy from the GNU lib does
 *       - no argument testing (the original memcpy from the GNU lib does
 *         no checking either)
 *         no checking either)
 *       - make sure the destination pointer (the write pointer) is long word
 *       - make sure the destination pointer (the write pointer) is long word
 *         aligned. This is the best you can do, because writing to unaligned
 *         aligned. This is the best you can do, because writing to unaligned
 *         addresses can be the most costfull thing you could do.
 *         addresses can be the most costfull thing you could do.
 *       - Once you have figured that out, we do a little loop unrolling
 *       - Once you have figured that out, we do a little loop unrolling
 *         to further improve speed.
 *         to further improve speed.
 */
 */
SYM(memcpy):
SYM(memcpy):
        move.l  4(sp),a0        | dest ptr
        move.l  4(sp),a0        | dest ptr
        move.l  8(sp),a1        | src ptr
        move.l  8(sp),a1        | src ptr
        move.l  12(sp),d1       | len
        move.l  12(sp),d1       | len
        cmp.l   #8,d1           | if fewer than 8 bytes to transfer,
        cmp.l   #8,d1           | if fewer than 8 bytes to transfer,
        blo     .Lresidue       | do not optimise
        blo     .Lresidue       | do not optimise
        /* align dest */
        /* align dest */
        move.l  a0,d0           | copy of dest
        move.l  a0,d0           | copy of dest
        neg.l   d0
        neg.l   d0
        and.l   #3,d0           | look for the lower two only
        and.l   #3,d0           | look for the lower two only
        beq     2f              | is aligned?
        beq     2f              | is aligned?
        sub.l   d0,d1
        sub.l   d0,d1
        lsr.l   #1,d0           | word align needed?
        lsr.l   #1,d0           | word align needed?
        bcc     1f
        bcc     1f
        move.b  (a1)+,(a0)+
        move.b  (a1)+,(a0)+
1:
1:
        lsr.l   #1,d0           | long align needed?
        lsr.l   #1,d0           | long align needed?
        bcc     2f
        bcc     2f
        move.w  (a1)+,(a0)+
        move.w  (a1)+,(a0)+
2:
2:
        /* long word transfers */
        /* long word transfers */
        move.l  d1,d0
        move.l  d1,d0
        and.l   #3,d1           | byte residue
        and.l   #3,d1           | byte residue
        lsr.l   #3,d0
        lsr.l   #3,d0
        bcc     1f              | carry set for 4-byte residue
        bcc     1f              | carry set for 4-byte residue
        move.l  (a1)+,(a0)+
        move.l  (a1)+,(a0)+
1:
1:
        lsr.l   #1,d0           | number of 16-byte transfers
        lsr.l   #1,d0           | number of 16-byte transfers
        bcc     .Lcopy          | carry set for 8-byte residue
        bcc     .Lcopy          | carry set for 8-byte residue
        bra     .Lcopy8
        bra     .Lcopy8
1:
1:
        move.l  (a1)+,(a0)+
        move.l  (a1)+,(a0)+
        move.l  (a1)+,(a0)+
        move.l  (a1)+,(a0)+
.Lcopy8:
.Lcopy8:
        move.l  (a1)+,(a0)+
        move.l  (a1)+,(a0)+
        move.l  (a1)+,(a0)+
        move.l  (a1)+,(a0)+
.Lcopy:
.Lcopy:
#if !defined (__mcoldfire__)
#if !defined (__mcoldfire__)
        dbra    d0,1b
        dbra    d0,1b
        sub.l   #0x10000,d0
        sub.l   #0x10000,d0
#else
#else
        subq.l  #1,d0
        subq.l  #1,d0
#endif
#endif
        bpl     1b
        bpl     1b
        bra     .Lresidue
        bra     .Lresidue
1:
1:
        move.b  (a1)+,(a0)+     | move residue bytes
        move.b  (a1)+,(a0)+     | move residue bytes
.Lresidue:
.Lresidue:
#if !defined (__mcoldfire__)
#if !defined (__mcoldfire__)
        dbra    d1,1b           | loop until done
        dbra    d1,1b           | loop until done
#else
#else
        subq.l  #1,d1
        subq.l  #1,d1
        bpl     1b
        bpl     1b
#endif
#endif
        move.l  4(sp),d0        | return value
        move.l  4(sp),d0        | return value
        rts
        rts
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.