|  | /* | 
|  | * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch> | 
|  | * Copyright (C) 2004 Microtronix Datacom Ltd | 
|  | * | 
|  | * This file is subject to the terms and conditions of the GNU General Public | 
|  | * License.  See the file "COPYING" in the main directory of this archive | 
|  | * for more details. | 
|  | */ | 
|  |  | 
|  | #include <linux/types.h> | 
|  | #include <linux/string.h> | 
|  |  | 
|  | #ifdef __HAVE_ARCH_MEMSET | 
|  | void *memset(void *s, int c, size_t count) | 
|  | { | 
|  | int destptr, charcnt, dwordcnt, fill8reg, wrkrega; | 
|  |  | 
|  | if (!count) | 
|  | return s; | 
|  |  | 
|  | c &= 0xFF; | 
|  |  | 
|  | if (count <= 8) { | 
|  | char *xs = (char *) s; | 
|  |  | 
|  | while (count--) | 
|  | *xs++ = c; | 
|  | return s; | 
|  | } | 
|  |  | 
|  | __asm__ __volatile__ ( | 
|  | /* fill8 %3, %5 (c & 0xff) */ | 
|  | "	slli	%4, %5, 8\n" | 
|  | "	or	%4, %4, %5\n" | 
|  | "	slli    %3, %4, 16\n" | 
|  | "	or	%3, %3, %4\n" | 
|  | /* Word-align %0 (s) if necessary */ | 
|  | "	andi	%4, %0, 0x01\n" | 
|  | "	beq	%4, zero, 1f\n" | 
|  | "	addi	%1, %1, -1\n" | 
|  | "	stb	%3, 0(%0)\n" | 
|  | "	addi	%0, %0, 1\n" | 
|  | "1:	mov	%2, %1\n" | 
|  | /* Dword-align %0 (s) if necessary */ | 
|  | "	andi	%4, %0, 0x02\n" | 
|  | "	beq	%4, zero, 2f\n" | 
|  | "	addi	%1, %1, -2\n" | 
|  | "	sth	%3, 0(%0)\n" | 
|  | "	addi	%0, %0, 2\n" | 
|  | "	mov	%2, %1\n" | 
|  | /* %1 and %2 are how many more bytes to set */ | 
|  | "2:	srli	%2, %2, 2\n" | 
|  | /* %2 is how many dwords to set */ | 
|  | "3:	stw	%3, 0(%0)\n" | 
|  | "	addi	%0, %0, 4\n" | 
|  | "	addi    %2, %2, -1\n" | 
|  | "	bne	%2, zero, 3b\n" | 
|  | /* store residual word and/or byte if necessary */ | 
|  | "	andi	%4, %1, 0x02\n" | 
|  | "	beq	%4, zero, 4f\n" | 
|  | "	sth	%3, 0(%0)\n" | 
|  | "	addi	%0, %0, 2\n" | 
|  | /* store residual byte if necessary */ | 
|  | "4:	andi	%4, %1, 0x01\n" | 
|  | "	beq	%4, zero, 5f\n" | 
|  | "	stb	%3, 0(%0)\n" | 
|  | "5:\n" | 
|  | : "=r" (destptr),	/* %0  Output */ | 
|  | "=r" (charcnt),	/* %1  Output */ | 
|  | "=r" (dwordcnt),	/* %2  Output */ | 
|  | "=r" (fill8reg),	/* %3  Output */ | 
|  | "=r" (wrkrega)	/* %4  Output */ | 
|  | : "r" (c),		/* %5  Input */ | 
|  | "0" (s),		/* %0  Input/Output */ | 
|  | "1" (count)		/* %1  Input/Output */ | 
|  | : "memory"		/* clobbered */ | 
|  | ); | 
|  |  | 
|  | return s; | 
|  | } | 
|  | #endif /* __HAVE_ARCH_MEMSET */ |