/* MN10300 Optimised simple memory to memory copy * * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public Licence * as published by the Free Software Foundation; either version * 2 of the Licence, or (at your option) any later version. */ #include <asm/cache.h> .section .text .balign L1_CACHE_BYTES ############################################################################### # # void *memcpy(void *dst, const void *src, size_t n) # ############################################################################### .globl memcpy .type memcpy,@function memcpy: movm [d2,d3],(sp) mov d0,(12,sp) mov d1,(16,sp) mov (20,sp),d2 # count mov d0,a0 # dst mov d1,a1 # src mov d0,e3 # the return value cmp +0,d2 beq memcpy_done # return if zero-length copy # see if the three parameters are all four-byte aligned or d0,d1,d3 or d2,d3 and +3,d3 bne memcpy_1 # jump if not # we want to transfer as much as we can in chunks of 32 bytes cmp +31,d2 bls memcpy_4_remainder # 4-byte aligned remainder movm [exreg1],(sp) add -32,d2 mov +32,d3 memcpy_4_loop: mov (a1+),d0 mov (a1+),d1 mov (a1+),e0 mov (a1+),e1 mov (a1+),e4 mov (a1+),e5 mov (a1+),e6 mov (a1+),e7 mov d0,(a0+) mov d1,(a0+) mov e0,(a0+) mov e1,(a0+) mov e4,(a0+) mov e5,(a0+) mov e6,(a0+) mov e7,(a0+) sub d3,d2 bcc memcpy_4_loop movm (sp),[exreg1] add d3,d2 beq memcpy_4_no_remainder memcpy_4_remainder: # cut 4-7 words down to 0-3 cmp +16,d2 bcs memcpy_4_three_or_fewer_words mov (a1+),d0 mov (a1+),d1 mov (a1+),e0 mov (a1+),e1 mov d0,(a0+) mov d1,(a0+) mov e0,(a0+) mov e1,(a0+) add -16,d2 beq memcpy_4_no_remainder # copy the remaining 1, 2 or 3 words memcpy_4_three_or_fewer_words: cmp +8,d2 bcs memcpy_4_one_word beq memcpy_4_two_words mov (a1+),d0 mov d0,(a0+) memcpy_4_two_words: mov (a1+),d0 mov d0,(a0+) memcpy_4_one_word: mov (a1+),d0 mov d0,(a0+) memcpy_4_no_remainder: # check we copied the correct amount # TODO: REMOVE CHECK sub e3,a0,d2 mov (20,sp),d1 cmp d2,d1 beq memcpy_done break break break memcpy_done: mov e3,a0 ret [d2,d3],8 # handle misaligned copying memcpy_1: add -1,d2 mov +1,d3 setlb # setlb requires the next insns # to occupy exactly 4 bytes sub d3,d2 movbu (a1),d0 movbu d0,(a0) add_add d3,a1,d3,a0 lcc mov e3,a0 ret [d2,d3],8 memcpy_end: .size memcpy, memcpy_end-memcpy