csumpartial.S
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/arch/arm/lib/csumpartial.S
  3.  *
  4.  *  Copyright (C) 1995-1998 Russell King
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License version 2 as
  8.  * published by the Free Software Foundation.
  9.  */
  10. #include <linux/linkage.h>
  11. #include <asm/assembler.h>
  12. .text
  13. /*
  14.  * Function: __u32 csum_partial(const char *src, int len, __u32 sum)
  15.  * Params  : r0 = buffer, r1 = len, r2 = checksum
  16.  * Returns : r0 = new checksum
  17.  */
  18. buf .req r0
  19. len .req r1
  20. sum .req r2
  21. td0 .req r3
  22. td1 .req r4 @ save before use
  23. td2 .req r5 @ save before use
  24. td3 .req lr
  25. .zero: mov r0, sum
  26. add sp, sp, #4
  27. ldr pc, [sp], #4
  28. /*
  29.  * Handle 0 to 7 bytes, with any alignment of source and
  30.  * destination pointers.  Note that when we get here, C = 0
  31.  */
  32. .less8: teq len, #0 @ check for zero count
  33. beq .zero
  34. /* we must have at least one byte. */
  35. tst buf, #1 @ odd address?
  36. ldrneb td0, [buf], #1
  37. subne len, len, #1
  38. adcnes sum, sum, td0, lsl #8
  39. .less4: tst len, #6
  40. beq .less8_byte
  41. /* we are now half-word aligned */
  42. .less8_wordlp:
  43. #ifdef __ARM_ARCH_4__
  44. ldrh td0, [buf], #2
  45. sub len, len, #2
  46. #else
  47. ldrb td0, [buf], #1
  48. ldrb td3, [buf], #1
  49. sub len, len, #2
  50. orr td0, td0, td3, lsl #8
  51. #endif
  52. adcs sum, sum, td0
  53. tst len, #6
  54. bne .less8_wordlp
  55. .less8_byte: tst len, #1 @ odd number of bytes
  56. ldrneb td0, [buf], #1 @ include last byte
  57. adcnes sum, sum, td0 @ update checksum
  58. .done: adc r0, sum, #0 @ collect up the last carry
  59. ldr td0, [sp], #4
  60. tst td0, #1 @ check buffer alignment
  61. movne td0, r0, lsl #8 @ rotate checksum by 8 bits
  62. orrne r0, td0, r0, lsr #24
  63. ldr pc, [sp], #4 @ return
  64. .not_aligned: tst buf, #1 @ odd address
  65. ldrneb td0, [buf], #1 @ make even
  66. subne len, len, #1
  67. adcnes sum, sum, td0, lsl #8 @ update checksum
  68. tst buf, #2 @ 32-bit aligned?
  69. #ifdef __ARM_ARCH_4__
  70. ldrneh td0, [buf], #2 @ make 32-bit aligned
  71. subne len, len, #2
  72. #else
  73. ldrneb td0, [buf], #1
  74. ldrneb ip, [buf], #1
  75. subne len, len, #2
  76. orrne td0, td0, ip, lsl #8
  77. #endif
  78. adcnes sum, sum, td0 @ update checksum
  79. mov pc, lr
  80. ENTRY(csum_partial)
  81. stmfd sp!, {buf, lr}
  82. cmp len, #8 @ Ensure that we have at least
  83. blo .less8 @ 8 bytes to copy.
  84. adds sum, sum, #0 @ C = 0
  85. tst buf, #3 @ Test destination alignment
  86. blne .not_aligned @ aligh destination, return here
  87. 1: bics ip, len, #31
  88. beq 3f
  89. stmfd sp!, {r4 - r5}
  90. 2: ldmia buf!, {td0, td1, td2, td3}
  91. adcs sum, sum, td0
  92. adcs sum, sum, td1
  93. adcs sum, sum, td2
  94. adcs sum, sum, td3
  95. ldmia buf!, {td0, td1, td2, td3}
  96. adcs sum, sum, td0
  97. adcs sum, sum, td1
  98. adcs sum, sum, td2
  99. adcs sum, sum, td3
  100. sub ip, ip, #32
  101. teq ip, #0
  102. bne 2b
  103. ldmfd sp!, {r4 - r5}
  104. 3: tst len, #0x1c @ should not change C
  105. beq .less4
  106. 4: ldr td0, [buf], #4
  107. sub len, len, #4
  108. adcs sum, sum, td0
  109. tst len, #0x1c
  110. bne 4b
  111. b .less4