linux/arch/mn10300/lib/memcpy.S
<<
>>
Prefs
   1/* MN10300 Optimised simple memory to memory copy
   2 *
   3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
   4 * Written by David Howells (dhowells@redhat.com)
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public Licence
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the Licence, or (at your option) any later version.
  10 */
  11#include <asm/cache.h>
  12
  13        .section .text
  14        .balign L1_CACHE_BYTES
  15
  16###############################################################################
  17#
  18# void *memcpy(void *dst, const void *src, size_t n)
  19#
  20###############################################################################
  21        .globl  memcpy
  22        .type   memcpy,@function
  23memcpy:
  24        movm    [d2,d3],(sp)
  25        mov     d0,(12,sp)
  26        mov     d1,(16,sp)
  27        mov     (20,sp),d2                      # count
  28        mov     d0,a0                           # dst
  29        mov     d1,a1                           # src
  30        mov     d0,e3                           # the return value
  31
  32        cmp     +0,d2
  33        beq     memcpy_done                     # return if zero-length copy
  34
  35        # see if the three parameters are all four-byte aligned
  36        or      d0,d1,d3
  37        or      d2,d3
  38        and     +3,d3
  39        bne     memcpy_1                        # jump if not
  40
  41        # we want to transfer as much as we can in chunks of 32 bytes
  42        cmp     +31,d2
  43        bls     memcpy_4_remainder              # 4-byte aligned remainder
  44
  45        movm    [exreg1],(sp)
  46        add     -32,d2
  47        mov     +32,d3
  48
  49memcpy_4_loop:
  50        mov     (a1+),d0
  51        mov     (a1+),d1
  52        mov     (a1+),e0
  53        mov     (a1+),e1
  54        mov     (a1+),e4
  55        mov     (a1+),e5
  56        mov     (a1+),e6
  57        mov     (a1+),e7
  58        mov     d0,(a0+)
  59        mov     d1,(a0+)
  60        mov     e0,(a0+)
  61        mov     e1,(a0+)
  62        mov     e4,(a0+)
  63        mov     e5,(a0+)
  64        mov     e6,(a0+)
  65        mov     e7,(a0+)
  66
  67        sub     d3,d2
  68        bcc     memcpy_4_loop
  69
  70        movm    (sp),[exreg1]
  71        add     d3,d2
  72        beq     memcpy_4_no_remainder
  73
  74memcpy_4_remainder:
  75        # cut 4-7 words down to 0-3
  76        cmp     +16,d2
  77        bcs     memcpy_4_three_or_fewer_words
  78        mov     (a1+),d0
  79        mov     (a1+),d1
  80        mov     (a1+),e0
  81        mov     (a1+),e1
  82        mov     d0,(a0+)
  83        mov     d1,(a0+)
  84        mov     e0,(a0+)
  85        mov     e1,(a0+)
  86        add     -16,d2
  87        beq     memcpy_4_no_remainder
  88
  89        # copy the remaining 1, 2 or 3 words
  90memcpy_4_three_or_fewer_words:
  91        cmp     +8,d2
  92        bcs     memcpy_4_one_word
  93        beq     memcpy_4_two_words
  94        mov     (a1+),d0
  95        mov     d0,(a0+)
  96memcpy_4_two_words:
  97        mov     (a1+),d0
  98        mov     d0,(a0+)
  99memcpy_4_one_word:
 100        mov     (a1+),d0
 101        mov     d0,(a0+)
 102
 103memcpy_4_no_remainder:
 104        # check we copied the correct amount
 105        # TODO: REMOVE CHECK
 106        sub     e3,a0,d2
 107        mov     (20,sp),d1
 108        cmp     d2,d1
 109        beq     memcpy_done
 110        break
 111        break
 112        break
 113
 114memcpy_done:
 115        mov     e3,a0
 116        ret     [d2,d3],8
 117
 118        # handle misaligned copying
 119memcpy_1:
 120        add     -1,d2
 121        mov     +1,d3
 122        setlb                                   # setlb requires the next insns
 123                                                # to occupy exactly 4 bytes
 124
 125        sub     d3,d2
 126        movbu   (a1),d0
 127        movbu   d0,(a0)
 128        add_add d3,a1,d3,a0
 129        lcc
 130
 131        mov     e3,a0
 132        ret     [d2,d3],8
 133
 134memcpy_end:
 135        .size   memcpy, memcpy_end-memcpy
 136