memset.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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. #include <linux/types.h>
  10. #include <linux/string.h>
  11. void *memset(void *s, int c, size_t count)
  12. {
  13. int destptr, charcnt, dwordcnt, fill8reg, wrkrega;
  14. if (!count)
  15. return s;
  16. c &= 0xFF;
  17. if (count <= 8) {
  18. char *xs = (char *) s;
  19. while (count--)
  20. *xs++ = c;
  21. return s;
  22. }
  23. __asm__ __volatile__ (
  24. /* fill8 %3, %5 (c & 0xff) */
  25. " slli %4, %5, 8\n"
  26. " or %4, %4, %5\n"
  27. " slli %3, %4, 16\n"
  28. " or %3, %3, %4\n"
  29. /* Word-align %0 (s) if necessary */
  30. " andi %4, %0, 0x01\n"
  31. " beq %4, zero, 1f\n"
  32. " addi %1, %1, -1\n"
  33. " stb %3, 0(%0)\n"
  34. " addi %0, %0, 1\n"
  35. "1: mov %2, %1\n"
  36. /* Dword-align %0 (s) if necessary */
  37. " andi %4, %0, 0x02\n"
  38. " beq %4, zero, 2f\n"
  39. " addi %1, %1, -2\n"
  40. " sth %3, 0(%0)\n"
  41. " addi %0, %0, 2\n"
  42. " mov %2, %1\n"
  43. /* %1 and %2 are how many more bytes to set */
  44. "2: srli %2, %2, 2\n"
  45. /* %2 is how many dwords to set */
  46. "3: stw %3, 0(%0)\n"
  47. " addi %0, %0, 4\n"
  48. " addi %2, %2, -1\n"
  49. " bne %2, zero, 3b\n"
  50. /* store residual word and/or byte if necessary */
  51. " andi %4, %1, 0x02\n"
  52. " beq %4, zero, 4f\n"
  53. " sth %3, 0(%0)\n"
  54. " addi %0, %0, 2\n"
  55. /* store residual byte if necessary */
  56. "4: andi %4, %1, 0x01\n"
  57. " beq %4, zero, 5f\n"
  58. " stb %3, 0(%0)\n"
  59. "5:\n"
  60. : "=r" (destptr), /* %0 Output */
  61. "=r" (charcnt), /* %1 Output */
  62. "=r" (dwordcnt), /* %2 Output */
  63. "=r" (fill8reg), /* %3 Output */
  64. "=r" (wrkrega) /* %4 Output */
  65. : "r" (c), /* %5 Input */
  66. "0" (s), /* %0 Input/Output */
  67. "1" (count) /* %1 Input/Output */
  68. : "memory" /* clobbered */
  69. );
  70. return s;
  71. }