^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <asm/asm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /* void *memset(void *, int, size_t) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) ENTRY(__memset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) WEAK(memset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) move t0, a0 /* Preserve return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) /* Defer to byte-oriented fill for small sizes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) sltiu a3, a2, 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) bnez a3, 4f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Round to nearest XLEN-aligned address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * greater than or equal to start address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) addi a3, t0, SZREG-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) andi a3, a3, ~(SZREG-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) beq a3, t0, 2f /* Skip if already aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* Handle initial misalignment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) sub a4, a3, t0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) sb a1, 0(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) addi t0, t0, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) bltu t0, a3, 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) sub a2, a2, a4 /* Update count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) 2: /* Duff's device with 32 XLEN stores per iteration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* Broadcast value into all bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) andi a1, a1, 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) slli a3, a1, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) or a1, a3, a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) slli a3, a1, 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) or a1, a3, a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #ifdef CONFIG_64BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) slli a3, a1, 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) or a1, a3, a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* Calculate end address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) andi a4, a2, ~(SZREG-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) add a3, t0, a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) andi a4, a4, 31*SZREG /* Calculate remainder */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) beqz a4, 3f /* Shortcut if no remainder */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) neg a4, a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) addi a4, a4, 32*SZREG /* Calculate initial offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* Adjust start address with offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) sub t0, t0, a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* Jump into loop body */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* Assumes 32-bit instruction lengths */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) la a5, 3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #ifdef CONFIG_64BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) srli a4, a4, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) add a5, a5, a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) jr a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) REG_S a1, 0(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) REG_S a1, SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) REG_S a1, 2*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) REG_S a1, 3*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) REG_S a1, 4*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) REG_S a1, 5*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) REG_S a1, 6*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) REG_S a1, 7*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) REG_S a1, 8*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) REG_S a1, 9*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) REG_S a1, 10*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) REG_S a1, 11*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) REG_S a1, 12*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) REG_S a1, 13*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) REG_S a1, 14*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) REG_S a1, 15*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) REG_S a1, 16*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) REG_S a1, 17*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) REG_S a1, 18*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) REG_S a1, 19*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) REG_S a1, 20*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) REG_S a1, 21*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) REG_S a1, 22*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) REG_S a1, 23*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) REG_S a1, 24*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) REG_S a1, 25*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) REG_S a1, 26*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) REG_S a1, 27*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) REG_S a1, 28*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) REG_S a1, 29*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) REG_S a1, 30*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) REG_S a1, 31*SZREG(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) addi t0, t0, 32*SZREG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) bltu t0, a3, 3b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) andi a2, a2, SZREG-1 /* Update count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* Handle trailing misalignment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) beqz a2, 6f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) add a3, t0, a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) sb a1, 0(t0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) addi t0, t0, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) bltu t0, a3, 5b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) END(__memset)