memset.c 1.9 KB

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