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