memcmp.S 2.3 KB

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