memmove.S 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /*
  2. * File: memmove.S
  3. *
  4. * Copyright 2004-2007 Analog Devices Inc.
  5. * Enter bugs at http://blackfin.uclinux.org/
  6. *
  7. * SPDX-License-Identifier: GPL-2.0+
  8. */
  9. .align 2
  10. /*
  11. * C Library function MEMMOVE
  12. * R0 = To Address (leave unchanged to form result)
  13. * R1 = From Address
  14. * R2 = count
  15. * Data may overlap
  16. */
  17. .globl _memmove;
  18. .type _memmove, STT_FUNC;
  19. _memmove:
  20. I1 = P3;
  21. P0 = R0; /* P0 = To address */
  22. P3 = R1; /* P3 = From Address */
  23. P2 = R2 ; /* P2 = count */
  24. CC = P2 == 0; /* Check zero count*/
  25. IF CC JUMP .Lfinished; /* very unlikely */
  26. CC = R1 < R0 (IU); /* From < To */
  27. IF !CC JUMP .Lno_overlap;
  28. R3 = R1 + R2;
  29. CC = R0 <= R3 (IU); /* (From+len) >= To */
  30. IF CC JUMP .Loverlap;
  31. .Lno_overlap:
  32. R3 = 11;
  33. CC = R2 <= R3;
  34. IF CC JUMP .Lbytes;
  35. R3 = R1 | R0; /* OR addresses together */
  36. R3 <<= 30; /* check bottom two bits */
  37. CC = AZ; /* AZ set if zero.*/
  38. IF !CC JUMP .Lbytes ; /* Jump if addrs not aligned.*/
  39. I0 = P3;
  40. P1 = P2 >> 2; /* count = n/4 */
  41. P1 += -1;
  42. R3 = 3;
  43. R2 = R2 & R3; /* remainder */
  44. P2 = R2; /* set remainder */
  45. R1 = [I0++];
  46. LSETUP (.Lquad_loop , .Lquad_loop) LC0=P1;
  47. .Lquad_loop: MNOP || [P0++] = R1 || R1 = [I0++];
  48. [P0++] = R1;
  49. CC = P2 == 0; /* any remaining bytes? */
  50. P3 = I0; /* Ammend P3 to updated ptr. */
  51. IF !CC JUMP .Lbytes;
  52. P3 = I1;
  53. RTS;
  54. .Lbytes: LSETUP (.Lbyte2_s , .Lbyte2_e) LC0=P2;
  55. .Lbyte2_s: R1 = B[P3++](Z);
  56. .Lbyte2_e: B[P0++] = R1;
  57. .Lfinished: P3 = I1;
  58. RTS;
  59. .Loverlap:
  60. P2 += -1;
  61. P0 = P0 + P2;
  62. P3 = P3 + P2;
  63. R1 = B[P3--] (Z);
  64. CC = P2 == 0;
  65. IF CC JUMP .Lno_loop;
  66. LSETUP (.Lol_s, .Lol_e) LC0 = P2;
  67. .Lol_s: B[P0--] = R1;
  68. .Lol_e: R1 = B[P3--] (Z);
  69. .Lno_loop: B[P0] = R1;
  70. P3 = I1;
  71. RTS;
  72. .size _memmove, .-_memmove