^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2004 Microtronix Datacom Ltd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) void *memset(void *s, int c, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) int destptr, charcnt, dwordcnt, fill8reg, wrkrega;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) if (!count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) c &= 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) if (count <= 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) char *xs = (char *) s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) while (count--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *xs++ = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) __asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /* fill8 %3, %5 (c & 0xff) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) " slli %4, %5, 8\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) " or %4, %4, %5\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) " slli %3, %4, 16\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) " or %3, %3, %4\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* Word-align %0 (s) if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) " andi %4, %0, 0x01\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) " beq %4, zero, 1f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) " addi %1, %1, -1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) " stb %3, 0(%0)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) " addi %0, %0, 1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) "1: mov %2, %1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* Dword-align %0 (s) if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) " andi %4, %0, 0x02\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) " beq %4, zero, 2f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) " addi %1, %1, -2\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) " sth %3, 0(%0)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) " addi %0, %0, 2\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) " mov %2, %1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* %1 and %2 are how many more bytes to set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) "2: srli %2, %2, 2\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* %2 is how many dwords to set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) "3: stw %3, 0(%0)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) " addi %0, %0, 4\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) " addi %2, %2, -1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) " bne %2, zero, 3b\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* store residual word and/or byte if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) " andi %4, %1, 0x02\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) " beq %4, zero, 4f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) " sth %3, 0(%0)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) " addi %0, %0, 2\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* store residual byte if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) "4: andi %4, %1, 0x01\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) " beq %4, zero, 5f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) " stb %3, 0(%0)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) "5:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) : "=r" (destptr), /* %0 Output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) "=r" (charcnt), /* %1 Output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) "=r" (dwordcnt), /* %2 Output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) "=r" (fill8reg), /* %3 Output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) "=&r" (wrkrega) /* %4 Output only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) : "r" (c), /* %5 Input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) "0" (s), /* %0 Input/Output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) "1" (count) /* %1 Input/Output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) : "memory" /* clobbered */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }