18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch> 38c2ecf20Sopenharmony_ci * Copyright (C) 2004 Microtronix Datacom Ltd 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 68c2ecf20Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 78c2ecf20Sopenharmony_ci * for more details. 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/types.h> 118c2ecf20Sopenharmony_ci#include <linux/string.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_civoid *memset(void *s, int c, size_t count) 148c2ecf20Sopenharmony_ci{ 158c2ecf20Sopenharmony_ci int destptr, charcnt, dwordcnt, fill8reg, wrkrega; 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci if (!count) 188c2ecf20Sopenharmony_ci return s; 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci c &= 0xFF; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci if (count <= 8) { 238c2ecf20Sopenharmony_ci char *xs = (char *) s; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci while (count--) 268c2ecf20Sopenharmony_ci *xs++ = c; 278c2ecf20Sopenharmony_ci return s; 288c2ecf20Sopenharmony_ci } 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci __asm__ __volatile__ ( 318c2ecf20Sopenharmony_ci /* fill8 %3, %5 (c & 0xff) */ 328c2ecf20Sopenharmony_ci " slli %4, %5, 8\n" 338c2ecf20Sopenharmony_ci " or %4, %4, %5\n" 348c2ecf20Sopenharmony_ci " slli %3, %4, 16\n" 358c2ecf20Sopenharmony_ci " or %3, %3, %4\n" 368c2ecf20Sopenharmony_ci /* Word-align %0 (s) if necessary */ 378c2ecf20Sopenharmony_ci " andi %4, %0, 0x01\n" 388c2ecf20Sopenharmony_ci " beq %4, zero, 1f\n" 398c2ecf20Sopenharmony_ci " addi %1, %1, -1\n" 408c2ecf20Sopenharmony_ci " stb %3, 0(%0)\n" 418c2ecf20Sopenharmony_ci " addi %0, %0, 1\n" 428c2ecf20Sopenharmony_ci "1: mov %2, %1\n" 438c2ecf20Sopenharmony_ci /* Dword-align %0 (s) if necessary */ 448c2ecf20Sopenharmony_ci " andi %4, %0, 0x02\n" 458c2ecf20Sopenharmony_ci " beq %4, zero, 2f\n" 468c2ecf20Sopenharmony_ci " addi %1, %1, -2\n" 478c2ecf20Sopenharmony_ci " sth %3, 0(%0)\n" 488c2ecf20Sopenharmony_ci " addi %0, %0, 2\n" 498c2ecf20Sopenharmony_ci " mov %2, %1\n" 508c2ecf20Sopenharmony_ci /* %1 and %2 are how many more bytes to set */ 518c2ecf20Sopenharmony_ci "2: srli %2, %2, 2\n" 528c2ecf20Sopenharmony_ci /* %2 is how many dwords to set */ 538c2ecf20Sopenharmony_ci "3: stw %3, 0(%0)\n" 548c2ecf20Sopenharmony_ci " addi %0, %0, 4\n" 558c2ecf20Sopenharmony_ci " addi %2, %2, -1\n" 568c2ecf20Sopenharmony_ci " bne %2, zero, 3b\n" 578c2ecf20Sopenharmony_ci /* store residual word and/or byte if necessary */ 588c2ecf20Sopenharmony_ci " andi %4, %1, 0x02\n" 598c2ecf20Sopenharmony_ci " beq %4, zero, 4f\n" 608c2ecf20Sopenharmony_ci " sth %3, 0(%0)\n" 618c2ecf20Sopenharmony_ci " addi %0, %0, 2\n" 628c2ecf20Sopenharmony_ci /* store residual byte if necessary */ 638c2ecf20Sopenharmony_ci "4: andi %4, %1, 0x01\n" 648c2ecf20Sopenharmony_ci " beq %4, zero, 5f\n" 658c2ecf20Sopenharmony_ci " stb %3, 0(%0)\n" 668c2ecf20Sopenharmony_ci "5:\n" 678c2ecf20Sopenharmony_ci : "=r" (destptr), /* %0 Output */ 688c2ecf20Sopenharmony_ci "=r" (charcnt), /* %1 Output */ 698c2ecf20Sopenharmony_ci "=r" (dwordcnt), /* %2 Output */ 708c2ecf20Sopenharmony_ci "=r" (fill8reg), /* %3 Output */ 718c2ecf20Sopenharmony_ci "=&r" (wrkrega) /* %4 Output only */ 728c2ecf20Sopenharmony_ci : "r" (c), /* %5 Input */ 738c2ecf20Sopenharmony_ci "0" (s), /* %0 Input/Output */ 748c2ecf20Sopenharmony_ci "1" (count) /* %1 Input/Output */ 758c2ecf20Sopenharmony_ci : "memory" /* clobbered */ 768c2ecf20Sopenharmony_ci ); 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci return s; 798c2ecf20Sopenharmony_ci} 80