1*c5af58b7SGuo Ren/* SPDX-License-Identifier: GPL-2.0 */ 2*c5af58b7SGuo Ren// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. 3*c5af58b7SGuo Ren 4*c5af58b7SGuo Ren#include <linux/linkage.h> 5*c5af58b7SGuo Ren#include "sysdep.h" 6*c5af58b7SGuo Ren 7*c5af58b7SGuo Ren .weak memmove 8*c5af58b7SGuo RenENTRY(__memmove) 9*c5af58b7SGuo RenENTRY(memmove) 10*c5af58b7SGuo Ren subu r3, r0, r1 11*c5af58b7SGuo Ren cmphs r3, r2 12*c5af58b7SGuo Ren bt memcpy 13*c5af58b7SGuo Ren 14*c5af58b7SGuo Ren mov r12, r0 15*c5af58b7SGuo Ren addu r0, r0, r2 16*c5af58b7SGuo Ren addu r1, r1, r2 17*c5af58b7SGuo Ren 18*c5af58b7SGuo Ren /* Test if len less than 4 bytes. */ 19*c5af58b7SGuo Ren cmplti r2, 4 20*c5af58b7SGuo Ren bt .L_copy_by_byte 21*c5af58b7SGuo Ren 22*c5af58b7SGuo Ren andi r13, r0, 3 23*c5af58b7SGuo Ren /* Test if dest is not 4 bytes aligned. */ 24*c5af58b7SGuo Ren bnez r13, .L_dest_not_aligned 25*c5af58b7SGuo Ren /* Hardware can handle unaligned access directly. */ 26*c5af58b7SGuo Ren.L_dest_aligned: 27*c5af58b7SGuo Ren /* If dest is aligned, then copy. */ 28*c5af58b7SGuo Ren zext r18, r2, 31, 4 29*c5af58b7SGuo Ren /* Test if len less than 16 bytes. */ 30*c5af58b7SGuo Ren bez r18, .L_len_less_16bytes 31*c5af58b7SGuo Ren movi r19, 0 32*c5af58b7SGuo Ren 33*c5af58b7SGuo Ren /* len > 16 bytes */ 34*c5af58b7SGuo Ren LABLE_ALIGN 35*c5af58b7SGuo Ren.L_len_larger_16bytes: 36*c5af58b7SGuo Ren subi r1, 16 37*c5af58b7SGuo Ren subi r0, 16 38*c5af58b7SGuo Ren#if defined(__CSKY_VDSPV2__) 39*c5af58b7SGuo Ren vldx.8 vr0, (r1), r19 40*c5af58b7SGuo Ren PRE_BNEZAD (r18) 41*c5af58b7SGuo Ren vstx.8 vr0, (r0), r19 42*c5af58b7SGuo Ren#elif defined(__CK860__) 43*c5af58b7SGuo Ren ldw r3, (r1, 12) 44*c5af58b7SGuo Ren stw r3, (r0, 12) 45*c5af58b7SGuo Ren ldw r3, (r1, 8) 46*c5af58b7SGuo Ren stw r3, (r0, 8) 47*c5af58b7SGuo Ren ldw r3, (r1, 4) 48*c5af58b7SGuo Ren stw r3, (r0, 4) 49*c5af58b7SGuo Ren ldw r3, (r1, 0) 50*c5af58b7SGuo Ren stw r3, (r0, 0) 51*c5af58b7SGuo Ren#else 52*c5af58b7SGuo Ren ldw r20, (r1, 0) 53*c5af58b7SGuo Ren ldw r21, (r1, 4) 54*c5af58b7SGuo Ren ldw r22, (r1, 8) 55*c5af58b7SGuo Ren ldw r23, (r1, 12) 56*c5af58b7SGuo Ren stw r20, (r0, 0) 57*c5af58b7SGuo Ren stw r21, (r0, 4) 58*c5af58b7SGuo Ren stw r22, (r0, 8) 59*c5af58b7SGuo Ren stw r23, (r0, 12) 60*c5af58b7SGuo Ren PRE_BNEZAD (r18) 61*c5af58b7SGuo Ren#endif 62*c5af58b7SGuo Ren BNEZAD (r18, .L_len_larger_16bytes) 63*c5af58b7SGuo Ren 64*c5af58b7SGuo Ren.L_len_less_16bytes: 65*c5af58b7SGuo Ren zext r18, r2, 3, 2 66*c5af58b7SGuo Ren bez r18, .L_copy_by_byte 67*c5af58b7SGuo Ren.L_len_less_16bytes_loop: 68*c5af58b7SGuo Ren subi r1, 4 69*c5af58b7SGuo Ren subi r0, 4 70*c5af58b7SGuo Ren ldw r3, (r1, 0) 71*c5af58b7SGuo Ren PRE_BNEZAD (r18) 72*c5af58b7SGuo Ren stw r3, (r0, 0) 73*c5af58b7SGuo Ren BNEZAD (r18, .L_len_less_16bytes_loop) 74*c5af58b7SGuo Ren 75*c5af58b7SGuo Ren /* Test if len less than 4 bytes. */ 76*c5af58b7SGuo Ren.L_copy_by_byte: 77*c5af58b7SGuo Ren zext r18, r2, 1, 0 78*c5af58b7SGuo Ren bez r18, .L_return 79*c5af58b7SGuo Ren.L_copy_by_byte_loop: 80*c5af58b7SGuo Ren subi r1, 1 81*c5af58b7SGuo Ren subi r0, 1 82*c5af58b7SGuo Ren ldb r3, (r1, 0) 83*c5af58b7SGuo Ren PRE_BNEZAD (r18) 84*c5af58b7SGuo Ren stb r3, (r0, 0) 85*c5af58b7SGuo Ren BNEZAD (r18, .L_copy_by_byte_loop) 86*c5af58b7SGuo Ren 87*c5af58b7SGuo Ren.L_return: 88*c5af58b7SGuo Ren mov r0, r12 89*c5af58b7SGuo Ren rts 90*c5af58b7SGuo Ren 91*c5af58b7SGuo Ren /* If dest is not aligned, just copy some bytes makes the dest 92*c5af58b7SGuo Ren align. */ 93*c5af58b7SGuo Ren.L_dest_not_aligned: 94*c5af58b7SGuo Ren sub r2, r13 95*c5af58b7SGuo Ren.L_dest_not_aligned_loop: 96*c5af58b7SGuo Ren subi r1, 1 97*c5af58b7SGuo Ren subi r0, 1 98*c5af58b7SGuo Ren /* Makes the dest align. */ 99*c5af58b7SGuo Ren ldb r3, (r1, 0) 100*c5af58b7SGuo Ren PRE_BNEZAD (r13) 101*c5af58b7SGuo Ren stb r3, (r0, 0) 102*c5af58b7SGuo Ren BNEZAD (r13, .L_dest_not_aligned_loop) 103*c5af58b7SGuo Ren cmplti r2, 4 104*c5af58b7SGuo Ren bt .L_copy_by_byte 105*c5af58b7SGuo Ren /* Check whether the src is aligned. */ 106*c5af58b7SGuo Ren jbr .L_dest_aligned 107*c5af58b7SGuo RenENDPROC(memmove) 108*c5af58b7SGuo RenENDPROC(__memmove) 109