Home | History | Annotate | Download | only in lib
      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 (at) 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
     23 memcpy:
     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 
     49 memcpy_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 
     74 memcpy_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
     90 memcpy_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+)
     96 memcpy_4_two_words:
     97 	mov	(a1+),d0
     98 	mov	d0,(a0+)
     99 memcpy_4_one_word:
    100 	mov	(a1+),d0
    101 	mov	d0,(a0+)
    102 
    103 memcpy_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 
    114 memcpy_done:
    115 	mov	e3,a0
    116 	ret	[d2,d3],8
    117 
    118 	# handle misaligned copying
    119 memcpy_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 
    134 memcpy_end:
    135 	.size	memcpy, memcpy_end-memcpy
    136