7zCrcOpt.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /* 7zCrcOpt.c -- CRC32 calculation (optimized functions)
  2. 2023-12-07 : Igor Pavlov : Public domain */
  3. #include "Precomp.h"
  4. #include "CpuArch.h"
  5. #if !defined(Z7_CRC_NUM_TABLES) || Z7_CRC_NUM_TABLES > 1
  6. // for debug only : define Z7_CRC_DEBUG_BE to test big-endian code in little-endian cpu
  7. // #define Z7_CRC_DEBUG_BE
  8. #ifdef Z7_CRC_DEBUG_BE
  9. #undef MY_CPU_LE
  10. #define MY_CPU_BE
  11. #endif
  12. // the value Z7_CRC_NUM_TABLES_USE must be defined to same value as in 7zCrc.c
  13. #ifdef Z7_CRC_NUM_TABLES
  14. #define Z7_CRC_NUM_TABLES_USE Z7_CRC_NUM_TABLES
  15. #else
  16. #define Z7_CRC_NUM_TABLES_USE 12
  17. #endif
  18. #if Z7_CRC_NUM_TABLES_USE % 4 || \
  19. Z7_CRC_NUM_TABLES_USE < 4 * 1 || \
  20. Z7_CRC_NUM_TABLES_USE > 4 * 6
  21. #error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES
  22. #endif
  23. #ifndef MY_CPU_BE
  24. #define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
  25. #define Q(n, d) \
  26. ( (table + ((n) * 4 + 3) * 0x100)[(Byte)(d)] \
  27. ^ (table + ((n) * 4 + 2) * 0x100)[((d) >> 1 * 8) & 0xFF] \
  28. ^ (table + ((n) * 4 + 1) * 0x100)[((d) >> 2 * 8) & 0xFF] \
  29. ^ (table + ((n) * 4 + 0) * 0x100)[((d) >> 3 * 8)] )
  30. #define R(a) *((const UInt32 *)(const void *)p + (a))
  31. #define CRC_FUNC_PRE_LE2(step) \
  32. UInt32 Z7_FASTCALL CrcUpdateT ## step (UInt32 v, const void *data, size_t size, const UInt32 *table)
  33. #define CRC_FUNC_PRE_LE(step) \
  34. CRC_FUNC_PRE_LE2(step); \
  35. CRC_FUNC_PRE_LE2(step)
  36. CRC_FUNC_PRE_LE(Z7_CRC_NUM_TABLES_USE)
  37. {
  38. const Byte *p = (const Byte *)data;
  39. const Byte *lim;
  40. for (; size && ((unsigned)(ptrdiff_t)p & (7 - (Z7_CRC_NUM_TABLES_USE & 4))) != 0; size--, p++)
  41. v = CRC_UPDATE_BYTE_2(v, *p);
  42. lim = p + size;
  43. if (size >= Z7_CRC_NUM_TABLES_USE)
  44. {
  45. lim -= Z7_CRC_NUM_TABLES_USE;
  46. do
  47. {
  48. v ^= R(0);
  49. {
  50. #if Z7_CRC_NUM_TABLES_USE == 1 * 4
  51. v = Q(0, v);
  52. #else
  53. #define U2(r, op) \
  54. { d = R(r); x op Q(Z7_CRC_NUM_TABLES_USE / 4 - 1 - (r), d); }
  55. UInt32 d, x;
  56. U2(1, =)
  57. #if Z7_CRC_NUM_TABLES_USE >= 3 * 4
  58. #define U(r) U2(r, ^=)
  59. U(2)
  60. #if Z7_CRC_NUM_TABLES_USE >= 4 * 4
  61. U(3)
  62. #if Z7_CRC_NUM_TABLES_USE >= 5 * 4
  63. U(4)
  64. #if Z7_CRC_NUM_TABLES_USE >= 6 * 4
  65. U(5)
  66. #if Z7_CRC_NUM_TABLES_USE >= 7 * 4
  67. #error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES
  68. #endif
  69. #endif
  70. #endif
  71. #endif
  72. #endif
  73. #undef U
  74. #undef U2
  75. v = x ^ Q(Z7_CRC_NUM_TABLES_USE / 4 - 1, v);
  76. #endif
  77. }
  78. p += Z7_CRC_NUM_TABLES_USE;
  79. }
  80. while (p <= lim);
  81. lim += Z7_CRC_NUM_TABLES_USE;
  82. }
  83. for (; p < lim; p++)
  84. v = CRC_UPDATE_BYTE_2(v, *p);
  85. return v;
  86. }
  87. #undef CRC_UPDATE_BYTE_2
  88. #undef R
  89. #undef Q
  90. #undef CRC_FUNC_PRE_LE
  91. #undef CRC_FUNC_PRE_LE2
  92. #endif
  93. #ifndef MY_CPU_LE
  94. #define CRC_UPDATE_BYTE_2_BE(crc, b) (table[((crc) >> 24) ^ (b)] ^ ((crc) << 8))
  95. #define Q(n, d) \
  96. ( (table + ((n) * 4 + 0) * 0x100)[((d)) & 0xFF] \
  97. ^ (table + ((n) * 4 + 1) * 0x100)[((d) >> 1 * 8) & 0xFF] \
  98. ^ (table + ((n) * 4 + 2) * 0x100)[((d) >> 2 * 8) & 0xFF] \
  99. ^ (table + ((n) * 4 + 3) * 0x100)[((d) >> 3 * 8)] )
  100. #ifdef Z7_CRC_DEBUG_BE
  101. #define R(a) GetBe32a((const UInt32 *)(const void *)p + (a))
  102. #else
  103. #define R(a) *((const UInt32 *)(const void *)p + (a))
  104. #endif
  105. #define CRC_FUNC_PRE_BE2(step) \
  106. UInt32 Z7_FASTCALL CrcUpdateT1_BeT ## step (UInt32 v, const void *data, size_t size, const UInt32 *table)
  107. #define CRC_FUNC_PRE_BE(step) \
  108. CRC_FUNC_PRE_BE2(step); \
  109. CRC_FUNC_PRE_BE2(step)
  110. CRC_FUNC_PRE_BE(Z7_CRC_NUM_TABLES_USE)
  111. {
  112. const Byte *p = (const Byte *)data;
  113. const Byte *lim;
  114. table += 0x100;
  115. v = Z7_BSWAP32(v);
  116. for (; size && ((unsigned)(ptrdiff_t)p & (7 - (Z7_CRC_NUM_TABLES_USE & 4))) != 0; size--, p++)
  117. v = CRC_UPDATE_BYTE_2_BE(v, *p);
  118. lim = p + size;
  119. if (size >= Z7_CRC_NUM_TABLES_USE)
  120. {
  121. lim -= Z7_CRC_NUM_TABLES_USE;
  122. do
  123. {
  124. v ^= R(0);
  125. {
  126. #if Z7_CRC_NUM_TABLES_USE == 1 * 4
  127. v = Q(0, v);
  128. #else
  129. #define U2(r, op) \
  130. { d = R(r); x op Q(Z7_CRC_NUM_TABLES_USE / 4 - 1 - (r), d); }
  131. UInt32 d, x;
  132. U2(1, =)
  133. #if Z7_CRC_NUM_TABLES_USE >= 3 * 4
  134. #define U(r) U2(r, ^=)
  135. U(2)
  136. #if Z7_CRC_NUM_TABLES_USE >= 4 * 4
  137. U(3)
  138. #if Z7_CRC_NUM_TABLES_USE >= 5 * 4
  139. U(4)
  140. #if Z7_CRC_NUM_TABLES_USE >= 6 * 4
  141. U(5)
  142. #if Z7_CRC_NUM_TABLES_USE >= 7 * 4
  143. #error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES
  144. #endif
  145. #endif
  146. #endif
  147. #endif
  148. #endif
  149. #undef U
  150. #undef U2
  151. v = x ^ Q(Z7_CRC_NUM_TABLES_USE / 4 - 1, v);
  152. #endif
  153. }
  154. p += Z7_CRC_NUM_TABLES_USE;
  155. }
  156. while (p <= lim);
  157. lim += Z7_CRC_NUM_TABLES_USE;
  158. }
  159. for (; p < lim; p++)
  160. v = CRC_UPDATE_BYTE_2_BE(v, *p);
  161. return Z7_BSWAP32(v);
  162. }
  163. #undef CRC_UPDATE_BYTE_2_BE
  164. #undef R
  165. #undef Q
  166. #undef CRC_FUNC_PRE_BE
  167. #undef CRC_FUNC_PRE_BE2
  168. #endif
  169. #undef Z7_CRC_NUM_TABLES_USE
  170. #endif