mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
1.8 KiB
79 lines
1.8 KiB
/* |
|
* Copyright (C) 2011 Tobias Klauser <[email protected]> |
|
* 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> |
|
|
|
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 only */ |
|
: "r" (c), /* %5 Input */ |
|
"0" (s), /* %0 Input/Output */ |
|
"1" (count) /* %1 Input/Output */ |
|
: "memory" /* clobbered */ |
|
); |
|
|
|
return s; |
|
}
|
|
|