memcmp.S 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /* memcmp.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. /* int memcmp(const void *s1, const void *s2, size_t n);
  12. * R0 = First Address (s1)
  13. * R1 = Second Address (s2)
  14. * R2 = count (n)
  15. *
  16. * Favours word aligned data.
  17. */
  18. .text
  19. .align 2
  20. .global _memcmp
  21. .type _memcmp, STT_FUNC
  22. _memcmp:
  23. I1 = P3;
  24. P0 = R0; // P0 = s1 address
  25. P3 = R1; // P3 = s2 Address
  26. P2 = R2 ; // P2 = count
  27. CC = R2 <= 7(IU);
  28. IF CC JUMP too_small;
  29. I0 = R1; // s2
  30. R1 = R1 | R0; // OR addresses together
  31. R1 <<= 30; // check bottom two bits
  32. CC = AZ; // AZ set if zero.
  33. IF !CC JUMP bytes ; // Jump if addrs not aligned.
  34. P1 = P2 >> 2; // count = n/4
  35. R3 = 3;
  36. R2 = R2 & R3; // remainder
  37. P2 = R2; // set remainder
  38. LSETUP (quad_loop_s , quad_loop_e) LC0=P1;
  39. quad_loop_s:
  40. #if !defined(__WORKAROUND_AVOID_DAG1)
  41. MNOP || R0 = [P0++] || R1 = [I0++];
  42. #else
  43. R0 = [P0++];
  44. R1 = [I0++];
  45. #endif
  46. CC = R0 == R1;
  47. IF !CC JUMP quad_different;
  48. quad_loop_e:
  49. NOP;
  50. P3 = I0; // s2
  51. too_small:
  52. CC = P2 == 0; //Check zero count
  53. IF CC JUMP finished; // very unlikely
  54. bytes:
  55. LSETUP (byte_loop_s , byte_loop_e) LC0=P2;
  56. byte_loop_s:
  57. R1 = B[P3++](Z); // *s2
  58. R0 = B[P0++](Z); // *s1
  59. CC = R0 == R1;
  60. IF !CC JUMP different;
  61. byte_loop_e:
  62. NOP;
  63. different:
  64. R0 = R0 - R1;
  65. P3 = I1;
  66. RTS;
  67. quad_different:
  68. // We've read two quads which don't match.
  69. // Can't just compare them, because we're
  70. // a little-endian machine, so the MSBs of
  71. // the regs occur at later addresses in the
  72. // string.
  73. // Arrange to re-read those two quads again,
  74. // byte-by-byte.
  75. P0 += -4; // back up to the start of the
  76. P3 = I0; // quads, and increase the
  77. P2 += 4; // remainder count
  78. P3 += -4;
  79. JUMP bytes;
  80. finished:
  81. R0 = 0;
  82. P3 = I1;
  83. RTS;
  84. .size _memcmp,.-_memcmp
  85. libc_hidden_def (memcmp)
  86. #ifdef __UCLIBC_SUSV3_LEGACY__
  87. strong_alias (memcmp,bcmp)
  88. #endif