memmove.S 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /* memmove.S
  2. * Copyright (C) 2003, 2005, 2006 Analog Devices Inc., All Rights Reserved.
  3. *
  4. * This file is subject to the terms and conditions of the GNU Library General
  5. * Public License. See the file "COPYING.LIB" in the main directory of this
  6. * archive for more details.
  7. *
  8. * Non-LGPL License also available as part of VisualDSP++
  9. * http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html
  10. */
  11. /* void *memmove(void *dest, const void *src, size_t n);
  12. * R0 = To Address (dest) (leave unchanged to form result)
  13. * R1 = From Address (src)
  14. * R2 = count (n)
  15. *
  16. * Note: Data may overlap
  17. */
  18. .text
  19. .align 2
  20. .global _memmove
  21. .type _memmove, STT_FUNC
  22. _memmove:
  23. I1 = P3;
  24. P0 = R0; // P0 = To address
  25. P3 = R1; // P3 = From Address
  26. P2 = R2 ; // P2 = count
  27. CC = P2 == 0; //Check zero count
  28. IF CC JUMP finished; // very unlikely
  29. CC = R1 < R0 (IU); // From < To
  30. IF !CC JUMP no_overlap;
  31. R3 = R1 + R2;
  32. CC = R0 <= R3 (IU); // (From+len) >= To
  33. IF CC JUMP overlap;
  34. no_overlap:
  35. R3 = 11;
  36. CC = R2 <= R3;
  37. IF CC JUMP bytes;
  38. R3 = R1 | R0; // OR addresses together
  39. R3 <<= 30; // check bottom two bits
  40. CC = AZ; // AZ set if zero.
  41. IF !CC JUMP bytes ; // Jump if addrs not aligned.
  42. I0 = P3;
  43. P1 = P2 >> 2; // count = n/4
  44. P1 += -1;
  45. R3 = 3;
  46. R2 = R2 & R3; // remainder
  47. P2 = R2; // set remainder
  48. R1 = [I0++];
  49. #if !defined(__WORKAROUND_AVOID_DAG1)
  50. LSETUP (quad_loop , quad_loop) LC0=P1;
  51. quad_loop: MNOP || [P0++] = R1 || R1 = [I0++];
  52. #else
  53. LSETUP (quad_loop_s, quad_loop_e) LC0=P1;
  54. quad_loop_s: [P0++] = R1;
  55. quad_loop_e: R1 = [I0++];
  56. #endif
  57. [P0++] = R1;
  58. CC = P2 == 0; // any remaining bytes?
  59. P3 = I0; // Ammend P3 to updated ptr.
  60. IF !CC JUMP bytes;
  61. P3 = I1;
  62. RTS;
  63. bytes: LSETUP (byte2_s , byte2_e) LC0=P2;
  64. byte2_s: R1 = B[P3++](Z);
  65. byte2_e: B[P0++] = R1;
  66. finished:
  67. P3 = I1;
  68. RTS;
  69. overlap:
  70. P2 += -1;
  71. P0 = P0 + P2;
  72. P3 = P3 + P2;
  73. R1 = B[P3--] (Z);
  74. CC = P2 == 0;
  75. IF CC JUMP no_loop;
  76. LSETUP (ol_s, ol_e) LC0 = P2;
  77. ol_s: B[P0--] = R1;
  78. ol_e: R1 = B[P3--] (Z);
  79. no_loop: B[P0] = R1;
  80. P3 = I1;
  81. RTS;
  82. .size _memmove,.-_memmove
  83. libc_hidden_def (memmove)