csum_64plus.S 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. ; SPDX-License-Identifier: GPL-2.0-only
  2. ;
  3. ; linux/arch/c6x/lib/csum_64plus.s
  4. ;
  5. ; Port on Texas Instruments TMS320C6x architecture
  6. ;
  7. ; Copyright (C) 2006, 2009, 2010, 2011 Texas Instruments Incorporated
  8. ; Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
  9. ;
  10. #include <linux/linkage.h>
  11. ;
  12. ;unsigned int csum_partial_copy_nocheck(const char *src, char * dst,
  13. ; int len, int sum)
  14. ;
  15. ; A4: src
  16. ; B4: dst
  17. ; A6: len
  18. ; B6: sum
  19. ; return csum in A4
  20. ;
  21. .text
  22. ENTRY(csum_partial_copy_nocheck)
  23. MVC .S2 ILC,B30
  24. ZERO .D1 A9 ; csum (a side)
  25. || ZERO .D2 B9 ; csum (b side)
  26. || SHRU .S2X A6,2,B5 ; len / 4
  27. ;; Check alignment and size
  28. AND .S1 3,A4,A1
  29. || AND .S2 3,B4,B0
  30. OR .L2X B0,A1,B0 ; non aligned condition
  31. || MVC .S2 B5,ILC
  32. || MVK .D2 1,B2
  33. || MV .D1X B5,A1 ; words condition
  34. [!A1] B .S1 L8
  35. [B0] BNOP .S1 L6,5
  36. SPLOOP 1
  37. ;; Main loop for aligned words
  38. LDW .D1T1 *A4++,A7
  39. NOP 4
  40. MV .S2X A7,B7
  41. || EXTU .S1 A7,0,16,A16
  42. STW .D2T2 B7,*B4++
  43. || MPYU .M2 B7,B2,B8
  44. || ADD .L1 A16,A9,A9
  45. NOP
  46. SPKERNEL 8,0
  47. || ADD .L2 B8,B9,B9
  48. ZERO .D1 A1
  49. || ADD .L1X A9,B9,A9 ; add csum from a and b sides
  50. L6:
  51. [!A1] BNOP .S1 L8,5
  52. ;; Main loop for non-aligned words
  53. SPLOOP 2
  54. || MVK .L1 1,A2
  55. LDNW .D1T1 *A4++,A7
  56. NOP 3
  57. NOP
  58. MV .S2X A7,B7
  59. || EXTU .S1 A7,0,16,A16
  60. || MPYU .M1 A7,A2,A8
  61. ADD .L1 A16,A9,A9
  62. SPKERNEL 6,0
  63. || STNW .D2T2 B7,*B4++
  64. || ADD .L1 A8,A9,A9
  65. L8: AND .S2X 2,A6,B5
  66. CMPGT .L2 B5,0,B0
  67. [!B0] BNOP .S1 L82,4
  68. ;; Manage half-word
  69. ZERO .L1 A7
  70. || ZERO .D1 A8
  71. #ifdef CONFIG_CPU_BIG_ENDIAN
  72. LDBU .D1T1 *A4++,A7
  73. LDBU .D1T1 *A4++,A8
  74. NOP 3
  75. SHL .S1 A7,8,A0
  76. ADD .S1 A8,A9,A9
  77. STB .D2T1 A7,*B4++
  78. || ADD .S1 A0,A9,A9
  79. STB .D2T1 A8,*B4++
  80. #else
  81. LDBU .D1T1 *A4++,A7
  82. LDBU .D1T1 *A4++,A8
  83. NOP 3
  84. ADD .S1 A7,A9,A9
  85. SHL .S1 A8,8,A0
  86. STB .D2T1 A7,*B4++
  87. || ADD .S1 A0,A9,A9
  88. STB .D2T1 A8,*B4++
  89. #endif
  90. ;; Manage eventually the last byte
  91. L82: AND .S2X 1,A6,B0
  92. [!B0] BNOP .S1 L9,5
  93. || ZERO .L1 A7
  94. L83: LDBU .D1T1 *A4++,A7
  95. NOP 4
  96. MV .L2X A7,B7
  97. #ifdef CONFIG_CPU_BIG_ENDIAN
  98. STB .D2T2 B7,*B4++
  99. || SHL .S1 A7,8,A7
  100. ADD .S1 A7,A9,A9
  101. #else
  102. STB .D2T2 B7,*B4++
  103. || ADD .S1 A7,A9,A9
  104. #endif
  105. ;; Fold the csum
  106. L9: SHRU .S2X A9,16,B0
  107. [!B0] BNOP .S1 L10,5
  108. L91: SHRU .S2X A9,16,B4
  109. || EXTU .S1 A9,16,16,A3
  110. ADD .D1X A3,B4,A9
  111. SHRU .S1 A9,16,A0
  112. [A0] BNOP .S1 L91,5
  113. L10: MV .D1 A9,A4
  114. BNOP .S2 B3,4
  115. MVC .S2 B30,ILC
  116. ENDPROC(csum_partial_copy_nocheck)
  117. ;
  118. ;unsigned short
  119. ;ip_fast_csum(unsigned char *iph, unsigned int ihl)
  120. ;{
  121. ; unsigned int checksum = 0;
  122. ; unsigned short *tosum = (unsigned short *) iph;
  123. ; int len;
  124. ;
  125. ; len = ihl*4;
  126. ;
  127. ; if (len <= 0)
  128. ; return 0;
  129. ;
  130. ; while(len) {
  131. ; len -= 2;
  132. ; checksum += *tosum++;
  133. ; }
  134. ; if (len & 1)
  135. ; checksum += *(unsigned char*) tosum;
  136. ;
  137. ; while(checksum >> 16)
  138. ; checksum = (checksum & 0xffff) + (checksum >> 16);
  139. ;
  140. ; return ~checksum;
  141. ;}
  142. ;
  143. ; A4: iph
  144. ; B4: ihl
  145. ; return checksum in A4
  146. ;
  147. .text
  148. ENTRY(ip_fast_csum)
  149. ZERO .D1 A5
  150. || MVC .S2 ILC,B30
  151. SHL .S2 B4,2,B0
  152. CMPGT .L2 B0,0,B1
  153. [!B1] BNOP .S1 L15,4
  154. [!B1] ZERO .D1 A3
  155. [!B0] B .S1 L12
  156. SHRU .S2 B0,1,B0
  157. MVC .S2 B0,ILC
  158. NOP 3
  159. SPLOOP 1
  160. LDHU .D1T1 *A4++,A3
  161. NOP 3
  162. NOP
  163. SPKERNEL 5,0
  164. || ADD .L1 A3,A5,A5
  165. L12: SHRU .S1 A5,16,A0
  166. [!A0] BNOP .S1 L14,5
  167. L13: SHRU .S2X A5,16,B4
  168. EXTU .S1 A5,16,16,A3
  169. ADD .D1X A3,B4,A5
  170. SHRU .S1 A5,16,A0
  171. [A0] BNOP .S1 L13,5
  172. L14: NOT .D1 A5,A3
  173. EXTU .S1 A3,16,16,A3
  174. L15: BNOP .S2 B3,3
  175. MVC .S2 B30,ILC
  176. MV .D1 A3,A4
  177. ENDPROC(ip_fast_csum)
  178. ;
  179. ;unsigned short
  180. ;do_csum(unsigned char *buff, unsigned int len)
  181. ;{
  182. ; int odd, count;
  183. ; unsigned int result = 0;
  184. ;
  185. ; if (len <= 0)
  186. ; goto out;
  187. ; odd = 1 & (unsigned long) buff;
  188. ; if (odd) {
  189. ;#ifdef __LITTLE_ENDIAN
  190. ; result += (*buff << 8);
  191. ;#else
  192. ; result = *buff;
  193. ;#endif
  194. ; len--;
  195. ; buff++;
  196. ; }
  197. ; count = len >> 1; /* nr of 16-bit words.. */
  198. ; if (count) {
  199. ; if (2 & (unsigned long) buff) {
  200. ; result += *(unsigned short *) buff;
  201. ; count--;
  202. ; len -= 2;
  203. ; buff += 2;
  204. ; }
  205. ; count >>= 1; /* nr of 32-bit words.. */
  206. ; if (count) {
  207. ; unsigned int carry = 0;
  208. ; do {
  209. ; unsigned int w = *(unsigned int *) buff;
  210. ; count--;
  211. ; buff += 4;
  212. ; result += carry;
  213. ; result += w;
  214. ; carry = (w > result);
  215. ; } while (count);
  216. ; result += carry;
  217. ; result = (result & 0xffff) + (result >> 16);
  218. ; }
  219. ; if (len & 2) {
  220. ; result += *(unsigned short *) buff;
  221. ; buff += 2;
  222. ; }
  223. ; }
  224. ; if (len & 1)
  225. ;#ifdef __LITTLE_ENDIAN
  226. ; result += *buff;
  227. ;#else
  228. ; result += (*buff << 8);
  229. ;#endif
  230. ; result = (result & 0xffff) + (result >> 16);
  231. ; /* add up carry.. */
  232. ; result = (result & 0xffff) + (result >> 16);
  233. ; if (odd)
  234. ; result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
  235. ;out:
  236. ; return result;
  237. ;}
  238. ;
  239. ; A4: buff
  240. ; B4: len
  241. ; return checksum in A4
  242. ;
  243. ENTRY(do_csum)
  244. CMPGT .L2 B4,0,B0
  245. [!B0] BNOP .S1 L26,3
  246. EXTU .S1 A4,31,31,A0
  247. MV .L1 A0,A3
  248. || MV .S1X B3,A5
  249. || MV .L2 B4,B3
  250. || ZERO .D1 A1
  251. #ifdef CONFIG_CPU_BIG_ENDIAN
  252. [A0] SUB .L2 B3,1,B3
  253. || [A0] LDBU .D1T1 *A4++,A1
  254. #else
  255. [!A0] BNOP .S1 L21,5
  256. || [A0] LDBU .D1T1 *A4++,A0
  257. SUB .L2 B3,1,B3
  258. || SHL .S1 A0,8,A1
  259. L21:
  260. #endif
  261. SHR .S2 B3,1,B0
  262. [!B0] BNOP .S1 L24,3
  263. MVK .L1 2,A0
  264. AND .L1 A4,A0,A0
  265. [!A0] BNOP .S1 L22,5
  266. || [A0] LDHU .D1T1 *A4++,A0
  267. SUB .L2 B0,1,B0
  268. || SUB .S2 B3,2,B3
  269. || ADD .L1 A0,A1,A1
  270. L22:
  271. SHR .S2 B0,1,B0
  272. || ZERO .L1 A0
  273. [!B0] BNOP .S1 L23,5
  274. || [B0] MVC .S2 B0,ILC
  275. SPLOOP 3
  276. SPMASK L1
  277. || MV .L1 A1,A2
  278. || LDW .D1T1 *A4++,A1
  279. NOP 4
  280. ADD .L1 A0,A1,A0
  281. ADD .L1 A2,A0,A2
  282. SPKERNEL 1,2
  283. || CMPGTU .L1 A1,A2,A0
  284. ADD .L1 A0,A2,A6
  285. EXTU .S1 A6,16,16,A7
  286. SHRU .S2X A6,16,B0
  287. NOP 1
  288. ADD .L1X A7,B0,A1
  289. L23:
  290. MVK .L2 2,B0
  291. AND .L2 B3,B0,B0
  292. [B0] LDHU .D1T1 *A4++,A0
  293. NOP 4
  294. [B0] ADD .L1 A0,A1,A1
  295. L24:
  296. EXTU .S2 B3,31,31,B0
  297. #ifdef CONFIG_CPU_BIG_ENDIAN
  298. [!B0] BNOP .S1 L25,4
  299. || [B0] LDBU .D1T1 *A4,A0
  300. SHL .S1 A0,8,A0
  301. ADD .L1 A0,A1,A1
  302. L25:
  303. #else
  304. [B0] LDBU .D1T1 *A4,A0
  305. NOP 4
  306. [B0] ADD .L1 A0,A1,A1
  307. #endif
  308. EXTU .S1 A1,16,16,A0
  309. SHRU .S2X A1,16,B0
  310. NOP 1
  311. ADD .L1X A0,B0,A0
  312. SHRU .S1 A0,16,A1
  313. ADD .L1 A0,A1,A0
  314. EXTU .S1 A0,16,16,A1
  315. EXTU .S1 A1,16,24,A2
  316. EXTU .S1 A1,24,16,A0
  317. || MV .L2X A3,B0
  318. [B0] OR .L1 A0,A2,A1
  319. L26:
  320. NOP 1
  321. BNOP .S2X A5,4
  322. MV .L1 A1,A4
  323. ENDPROC(do_csum)
  324. ;__wsum csum_partial(const void *buff, int len, __wsum wsum)
  325. ;{
  326. ; unsigned int sum = (__force unsigned int)wsum;
  327. ; unsigned int result = do_csum(buff, len);
  328. ;
  329. ; /* add in old sum, and carry.. */
  330. ; result += sum;
  331. ; if (sum > result)
  332. ; result += 1;
  333. ; return (__force __wsum)result;
  334. ;}
  335. ;
  336. ENTRY(csum_partial)
  337. MV .L1X B3,A9
  338. || CALLP .S2 do_csum,B3
  339. || MV .S1 A6,A8
  340. BNOP .S2X A9,2
  341. ADD .L1 A8,A4,A1
  342. CMPGTU .L1 A8,A1,A0
  343. ADD .L1 A1,A0,A4
  344. ENDPROC(csum_partial)
  345. ;unsigned short
  346. ;ip_compute_csum(unsigned char *buff, unsigned int len)
  347. ;
  348. ; A4: buff
  349. ; B4: len
  350. ; return checksum in A4
  351. ENTRY(ip_compute_csum)
  352. MV .L1X B3,A9
  353. || CALLP .S2 do_csum,B3
  354. BNOP .S2X A9,3
  355. NOT .S1 A4,A4
  356. CLR .S1 A4,16,31,A4
  357. ENDPROC(ip_compute_csum)