md5block_arm.s 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. // Copyright 2013 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. //
  5. // ARM version of md5block.go
  6. #include "textflag.h"
  7. // Register definitions
  8. #define Rtable R0 // Pointer to MD5 constants table
  9. #define Rdata R1 // Pointer to data to hash
  10. #define Ra R2 // MD5 accumulator
  11. #define Rb R3 // MD5 accumulator
  12. #define Rc R4 // MD5 accumulator
  13. #define Rd R5 // MD5 accumulator
  14. #define Rc0 R6 // MD5 constant
  15. #define Rc1 R7 // MD5 constant
  16. #define Rc2 R8 // MD5 constant
  17. // r9, r10 are forbidden
  18. // r11 is OK provided you check the assembler that no synthetic instructions use it
  19. #define Rc3 R11 // MD5 constant
  20. #define Rt0 R12 // temporary
  21. #define Rt1 R14 // temporary
  22. // func block(dig *digest, p []byte)
  23. // 0(FP) is *digest
  24. // 4(FP) is p.array (struct Slice)
  25. // 8(FP) is p.len
  26. //12(FP) is p.cap
  27. //
  28. // Stack frame
  29. #define p_end end-4(SP) // pointer to the end of data
  30. #define p_data data-8(SP) // current data pointer
  31. #define buf buffer-(8+4*16)(SP) //16 words temporary buffer
  32. // 3 words at 4..12(R13) for called routine parameters
  33. TEXT ·block(SB), NOSPLIT, $84-16
  34. MOVW p+4(FP), Rdata // pointer to the data
  35. MOVW p_len+8(FP), Rt0 // number of bytes
  36. ADD Rdata, Rt0
  37. MOVW Rt0, p_end // pointer to end of data
  38. loop:
  39. MOVW Rdata, p_data // Save Rdata
  40. AND.S $3, Rdata, Rt0 // TST $3, Rdata not working see issue 5921
  41. BEQ aligned // aligned detected - skip copy
  42. // Copy the unaligned source data into the aligned temporary buffer
  43. // memove(to=4(R13), from=8(R13), n=12(R13)) - Corrupts all registers
  44. MOVW $buf, Rtable // to
  45. MOVW $64, Rc0 // n
  46. MOVM.IB [Rtable,Rdata,Rc0], (R13)
  47. BL runtime·memmove(SB)
  48. // Point to the local aligned copy of the data
  49. MOVW $buf, Rdata
  50. aligned:
  51. // Point to the table of constants
  52. // A PC relative add would be cheaper than this
  53. MOVW $·table(SB), Rtable
  54. // Load up initial MD5 accumulator
  55. MOVW dig+0(FP), Rc0
  56. MOVM.IA (Rc0), [Ra,Rb,Rc,Rd]
  57. // a += (((c^d)&b)^d) + X[index] + const
  58. // a = a<<shift | a>>(32-shift) + b
  59. #define ROUND1(Ra, Rb, Rc, Rd, index, shift, Rconst) \
  60. EOR Rc, Rd, Rt0 ; \
  61. AND Rb, Rt0 ; \
  62. EOR Rd, Rt0 ; \
  63. MOVW (index<<2)(Rdata), Rt1 ; \
  64. ADD Rt1, Rt0 ; \
  65. ADD Rconst, Rt0 ; \
  66. ADD Rt0, Ra ; \
  67. ADD Ra@>(32-shift), Rb, Ra ;
  68. MOVM.IA.W (Rtable), [Rc0,Rc1,Rc2,Rc3]
  69. ROUND1(Ra, Rb, Rc, Rd, 0, 7, Rc0)
  70. ROUND1(Rd, Ra, Rb, Rc, 1, 12, Rc1)
  71. ROUND1(Rc, Rd, Ra, Rb, 2, 17, Rc2)
  72. ROUND1(Rb, Rc, Rd, Ra, 3, 22, Rc3)
  73. MOVM.IA.W (Rtable), [Rc0,Rc1,Rc2,Rc3]
  74. ROUND1(Ra, Rb, Rc, Rd, 4, 7, Rc0)
  75. ROUND1(Rd, Ra, Rb, Rc, 5, 12, Rc1)
  76. ROUND1(Rc, Rd, Ra, Rb, 6, 17, Rc2)
  77. ROUND1(Rb, Rc, Rd, Ra, 7, 22, Rc3)
  78. MOVM.IA.W (Rtable), [Rc0,Rc1,Rc2,Rc3]
  79. ROUND1(Ra, Rb, Rc, Rd, 8, 7, Rc0)
  80. ROUND1(Rd, Ra, Rb, Rc, 9, 12, Rc1)
  81. ROUND1(Rc, Rd, Ra, Rb, 10, 17, Rc2)
  82. ROUND1(Rb, Rc, Rd, Ra, 11, 22, Rc3)
  83. MOVM.IA.W (Rtable), [Rc0,Rc1,Rc2,Rc3]
  84. ROUND1(Ra, Rb, Rc, Rd, 12, 7, Rc0)
  85. ROUND1(Rd, Ra, Rb, Rc, 13, 12, Rc1)
  86. ROUND1(Rc, Rd, Ra, Rb, 14, 17, Rc2)
  87. ROUND1(Rb, Rc, Rd, Ra, 15, 22, Rc3)
  88. // a += (((b^c)&d)^c) + X[index] + const
  89. // a = a<<shift | a>>(32-shift) + b
  90. #define ROUND2(Ra, Rb, Rc, Rd, index, shift, Rconst) \
  91. EOR Rb, Rc, Rt0 ; \
  92. AND Rd, Rt0 ; \
  93. EOR Rc, Rt0 ; \
  94. MOVW (index<<2)(Rdata), Rt1 ; \
  95. ADD Rt1, Rt0 ; \
  96. ADD Rconst, Rt0 ; \
  97. ADD Rt0, Ra ; \
  98. ADD Ra@>(32-shift), Rb, Ra ;
  99. MOVM.IA.W (Rtable), [Rc0,Rc1,Rc2,Rc3]
  100. ROUND2(Ra, Rb, Rc, Rd, 1, 5, Rc0)
  101. ROUND2(Rd, Ra, Rb, Rc, 6, 9, Rc1)
  102. ROUND2(Rc, Rd, Ra, Rb, 11, 14, Rc2)
  103. ROUND2(Rb, Rc, Rd, Ra, 0, 20, Rc3)
  104. MOVM.IA.W (Rtable), [Rc0,Rc1,Rc2,Rc3]
  105. ROUND2(Ra, Rb, Rc, Rd, 5, 5, Rc0)
  106. ROUND2(Rd, Ra, Rb, Rc, 10, 9, Rc1)
  107. ROUND2(Rc, Rd, Ra, Rb, 15, 14, Rc2)
  108. ROUND2(Rb, Rc, Rd, Ra, 4, 20, Rc3)
  109. MOVM.IA.W (Rtable), [Rc0,Rc1,Rc2,Rc3]
  110. ROUND2(Ra, Rb, Rc, Rd, 9, 5, Rc0)
  111. ROUND2(Rd, Ra, Rb, Rc, 14, 9, Rc1)
  112. ROUND2(Rc, Rd, Ra, Rb, 3, 14, Rc2)
  113. ROUND2(Rb, Rc, Rd, Ra, 8, 20, Rc3)
  114. MOVM.IA.W (Rtable), [Rc0,Rc1,Rc2,Rc3]
  115. ROUND2(Ra, Rb, Rc, Rd, 13, 5, Rc0)
  116. ROUND2(Rd, Ra, Rb, Rc, 2, 9, Rc1)
  117. ROUND2(Rc, Rd, Ra, Rb, 7, 14, Rc2)
  118. ROUND2(Rb, Rc, Rd, Ra, 12, 20, Rc3)
  119. // a += (b^c^d) + X[index] + const
  120. // a = a<<shift | a>>(32-shift) + b
  121. #define ROUND3(Ra, Rb, Rc, Rd, index, shift, Rconst) \
  122. EOR Rb, Rc, Rt0 ; \
  123. EOR Rd, Rt0 ; \
  124. MOVW (index<<2)(Rdata), Rt1 ; \
  125. ADD Rt1, Rt0 ; \
  126. ADD Rconst, Rt0 ; \
  127. ADD Rt0, Ra ; \
  128. ADD Ra@>(32-shift), Rb, Ra ;
  129. MOVM.IA.W (Rtable), [Rc0,Rc1,Rc2,Rc3]
  130. ROUND3(Ra, Rb, Rc, Rd, 5, 4, Rc0)
  131. ROUND3(Rd, Ra, Rb, Rc, 8, 11, Rc1)
  132. ROUND3(Rc, Rd, Ra, Rb, 11, 16, Rc2)
  133. ROUND3(Rb, Rc, Rd, Ra, 14, 23, Rc3)
  134. MOVM.IA.W (Rtable), [Rc0,Rc1,Rc2,Rc3]
  135. ROUND3(Ra, Rb, Rc, Rd, 1, 4, Rc0)
  136. ROUND3(Rd, Ra, Rb, Rc, 4, 11, Rc1)
  137. ROUND3(Rc, Rd, Ra, Rb, 7, 16, Rc2)
  138. ROUND3(Rb, Rc, Rd, Ra, 10, 23, Rc3)
  139. MOVM.IA.W (Rtable), [Rc0,Rc1,Rc2,Rc3]
  140. ROUND3(Ra, Rb, Rc, Rd, 13, 4, Rc0)
  141. ROUND3(Rd, Ra, Rb, Rc, 0, 11, Rc1)
  142. ROUND3(Rc, Rd, Ra, Rb, 3, 16, Rc2)
  143. ROUND3(Rb, Rc, Rd, Ra, 6, 23, Rc3)
  144. MOVM.IA.W (Rtable), [Rc0,Rc1,Rc2,Rc3]
  145. ROUND3(Ra, Rb, Rc, Rd, 9, 4, Rc0)
  146. ROUND3(Rd, Ra, Rb, Rc, 12, 11, Rc1)
  147. ROUND3(Rc, Rd, Ra, Rb, 15, 16, Rc2)
  148. ROUND3(Rb, Rc, Rd, Ra, 2, 23, Rc3)
  149. // a += (c^(b|^d)) + X[index] + const
  150. // a = a<<shift | a>>(32-shift) + b
  151. #define ROUND4(Ra, Rb, Rc, Rd, index, shift, Rconst) \
  152. MVN Rd, Rt0 ; \
  153. ORR Rb, Rt0 ; \
  154. EOR Rc, Rt0 ; \
  155. MOVW (index<<2)(Rdata), Rt1 ; \
  156. ADD Rt1, Rt0 ; \
  157. ADD Rconst, Rt0 ; \
  158. ADD Rt0, Ra ; \
  159. ADD Ra@>(32-shift), Rb, Ra ;
  160. MOVM.IA.W (Rtable), [Rc0,Rc1,Rc2,Rc3]
  161. ROUND4(Ra, Rb, Rc, Rd, 0, 6, Rc0)
  162. ROUND4(Rd, Ra, Rb, Rc, 7, 10, Rc1)
  163. ROUND4(Rc, Rd, Ra, Rb, 14, 15, Rc2)
  164. ROUND4(Rb, Rc, Rd, Ra, 5, 21, Rc3)
  165. MOVM.IA.W (Rtable), [Rc0,Rc1,Rc2,Rc3]
  166. ROUND4(Ra, Rb, Rc, Rd, 12, 6, Rc0)
  167. ROUND4(Rd, Ra, Rb, Rc, 3, 10, Rc1)
  168. ROUND4(Rc, Rd, Ra, Rb, 10, 15, Rc2)
  169. ROUND4(Rb, Rc, Rd, Ra, 1, 21, Rc3)
  170. MOVM.IA.W (Rtable), [Rc0,Rc1,Rc2,Rc3]
  171. ROUND4(Ra, Rb, Rc, Rd, 8, 6, Rc0)
  172. ROUND4(Rd, Ra, Rb, Rc, 15, 10, Rc1)
  173. ROUND4(Rc, Rd, Ra, Rb, 6, 15, Rc2)
  174. ROUND4(Rb, Rc, Rd, Ra, 13, 21, Rc3)
  175. MOVM.IA.W (Rtable), [Rc0,Rc1,Rc2,Rc3]
  176. ROUND4(Ra, Rb, Rc, Rd, 4, 6, Rc0)
  177. ROUND4(Rd, Ra, Rb, Rc, 11, 10, Rc1)
  178. ROUND4(Rc, Rd, Ra, Rb, 2, 15, Rc2)
  179. ROUND4(Rb, Rc, Rd, Ra, 9, 21, Rc3)
  180. MOVW dig+0(FP), Rt0
  181. MOVM.IA (Rt0), [Rc0,Rc1,Rc2,Rc3]
  182. ADD Rc0, Ra
  183. ADD Rc1, Rb
  184. ADD Rc2, Rc
  185. ADD Rc3, Rd
  186. MOVM.IA [Ra,Rb,Rc,Rd], (Rt0)
  187. MOVW p_data, Rdata
  188. MOVW p_end, Rt0
  189. ADD $64, Rdata
  190. CMP Rt0, Rdata
  191. BLO loop
  192. RET
  193. // MD5 constants table
  194. // Round 1
  195. DATA ·table+0x00(SB)/4, $0xd76aa478
  196. DATA ·table+0x04(SB)/4, $0xe8c7b756
  197. DATA ·table+0x08(SB)/4, $0x242070db
  198. DATA ·table+0x0c(SB)/4, $0xc1bdceee
  199. DATA ·table+0x10(SB)/4, $0xf57c0faf
  200. DATA ·table+0x14(SB)/4, $0x4787c62a
  201. DATA ·table+0x18(SB)/4, $0xa8304613
  202. DATA ·table+0x1c(SB)/4, $0xfd469501
  203. DATA ·table+0x20(SB)/4, $0x698098d8
  204. DATA ·table+0x24(SB)/4, $0x8b44f7af
  205. DATA ·table+0x28(SB)/4, $0xffff5bb1
  206. DATA ·table+0x2c(SB)/4, $0x895cd7be
  207. DATA ·table+0x30(SB)/4, $0x6b901122
  208. DATA ·table+0x34(SB)/4, $0xfd987193
  209. DATA ·table+0x38(SB)/4, $0xa679438e
  210. DATA ·table+0x3c(SB)/4, $0x49b40821
  211. // Round 2
  212. DATA ·table+0x40(SB)/4, $0xf61e2562
  213. DATA ·table+0x44(SB)/4, $0xc040b340
  214. DATA ·table+0x48(SB)/4, $0x265e5a51
  215. DATA ·table+0x4c(SB)/4, $0xe9b6c7aa
  216. DATA ·table+0x50(SB)/4, $0xd62f105d
  217. DATA ·table+0x54(SB)/4, $0x02441453
  218. DATA ·table+0x58(SB)/4, $0xd8a1e681
  219. DATA ·table+0x5c(SB)/4, $0xe7d3fbc8
  220. DATA ·table+0x60(SB)/4, $0x21e1cde6
  221. DATA ·table+0x64(SB)/4, $0xc33707d6
  222. DATA ·table+0x68(SB)/4, $0xf4d50d87
  223. DATA ·table+0x6c(SB)/4, $0x455a14ed
  224. DATA ·table+0x70(SB)/4, $0xa9e3e905
  225. DATA ·table+0x74(SB)/4, $0xfcefa3f8
  226. DATA ·table+0x78(SB)/4, $0x676f02d9
  227. DATA ·table+0x7c(SB)/4, $0x8d2a4c8a
  228. // Round 3
  229. DATA ·table+0x80(SB)/4, $0xfffa3942
  230. DATA ·table+0x84(SB)/4, $0x8771f681
  231. DATA ·table+0x88(SB)/4, $0x6d9d6122
  232. DATA ·table+0x8c(SB)/4, $0xfde5380c
  233. DATA ·table+0x90(SB)/4, $0xa4beea44
  234. DATA ·table+0x94(SB)/4, $0x4bdecfa9
  235. DATA ·table+0x98(SB)/4, $0xf6bb4b60
  236. DATA ·table+0x9c(SB)/4, $0xbebfbc70
  237. DATA ·table+0xa0(SB)/4, $0x289b7ec6
  238. DATA ·table+0xa4(SB)/4, $0xeaa127fa
  239. DATA ·table+0xa8(SB)/4, $0xd4ef3085
  240. DATA ·table+0xac(SB)/4, $0x04881d05
  241. DATA ·table+0xb0(SB)/4, $0xd9d4d039
  242. DATA ·table+0xb4(SB)/4, $0xe6db99e5
  243. DATA ·table+0xb8(SB)/4, $0x1fa27cf8
  244. DATA ·table+0xbc(SB)/4, $0xc4ac5665
  245. // Round 4
  246. DATA ·table+0xc0(SB)/4, $0xf4292244
  247. DATA ·table+0xc4(SB)/4, $0x432aff97
  248. DATA ·table+0xc8(SB)/4, $0xab9423a7
  249. DATA ·table+0xcc(SB)/4, $0xfc93a039
  250. DATA ·table+0xd0(SB)/4, $0x655b59c3
  251. DATA ·table+0xd4(SB)/4, $0x8f0ccc92
  252. DATA ·table+0xd8(SB)/4, $0xffeff47d
  253. DATA ·table+0xdc(SB)/4, $0x85845dd1
  254. DATA ·table+0xe0(SB)/4, $0x6fa87e4f
  255. DATA ·table+0xe4(SB)/4, $0xfe2ce6e0
  256. DATA ·table+0xe8(SB)/4, $0xa3014314
  257. DATA ·table+0xec(SB)/4, $0x4e0811a1
  258. DATA ·table+0xf0(SB)/4, $0xf7537e82
  259. DATA ·table+0xf4(SB)/4, $0xbd3af235
  260. DATA ·table+0xf8(SB)/4, $0x2ad7d2bb
  261. DATA ·table+0xfc(SB)/4, $0xeb86d391
  262. // Global definition
  263. GLOBL ·table(SB),8,$256