/* MN10300 Optimised simple memory to memory copy, with support for overlapping1* regions2*3* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.4* Written by David Howells ([email protected])5*6* This program is free software; you can redistribute it and/or7* modify it under the terms of the GNU General Public Licence8* as published by the Free Software Foundation; either version9* 2 of the Licence, or (at your option) any later version.10*/11#include <asm/cache.h>1213.section .text14.balign L1_CACHE_BYTES1516###############################################################################17#18# void *memmove(void *dst, const void *src, size_t n)19#20###############################################################################21.globl memmove22.type memmove,@function23memmove:24# fall back to memcpy if dst < src to work bottom up25cmp d1,d026bcs memmove_memcpy2728# work top down29movm [d2,d3],(sp)30mov d0,(12,sp)31mov d1,(16,sp)32mov (20,sp),d2 # count33add d0,d2,a0 # dst end34add d1,d2,a1 # src end35mov d0,e3 # the return value3637cmp +0,d238beq memmove_done # return if zero-length copy3940# see if the three parameters are all four-byte aligned41or d0,d1,d342or d2,d343and +3,d344bne memmove_1 # jump if not4546# we want to transfer as much as we can in chunks of 32 bytes47add -4,a148cmp +31,d249bls memmove_4_remainder # 4-byte aligned remainder5051add -32,d252mov +32,d35354memmove_4_loop:55mov (a1),d056sub_sub +4,a1,+4,a057mov d0,(a0)58mov (a1),d159sub_sub +4,a1,+4,a060mov d1,(a0)6162mov (a1),d063sub_sub +4,a1,+4,a064mov d0,(a0)65mov (a1),d166sub_sub +4,a1,+4,a067mov d1,(a0)6869mov (a1),d070sub_sub +4,a1,+4,a071mov d0,(a0)72mov (a1),d173sub_sub +4,a1,+4,a074mov d1,(a0)7576mov (a1),d077sub_sub +4,a1,+4,a078mov d0,(a0)79mov (a1),d180sub_sub +4,a1,+4,a081mov d1,(a0)8283sub d3,d284bcc memmove_4_loop8586add d3,d287beq memmove_4_no_remainder8889memmove_4_remainder:90# cut 4-7 words down to 0-391cmp +16,d292bcs memmove_4_three_or_fewer_words93mov (a1),d094sub_sub +4,a1,+4,a095mov d0,(a0)96mov (a1),d197sub_sub +4,a1,+4,a098mov d1,(a0)99mov (a1),e0100sub_sub +4,a1,+4,a0101mov e0,(a0)102mov (a1),e1103sub_sub +4,a1,+4,a0104mov e1,(a0)105add -16,d2106beq memmove_4_no_remainder107108# copy the remaining 1, 2 or 3 words109memmove_4_three_or_fewer_words:110cmp +8,d2111bcs memmove_4_one_word112beq memmove_4_two_words113mov (a1),d0114sub_sub +4,a1,+4,a0115mov d0,(a0)116memmove_4_two_words:117mov (a1),d0118sub_sub +4,a1,+4,a0119mov d0,(a0)120memmove_4_one_word:121mov (a1),d0122sub_sub +4,a1,+4,a0123mov d0,(a0)124125memmove_4_no_remainder:126# check we copied the correct amount127# TODO: REMOVE CHECK128sub e3,a0,d2129beq memmove_done130break131break132break133134memmove_done:135mov e3,a0136ret [d2,d3],8137138# handle misaligned copying139memmove_1:140add -1,a1141add -1,d2142mov +1,d3143setlb # setlb requires the next insns144# to occupy exactly 4 bytes145146sub d3,d2147movbu (a1),d0148sub_sub d3,a1,d3,a0149movbu d0,(a0)150lcc151152mov e3,a0153ret [d2,d3],8154155memmove_memcpy:156jmp memcpy157158memmove_end:159.size memmove, memmove_end-memmove160161162