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