^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2013 Regents of the University of California
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <asm/asm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) /* void *memcpy(void *, const void *, size_t) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) ENTRY(__memcpy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) WEAK(memcpy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) move t6, a0 /* Preserve return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /* Defer to byte-oriented copy for small sizes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) sltiu a3, a2, 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) bnez a3, 4f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* Use word-oriented copy only if low-order bits match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) andi a3, t6, SZREG-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) andi a4, a1, SZREG-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) bne a3, a4, 4f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) beqz a3, 2f /* Skip if already aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * Round to nearest double word-aligned address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * greater than or equal to start address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) andi a3, a1, ~(SZREG-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) addi a3, a3, SZREG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* Handle initial misalignment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) sub a4, a3, a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) lb a5, 0(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) addi a1, a1, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) sb a5, 0(t6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) addi t6, t6, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) bltu a1, a3, 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) sub a2, a2, a4 /* Update count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) andi a4, a2, ~((16*SZREG)-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) beqz a4, 4f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) add a3, a1, a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) REG_L a4, 0(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) REG_L a5, SZREG(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) REG_L a6, 2*SZREG(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) REG_L a7, 3*SZREG(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) REG_L t0, 4*SZREG(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) REG_L t1, 5*SZREG(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) REG_L t2, 6*SZREG(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) REG_L t3, 7*SZREG(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) REG_L t4, 8*SZREG(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) REG_L t5, 9*SZREG(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) REG_S a4, 0(t6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) REG_S a5, SZREG(t6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) REG_S a6, 2*SZREG(t6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) REG_S a7, 3*SZREG(t6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) REG_S t0, 4*SZREG(t6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) REG_S t1, 5*SZREG(t6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) REG_S t2, 6*SZREG(t6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) REG_S t3, 7*SZREG(t6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) REG_S t4, 8*SZREG(t6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) REG_S t5, 9*SZREG(t6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) REG_L a4, 10*SZREG(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) REG_L a5, 11*SZREG(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) REG_L a6, 12*SZREG(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) REG_L a7, 13*SZREG(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) REG_L t0, 14*SZREG(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) REG_L t1, 15*SZREG(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) addi a1, a1, 16*SZREG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) REG_S a4, 10*SZREG(t6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) REG_S a5, 11*SZREG(t6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) REG_S a6, 12*SZREG(t6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) REG_S a7, 13*SZREG(t6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) REG_S t0, 14*SZREG(t6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) REG_S t1, 15*SZREG(t6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) addi t6, t6, 16*SZREG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) bltu a1, a3, 3b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) andi a2, a2, (16*SZREG)-1 /* Update count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* Handle trailing misalignment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) beqz a2, 6f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) add a3, a1, a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* Use word-oriented copy if co-aligned to word boundary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) or a5, a1, t6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) or a5, a5, a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) andi a5, a5, 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) bnez a5, 5f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) lw a4, 0(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) addi a1, a1, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) sw a4, 0(t6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) addi t6, t6, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) bltu a1, a3, 7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) lb a4, 0(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) addi a1, a1, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) sb a4, 0(t6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) addi t6, t6, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) bltu a1, a3, 5b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) END(__memcpy)