strncpy.S 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * Copyright 2005-2010 Analog Devices Inc.
  3. *
  4. * Licensed under the Clear BSD license or the GPL-2 (or later)
  5. */
  6. #include <linux/linkage.h>
  7. #include <asm/context.S>
  8. /* void *strncpy(char *dest, const char *src, size_t n);
  9. * R0 = address (dest)
  10. * R1 = address (src)
  11. * R2 = size
  12. * Returns a pointer (R0) to the destination string dest
  13. * we do this by not changing R0
  14. */
  15. #ifdef CONFIG_STRNCPY_L1
  16. .section .l1.text
  17. #else
  18. .text
  19. #endif
  20. .align 2
  21. ENTRY(_strncpy)
  22. CC = R2 == 0;
  23. if CC JUMP 6f;
  24. P2 = R2 ; /* size */
  25. P0 = R0 ; /* dst*/
  26. P1 = R1 ; /* src*/
  27. LSETUP (1f, 2f) LC0 = P2;
  28. 1:
  29. R1 = B [P1++] (Z);
  30. B [P0++] = R1;
  31. CC = R1 == 0;
  32. 2:
  33. if CC jump 3f;
  34. RTS;
  35. /* if src is shorter than n, we need to null pad bytes in dest
  36. * but, we can get here when the last byte is zero, and we don't
  37. * want to copy an extra byte at the end, so we need to check
  38. */
  39. 3:
  40. R2 = LC0;
  41. CC = R2
  42. if ! CC jump 6f;
  43. /* if the required null padded portion is small, do it here, rather than
  44. * handling the overhead of memset (which is OK when things are big).
  45. */
  46. R3 = 0x20;
  47. CC = R2 < R3;
  48. IF CC jump 4f;
  49. R2 += -1;
  50. /* Set things up for memset
  51. * R0 = address
  52. * R1 = filler byte (this case it's zero, set above)
  53. * R2 = count (set above)
  54. */
  55. I1 = R0;
  56. R0 = RETS;
  57. I0 = R0;
  58. R0 = P0;
  59. pseudo_long_call _memset, p0;
  60. R0 = I0;
  61. RETS = R0;
  62. R0 = I1;
  63. RTS;
  64. 4:
  65. LSETUP(5f, 5f) LC0;
  66. 5:
  67. B [P0++] = R1;
  68. 6:
  69. RTS;
  70. ENDPROC(_strncpy)