armv4-mont.S 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952
  1. #include "arm_arch.h"
  2. .text
  3. #if defined(__thumb2__)
  4. .syntax unified
  5. .thumb
  6. #else
  7. .code 32
  8. #endif
  9. #if __ARM_MAX_ARCH__>=7
  10. .align 5
  11. .LOPENSSL_armcap:
  12. .word OPENSSL_armcap_P-.Lbn_mul_mont
  13. #endif
  14. .global bn_mul_mont
  15. .type bn_mul_mont,%function
  16. .align 5
  17. bn_mul_mont:
  18. .Lbn_mul_mont:
  19. ldr ip,[sp,#4] @ load num
  20. stmdb sp!,{r0,r2} @ sp points at argument block
  21. #if __ARM_MAX_ARCH__>=7
  22. tst ip,#7
  23. bne .Lialu
  24. adr r0,.Lbn_mul_mont
  25. ldr r2,.LOPENSSL_armcap
  26. ldr r0,[r0,r2]
  27. #ifdef __APPLE__
  28. ldr r0,[r0]
  29. #endif
  30. tst r0,#ARMV7_NEON @ NEON available?
  31. ldmia sp, {r0,r2}
  32. beq .Lialu
  33. add sp,sp,#8
  34. b bn_mul8x_mont_neon
  35. .align 4
  36. .Lialu:
  37. #endif
  38. cmp ip,#2
  39. mov r0,ip @ load num
  40. #ifdef __thumb2__
  41. ittt lt
  42. #endif
  43. movlt r0,#0
  44. addlt sp,sp,#2*4
  45. blt .Labrt
  46. stmdb sp!,{r4-r12,lr} @ save 10 registers
  47. mov r0,r0,lsl#2 @ rescale r0 for byte count
  48. sub sp,sp,r0 @ alloca(4*num)
  49. sub sp,sp,#4 @ +extra dword
  50. sub r0,r0,#4 @ "num=num-1"
  51. add r4,r2,r0 @ &bp[num-1]
  52. add r0,sp,r0 @ r0 to point at &tp[num-1]
  53. ldr r8,[r0,#14*4] @ &n0
  54. ldr r2,[r2] @ bp[0]
  55. ldr r5,[r1],#4 @ ap[0],ap++
  56. ldr r6,[r3],#4 @ np[0],np++
  57. ldr r8,[r8] @ *n0
  58. str r4,[r0,#15*4] @ save &bp[num]
  59. umull r10,r11,r5,r2 @ ap[0]*bp[0]
  60. str r8,[r0,#14*4] @ save n0 value
  61. mul r8,r10,r8 @ "tp[0]"*n0
  62. mov r12,#0
  63. umlal r10,r12,r6,r8 @ np[0]*n0+"t[0]"
  64. mov r4,sp
  65. .L1st:
  66. ldr r5,[r1],#4 @ ap[j],ap++
  67. mov r10,r11
  68. ldr r6,[r3],#4 @ np[j],np++
  69. mov r11,#0
  70. umlal r10,r11,r5,r2 @ ap[j]*bp[0]
  71. mov r14,#0
  72. umlal r12,r14,r6,r8 @ np[j]*n0
  73. adds r12,r12,r10
  74. str r12,[r4],#4 @ tp[j-1]=,tp++
  75. adc r12,r14,#0
  76. cmp r4,r0
  77. bne .L1st
  78. adds r12,r12,r11
  79. ldr r4,[r0,#13*4] @ restore bp
  80. mov r14,#0
  81. ldr r8,[r0,#14*4] @ restore n0
  82. adc r14,r14,#0
  83. str r12,[r0] @ tp[num-1]=
  84. mov r7,sp
  85. str r14,[r0,#4] @ tp[num]=
  86. .Louter:
  87. sub r7,r0,r7 @ "original" r0-1 value
  88. sub r1,r1,r7 @ "rewind" ap to &ap[1]
  89. ldr r2,[r4,#4]! @ *(++bp)
  90. sub r3,r3,r7 @ "rewind" np to &np[1]
  91. ldr r5,[r1,#-4] @ ap[0]
  92. ldr r10,[sp] @ tp[0]
  93. ldr r6,[r3,#-4] @ np[0]
  94. ldr r7,[sp,#4] @ tp[1]
  95. mov r11,#0
  96. umlal r10,r11,r5,r2 @ ap[0]*bp[i]+tp[0]
  97. str r4,[r0,#13*4] @ save bp
  98. mul r8,r10,r8
  99. mov r12,#0
  100. umlal r10,r12,r6,r8 @ np[0]*n0+"tp[0]"
  101. mov r4,sp
  102. .Linner:
  103. ldr r5,[r1],#4 @ ap[j],ap++
  104. adds r10,r11,r7 @ +=tp[j]
  105. ldr r6,[r3],#4 @ np[j],np++
  106. mov r11,#0
  107. umlal r10,r11,r5,r2 @ ap[j]*bp[i]
  108. mov r14,#0
  109. umlal r12,r14,r6,r8 @ np[j]*n0
  110. adc r11,r11,#0
  111. ldr r7,[r4,#8] @ tp[j+1]
  112. adds r12,r12,r10
  113. str r12,[r4],#4 @ tp[j-1]=,tp++
  114. adc r12,r14,#0
  115. cmp r4,r0
  116. bne .Linner
  117. adds r12,r12,r11
  118. mov r14,#0
  119. ldr r4,[r0,#13*4] @ restore bp
  120. adc r14,r14,#0
  121. ldr r8,[r0,#14*4] @ restore n0
  122. adds r12,r12,r7
  123. ldr r7,[r0,#15*4] @ restore &bp[num]
  124. adc r14,r14,#0
  125. str r12,[r0] @ tp[num-1]=
  126. str r14,[r0,#4] @ tp[num]=
  127. cmp r4,r7
  128. #ifdef __thumb2__
  129. itt ne
  130. #endif
  131. movne r7,sp
  132. bne .Louter
  133. ldr r2,[r0,#12*4] @ pull rp
  134. mov r5,sp
  135. add r0,r0,#4 @ r0 to point at &tp[num]
  136. sub r5,r0,r5 @ "original" num value
  137. mov r4,sp @ "rewind" r4
  138. mov r1,r4 @ "borrow" r1
  139. sub r3,r3,r5 @ "rewind" r3 to &np[0]
  140. subs r7,r7,r7 @ "clear" carry flag
  141. .Lsub: ldr r7,[r4],#4
  142. ldr r6,[r3],#4
  143. sbcs r7,r7,r6 @ tp[j]-np[j]
  144. str r7,[r2],#4 @ rp[j]=
  145. teq r4,r0 @ preserve carry
  146. bne .Lsub
  147. sbcs r14,r14,#0 @ upmost carry
  148. mov r4,sp @ "rewind" r4
  149. sub r2,r2,r5 @ "rewind" r2
  150. .Lcopy: ldr r7,[r4] @ conditional copy
  151. ldr r5,[r2]
  152. str sp,[r4],#4 @ zap tp
  153. #ifdef __thumb2__
  154. it cc
  155. #endif
  156. movcc r5,r7
  157. str r5,[r2],#4
  158. teq r4,r0 @ preserve carry
  159. bne .Lcopy
  160. mov sp,r0
  161. add sp,sp,#4 @ skip over tp[num+1]
  162. ldmia sp!,{r4-r12,lr} @ restore registers
  163. add sp,sp,#2*4 @ skip over {r0,r2}
  164. mov r0,#1
  165. .Labrt:
  166. #if __ARM_ARCH__>=5
  167. bx lr @ bx lr
  168. #else
  169. tst lr,#1
  170. moveq pc,lr @ be binary compatible with V4, yet
  171. .word 0xe12fff1e @ interoperable with Thumb ISA:-)
  172. #endif
  173. .size bn_mul_mont,.-bn_mul_mont
  174. #if __ARM_MAX_ARCH__>=7
  175. .arch armv7-a
  176. .fpu neon
  177. .type bn_mul8x_mont_neon,%function
  178. .align 5
  179. bn_mul8x_mont_neon:
  180. mov ip,sp
  181. stmdb sp!,{r4-r11}
  182. vstmdb sp!,{d8-d15} @ ABI specification says so
  183. ldmia ip,{r4-r5} @ load rest of parameter block
  184. mov ip,sp
  185. cmp r5,#8
  186. bhi .LNEON_8n
  187. @ special case for r5==8, everything is in register bank...
  188. vld1.32 {d28[0]}, [r2,:32]!
  189. veor d8,d8,d8
  190. sub r7,sp,r5,lsl#4
  191. vld1.32 {d0-d3}, [r1]! @ can't specify :32 :-(
  192. and r7,r7,#-64
  193. vld1.32 {d30[0]}, [r4,:32]
  194. mov sp,r7 @ alloca
  195. vzip.16 d28,d8
  196. vmull.u32 q6,d28,d0[0]
  197. vmull.u32 q7,d28,d0[1]
  198. vmull.u32 q8,d28,d1[0]
  199. vshl.i64 d29,d13,#16
  200. vmull.u32 q9,d28,d1[1]
  201. vadd.u64 d29,d29,d12
  202. veor d8,d8,d8
  203. vmul.u32 d29,d29,d30
  204. vmull.u32 q10,d28,d2[0]
  205. vld1.32 {d4-d7}, [r3]!
  206. vmull.u32 q11,d28,d2[1]
  207. vmull.u32 q12,d28,d3[0]
  208. vzip.16 d29,d8
  209. vmull.u32 q13,d28,d3[1]
  210. vmlal.u32 q6,d29,d4[0]
  211. sub r9,r5,#1
  212. vmlal.u32 q7,d29,d4[1]
  213. vmlal.u32 q8,d29,d5[0]
  214. vmlal.u32 q9,d29,d5[1]
  215. vmlal.u32 q10,d29,d6[0]
  216. vmov q5,q6
  217. vmlal.u32 q11,d29,d6[1]
  218. vmov q6,q7
  219. vmlal.u32 q12,d29,d7[0]
  220. vmov q7,q8
  221. vmlal.u32 q13,d29,d7[1]
  222. vmov q8,q9
  223. vmov q9,q10
  224. vshr.u64 d10,d10,#16
  225. vmov q10,q11
  226. vmov q11,q12
  227. vadd.u64 d10,d10,d11
  228. vmov q12,q13
  229. veor q13,q13
  230. vshr.u64 d10,d10,#16
  231. b .LNEON_outer8
  232. .align 4
  233. .LNEON_outer8:
  234. vld1.32 {d28[0]}, [r2,:32]!
  235. veor d8,d8,d8
  236. vzip.16 d28,d8
  237. vadd.u64 d12,d12,d10
  238. vmlal.u32 q6,d28,d0[0]
  239. vmlal.u32 q7,d28,d0[1]
  240. vmlal.u32 q8,d28,d1[0]
  241. vshl.i64 d29,d13,#16
  242. vmlal.u32 q9,d28,d1[1]
  243. vadd.u64 d29,d29,d12
  244. veor d8,d8,d8
  245. subs r9,r9,#1
  246. vmul.u32 d29,d29,d30
  247. vmlal.u32 q10,d28,d2[0]
  248. vmlal.u32 q11,d28,d2[1]
  249. vmlal.u32 q12,d28,d3[0]
  250. vzip.16 d29,d8
  251. vmlal.u32 q13,d28,d3[1]
  252. vmlal.u32 q6,d29,d4[0]
  253. vmlal.u32 q7,d29,d4[1]
  254. vmlal.u32 q8,d29,d5[0]
  255. vmlal.u32 q9,d29,d5[1]
  256. vmlal.u32 q10,d29,d6[0]
  257. vmov q5,q6
  258. vmlal.u32 q11,d29,d6[1]
  259. vmov q6,q7
  260. vmlal.u32 q12,d29,d7[0]
  261. vmov q7,q8
  262. vmlal.u32 q13,d29,d7[1]
  263. vmov q8,q9
  264. vmov q9,q10
  265. vshr.u64 d10,d10,#16
  266. vmov q10,q11
  267. vmov q11,q12
  268. vadd.u64 d10,d10,d11
  269. vmov q12,q13
  270. veor q13,q13
  271. vshr.u64 d10,d10,#16
  272. bne .LNEON_outer8
  273. vadd.u64 d12,d12,d10
  274. mov r7,sp
  275. vshr.u64 d10,d12,#16
  276. mov r8,r5
  277. vadd.u64 d13,d13,d10
  278. add r6,sp,#96
  279. vshr.u64 d10,d13,#16
  280. vzip.16 d12,d13
  281. b .LNEON_tail_entry
  282. .align 4
  283. .LNEON_8n:
  284. veor q6,q6,q6
  285. sub r7,sp,#128
  286. veor q7,q7,q7
  287. sub r7,r7,r5,lsl#4
  288. veor q8,q8,q8
  289. and r7,r7,#-64
  290. veor q9,q9,q9
  291. mov sp,r7 @ alloca
  292. veor q10,q10,q10
  293. add r7,r7,#256
  294. veor q11,q11,q11
  295. sub r8,r5,#8
  296. veor q12,q12,q12
  297. veor q13,q13,q13
  298. .LNEON_8n_init:
  299. vst1.64 {q6-q7},[r7,:256]!
  300. subs r8,r8,#8
  301. vst1.64 {q8-q9},[r7,:256]!
  302. vst1.64 {q10-q11},[r7,:256]!
  303. vst1.64 {q12-q13},[r7,:256]!
  304. bne .LNEON_8n_init
  305. add r6,sp,#256
  306. vld1.32 {d0-d3},[r1]!
  307. add r10,sp,#8
  308. vld1.32 {d30[0]},[r4,:32]
  309. mov r9,r5
  310. b .LNEON_8n_outer
  311. .align 4
  312. .LNEON_8n_outer:
  313. vld1.32 {d28[0]},[r2,:32]! @ *b++
  314. veor d8,d8,d8
  315. vzip.16 d28,d8
  316. add r7,sp,#128
  317. vld1.32 {d4-d7},[r3]!
  318. vmlal.u32 q6,d28,d0[0]
  319. vmlal.u32 q7,d28,d0[1]
  320. veor d8,d8,d8
  321. vmlal.u32 q8,d28,d1[0]
  322. vshl.i64 d29,d13,#16
  323. vmlal.u32 q9,d28,d1[1]
  324. vadd.u64 d29,d29,d12
  325. vmlal.u32 q10,d28,d2[0]
  326. vmul.u32 d29,d29,d30
  327. vmlal.u32 q11,d28,d2[1]
  328. vst1.32 {d28},[sp,:64] @ put aside smashed b[8*i+0]
  329. vmlal.u32 q12,d28,d3[0]
  330. vzip.16 d29,d8
  331. vmlal.u32 q13,d28,d3[1]
  332. vld1.32 {d28[0]},[r2,:32]! @ *b++
  333. vmlal.u32 q6,d29,d4[0]
  334. veor d10,d10,d10
  335. vmlal.u32 q7,d29,d4[1]
  336. vzip.16 d28,d10
  337. vmlal.u32 q8,d29,d5[0]
  338. vshr.u64 d12,d12,#16
  339. vmlal.u32 q9,d29,d5[1]
  340. vmlal.u32 q10,d29,d6[0]
  341. vadd.u64 d12,d12,d13
  342. vmlal.u32 q11,d29,d6[1]
  343. vshr.u64 d12,d12,#16
  344. vmlal.u32 q12,d29,d7[0]
  345. vmlal.u32 q13,d29,d7[1]
  346. vadd.u64 d14,d14,d12
  347. vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+0]
  348. vmlal.u32 q7,d28,d0[0]
  349. vld1.64 {q6},[r6,:128]!
  350. vmlal.u32 q8,d28,d0[1]
  351. veor d8,d8,d8
  352. vmlal.u32 q9,d28,d1[0]
  353. vshl.i64 d29,d15,#16
  354. vmlal.u32 q10,d28,d1[1]
  355. vadd.u64 d29,d29,d14
  356. vmlal.u32 q11,d28,d2[0]
  357. vmul.u32 d29,d29,d30
  358. vmlal.u32 q12,d28,d2[1]
  359. vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+1]
  360. vmlal.u32 q13,d28,d3[0]
  361. vzip.16 d29,d8
  362. vmlal.u32 q6,d28,d3[1]
  363. vld1.32 {d28[0]},[r2,:32]! @ *b++
  364. vmlal.u32 q7,d29,d4[0]
  365. veor d10,d10,d10
  366. vmlal.u32 q8,d29,d4[1]
  367. vzip.16 d28,d10
  368. vmlal.u32 q9,d29,d5[0]
  369. vshr.u64 d14,d14,#16
  370. vmlal.u32 q10,d29,d5[1]
  371. vmlal.u32 q11,d29,d6[0]
  372. vadd.u64 d14,d14,d15
  373. vmlal.u32 q12,d29,d6[1]
  374. vshr.u64 d14,d14,#16
  375. vmlal.u32 q13,d29,d7[0]
  376. vmlal.u32 q6,d29,d7[1]
  377. vadd.u64 d16,d16,d14
  378. vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+1]
  379. vmlal.u32 q8,d28,d0[0]
  380. vld1.64 {q7},[r6,:128]!
  381. vmlal.u32 q9,d28,d0[1]
  382. veor d8,d8,d8
  383. vmlal.u32 q10,d28,d1[0]
  384. vshl.i64 d29,d17,#16
  385. vmlal.u32 q11,d28,d1[1]
  386. vadd.u64 d29,d29,d16
  387. vmlal.u32 q12,d28,d2[0]
  388. vmul.u32 d29,d29,d30
  389. vmlal.u32 q13,d28,d2[1]
  390. vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+2]
  391. vmlal.u32 q6,d28,d3[0]
  392. vzip.16 d29,d8
  393. vmlal.u32 q7,d28,d3[1]
  394. vld1.32 {d28[0]},[r2,:32]! @ *b++
  395. vmlal.u32 q8,d29,d4[0]
  396. veor d10,d10,d10
  397. vmlal.u32 q9,d29,d4[1]
  398. vzip.16 d28,d10
  399. vmlal.u32 q10,d29,d5[0]
  400. vshr.u64 d16,d16,#16
  401. vmlal.u32 q11,d29,d5[1]
  402. vmlal.u32 q12,d29,d6[0]
  403. vadd.u64 d16,d16,d17
  404. vmlal.u32 q13,d29,d6[1]
  405. vshr.u64 d16,d16,#16
  406. vmlal.u32 q6,d29,d7[0]
  407. vmlal.u32 q7,d29,d7[1]
  408. vadd.u64 d18,d18,d16
  409. vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+2]
  410. vmlal.u32 q9,d28,d0[0]
  411. vld1.64 {q8},[r6,:128]!
  412. vmlal.u32 q10,d28,d0[1]
  413. veor d8,d8,d8
  414. vmlal.u32 q11,d28,d1[0]
  415. vshl.i64 d29,d19,#16
  416. vmlal.u32 q12,d28,d1[1]
  417. vadd.u64 d29,d29,d18
  418. vmlal.u32 q13,d28,d2[0]
  419. vmul.u32 d29,d29,d30
  420. vmlal.u32 q6,d28,d2[1]
  421. vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+3]
  422. vmlal.u32 q7,d28,d3[0]
  423. vzip.16 d29,d8
  424. vmlal.u32 q8,d28,d3[1]
  425. vld1.32 {d28[0]},[r2,:32]! @ *b++
  426. vmlal.u32 q9,d29,d4[0]
  427. veor d10,d10,d10
  428. vmlal.u32 q10,d29,d4[1]
  429. vzip.16 d28,d10
  430. vmlal.u32 q11,d29,d5[0]
  431. vshr.u64 d18,d18,#16
  432. vmlal.u32 q12,d29,d5[1]
  433. vmlal.u32 q13,d29,d6[0]
  434. vadd.u64 d18,d18,d19
  435. vmlal.u32 q6,d29,d6[1]
  436. vshr.u64 d18,d18,#16
  437. vmlal.u32 q7,d29,d7[0]
  438. vmlal.u32 q8,d29,d7[1]
  439. vadd.u64 d20,d20,d18
  440. vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+3]
  441. vmlal.u32 q10,d28,d0[0]
  442. vld1.64 {q9},[r6,:128]!
  443. vmlal.u32 q11,d28,d0[1]
  444. veor d8,d8,d8
  445. vmlal.u32 q12,d28,d1[0]
  446. vshl.i64 d29,d21,#16
  447. vmlal.u32 q13,d28,d1[1]
  448. vadd.u64 d29,d29,d20
  449. vmlal.u32 q6,d28,d2[0]
  450. vmul.u32 d29,d29,d30
  451. vmlal.u32 q7,d28,d2[1]
  452. vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+4]
  453. vmlal.u32 q8,d28,d3[0]
  454. vzip.16 d29,d8
  455. vmlal.u32 q9,d28,d3[1]
  456. vld1.32 {d28[0]},[r2,:32]! @ *b++
  457. vmlal.u32 q10,d29,d4[0]
  458. veor d10,d10,d10
  459. vmlal.u32 q11,d29,d4[1]
  460. vzip.16 d28,d10
  461. vmlal.u32 q12,d29,d5[0]
  462. vshr.u64 d20,d20,#16
  463. vmlal.u32 q13,d29,d5[1]
  464. vmlal.u32 q6,d29,d6[0]
  465. vadd.u64 d20,d20,d21
  466. vmlal.u32 q7,d29,d6[1]
  467. vshr.u64 d20,d20,#16
  468. vmlal.u32 q8,d29,d7[0]
  469. vmlal.u32 q9,d29,d7[1]
  470. vadd.u64 d22,d22,d20
  471. vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+4]
  472. vmlal.u32 q11,d28,d0[0]
  473. vld1.64 {q10},[r6,:128]!
  474. vmlal.u32 q12,d28,d0[1]
  475. veor d8,d8,d8
  476. vmlal.u32 q13,d28,d1[0]
  477. vshl.i64 d29,d23,#16
  478. vmlal.u32 q6,d28,d1[1]
  479. vadd.u64 d29,d29,d22
  480. vmlal.u32 q7,d28,d2[0]
  481. vmul.u32 d29,d29,d30
  482. vmlal.u32 q8,d28,d2[1]
  483. vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+5]
  484. vmlal.u32 q9,d28,d3[0]
  485. vzip.16 d29,d8
  486. vmlal.u32 q10,d28,d3[1]
  487. vld1.32 {d28[0]},[r2,:32]! @ *b++
  488. vmlal.u32 q11,d29,d4[0]
  489. veor d10,d10,d10
  490. vmlal.u32 q12,d29,d4[1]
  491. vzip.16 d28,d10
  492. vmlal.u32 q13,d29,d5[0]
  493. vshr.u64 d22,d22,#16
  494. vmlal.u32 q6,d29,d5[1]
  495. vmlal.u32 q7,d29,d6[0]
  496. vadd.u64 d22,d22,d23
  497. vmlal.u32 q8,d29,d6[1]
  498. vshr.u64 d22,d22,#16
  499. vmlal.u32 q9,d29,d7[0]
  500. vmlal.u32 q10,d29,d7[1]
  501. vadd.u64 d24,d24,d22
  502. vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+5]
  503. vmlal.u32 q12,d28,d0[0]
  504. vld1.64 {q11},[r6,:128]!
  505. vmlal.u32 q13,d28,d0[1]
  506. veor d8,d8,d8
  507. vmlal.u32 q6,d28,d1[0]
  508. vshl.i64 d29,d25,#16
  509. vmlal.u32 q7,d28,d1[1]
  510. vadd.u64 d29,d29,d24
  511. vmlal.u32 q8,d28,d2[0]
  512. vmul.u32 d29,d29,d30
  513. vmlal.u32 q9,d28,d2[1]
  514. vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+6]
  515. vmlal.u32 q10,d28,d3[0]
  516. vzip.16 d29,d8
  517. vmlal.u32 q11,d28,d3[1]
  518. vld1.32 {d28[0]},[r2,:32]! @ *b++
  519. vmlal.u32 q12,d29,d4[0]
  520. veor d10,d10,d10
  521. vmlal.u32 q13,d29,d4[1]
  522. vzip.16 d28,d10
  523. vmlal.u32 q6,d29,d5[0]
  524. vshr.u64 d24,d24,#16
  525. vmlal.u32 q7,d29,d5[1]
  526. vmlal.u32 q8,d29,d6[0]
  527. vadd.u64 d24,d24,d25
  528. vmlal.u32 q9,d29,d6[1]
  529. vshr.u64 d24,d24,#16
  530. vmlal.u32 q10,d29,d7[0]
  531. vmlal.u32 q11,d29,d7[1]
  532. vadd.u64 d26,d26,d24
  533. vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+6]
  534. vmlal.u32 q13,d28,d0[0]
  535. vld1.64 {q12},[r6,:128]!
  536. vmlal.u32 q6,d28,d0[1]
  537. veor d8,d8,d8
  538. vmlal.u32 q7,d28,d1[0]
  539. vshl.i64 d29,d27,#16
  540. vmlal.u32 q8,d28,d1[1]
  541. vadd.u64 d29,d29,d26
  542. vmlal.u32 q9,d28,d2[0]
  543. vmul.u32 d29,d29,d30
  544. vmlal.u32 q10,d28,d2[1]
  545. vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+7]
  546. vmlal.u32 q11,d28,d3[0]
  547. vzip.16 d29,d8
  548. vmlal.u32 q12,d28,d3[1]
  549. vld1.32 {d28},[sp,:64] @ pull smashed b[8*i+0]
  550. vmlal.u32 q13,d29,d4[0]
  551. vld1.32 {d0-d3},[r1]!
  552. vmlal.u32 q6,d29,d4[1]
  553. vmlal.u32 q7,d29,d5[0]
  554. vshr.u64 d26,d26,#16
  555. vmlal.u32 q8,d29,d5[1]
  556. vmlal.u32 q9,d29,d6[0]
  557. vadd.u64 d26,d26,d27
  558. vmlal.u32 q10,d29,d6[1]
  559. vshr.u64 d26,d26,#16
  560. vmlal.u32 q11,d29,d7[0]
  561. vmlal.u32 q12,d29,d7[1]
  562. vadd.u64 d12,d12,d26
  563. vst1.32 {d29},[r10,:64] @ put aside smashed m[8*i+7]
  564. add r10,sp,#8 @ rewind
  565. sub r8,r5,#8
  566. b .LNEON_8n_inner
  567. .align 4
  568. .LNEON_8n_inner:
  569. subs r8,r8,#8
  570. vmlal.u32 q6,d28,d0[0]
  571. vld1.64 {q13},[r6,:128]
  572. vmlal.u32 q7,d28,d0[1]
  573. vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+0]
  574. vmlal.u32 q8,d28,d1[0]
  575. vld1.32 {d4-d7},[r3]!
  576. vmlal.u32 q9,d28,d1[1]
  577. it ne
  578. addne r6,r6,#16 @ don't advance in last iteration
  579. vmlal.u32 q10,d28,d2[0]
  580. vmlal.u32 q11,d28,d2[1]
  581. vmlal.u32 q12,d28,d3[0]
  582. vmlal.u32 q13,d28,d3[1]
  583. vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+1]
  584. vmlal.u32 q6,d29,d4[0]
  585. vmlal.u32 q7,d29,d4[1]
  586. vmlal.u32 q8,d29,d5[0]
  587. vmlal.u32 q9,d29,d5[1]
  588. vmlal.u32 q10,d29,d6[0]
  589. vmlal.u32 q11,d29,d6[1]
  590. vmlal.u32 q12,d29,d7[0]
  591. vmlal.u32 q13,d29,d7[1]
  592. vst1.64 {q6},[r7,:128]!
  593. vmlal.u32 q7,d28,d0[0]
  594. vld1.64 {q6},[r6,:128]
  595. vmlal.u32 q8,d28,d0[1]
  596. vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+1]
  597. vmlal.u32 q9,d28,d1[0]
  598. it ne
  599. addne r6,r6,#16 @ don't advance in last iteration
  600. vmlal.u32 q10,d28,d1[1]
  601. vmlal.u32 q11,d28,d2[0]
  602. vmlal.u32 q12,d28,d2[1]
  603. vmlal.u32 q13,d28,d3[0]
  604. vmlal.u32 q6,d28,d3[1]
  605. vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+2]
  606. vmlal.u32 q7,d29,d4[0]
  607. vmlal.u32 q8,d29,d4[1]
  608. vmlal.u32 q9,d29,d5[0]
  609. vmlal.u32 q10,d29,d5[1]
  610. vmlal.u32 q11,d29,d6[0]
  611. vmlal.u32 q12,d29,d6[1]
  612. vmlal.u32 q13,d29,d7[0]
  613. vmlal.u32 q6,d29,d7[1]
  614. vst1.64 {q7},[r7,:128]!
  615. vmlal.u32 q8,d28,d0[0]
  616. vld1.64 {q7},[r6,:128]
  617. vmlal.u32 q9,d28,d0[1]
  618. vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+2]
  619. vmlal.u32 q10,d28,d1[0]
  620. it ne
  621. addne r6,r6,#16 @ don't advance in last iteration
  622. vmlal.u32 q11,d28,d1[1]
  623. vmlal.u32 q12,d28,d2[0]
  624. vmlal.u32 q13,d28,d2[1]
  625. vmlal.u32 q6,d28,d3[0]
  626. vmlal.u32 q7,d28,d3[1]
  627. vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+3]
  628. vmlal.u32 q8,d29,d4[0]
  629. vmlal.u32 q9,d29,d4[1]
  630. vmlal.u32 q10,d29,d5[0]
  631. vmlal.u32 q11,d29,d5[1]
  632. vmlal.u32 q12,d29,d6[0]
  633. vmlal.u32 q13,d29,d6[1]
  634. vmlal.u32 q6,d29,d7[0]
  635. vmlal.u32 q7,d29,d7[1]
  636. vst1.64 {q8},[r7,:128]!
  637. vmlal.u32 q9,d28,d0[0]
  638. vld1.64 {q8},[r6,:128]
  639. vmlal.u32 q10,d28,d0[1]
  640. vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+3]
  641. vmlal.u32 q11,d28,d1[0]
  642. it ne
  643. addne r6,r6,#16 @ don't advance in last iteration
  644. vmlal.u32 q12,d28,d1[1]
  645. vmlal.u32 q13,d28,d2[0]
  646. vmlal.u32 q6,d28,d2[1]
  647. vmlal.u32 q7,d28,d3[0]
  648. vmlal.u32 q8,d28,d3[1]
  649. vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+4]
  650. vmlal.u32 q9,d29,d4[0]
  651. vmlal.u32 q10,d29,d4[1]
  652. vmlal.u32 q11,d29,d5[0]
  653. vmlal.u32 q12,d29,d5[1]
  654. vmlal.u32 q13,d29,d6[0]
  655. vmlal.u32 q6,d29,d6[1]
  656. vmlal.u32 q7,d29,d7[0]
  657. vmlal.u32 q8,d29,d7[1]
  658. vst1.64 {q9},[r7,:128]!
  659. vmlal.u32 q10,d28,d0[0]
  660. vld1.64 {q9},[r6,:128]
  661. vmlal.u32 q11,d28,d0[1]
  662. vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+4]
  663. vmlal.u32 q12,d28,d1[0]
  664. it ne
  665. addne r6,r6,#16 @ don't advance in last iteration
  666. vmlal.u32 q13,d28,d1[1]
  667. vmlal.u32 q6,d28,d2[0]
  668. vmlal.u32 q7,d28,d2[1]
  669. vmlal.u32 q8,d28,d3[0]
  670. vmlal.u32 q9,d28,d3[1]
  671. vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+5]
  672. vmlal.u32 q10,d29,d4[0]
  673. vmlal.u32 q11,d29,d4[1]
  674. vmlal.u32 q12,d29,d5[0]
  675. vmlal.u32 q13,d29,d5[1]
  676. vmlal.u32 q6,d29,d6[0]
  677. vmlal.u32 q7,d29,d6[1]
  678. vmlal.u32 q8,d29,d7[0]
  679. vmlal.u32 q9,d29,d7[1]
  680. vst1.64 {q10},[r7,:128]!
  681. vmlal.u32 q11,d28,d0[0]
  682. vld1.64 {q10},[r6,:128]
  683. vmlal.u32 q12,d28,d0[1]
  684. vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+5]
  685. vmlal.u32 q13,d28,d1[0]
  686. it ne
  687. addne r6,r6,#16 @ don't advance in last iteration
  688. vmlal.u32 q6,d28,d1[1]
  689. vmlal.u32 q7,d28,d2[0]
  690. vmlal.u32 q8,d28,d2[1]
  691. vmlal.u32 q9,d28,d3[0]
  692. vmlal.u32 q10,d28,d3[1]
  693. vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+6]
  694. vmlal.u32 q11,d29,d4[0]
  695. vmlal.u32 q12,d29,d4[1]
  696. vmlal.u32 q13,d29,d5[0]
  697. vmlal.u32 q6,d29,d5[1]
  698. vmlal.u32 q7,d29,d6[0]
  699. vmlal.u32 q8,d29,d6[1]
  700. vmlal.u32 q9,d29,d7[0]
  701. vmlal.u32 q10,d29,d7[1]
  702. vst1.64 {q11},[r7,:128]!
  703. vmlal.u32 q12,d28,d0[0]
  704. vld1.64 {q11},[r6,:128]
  705. vmlal.u32 q13,d28,d0[1]
  706. vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+6]
  707. vmlal.u32 q6,d28,d1[0]
  708. it ne
  709. addne r6,r6,#16 @ don't advance in last iteration
  710. vmlal.u32 q7,d28,d1[1]
  711. vmlal.u32 q8,d28,d2[0]
  712. vmlal.u32 q9,d28,d2[1]
  713. vmlal.u32 q10,d28,d3[0]
  714. vmlal.u32 q11,d28,d3[1]
  715. vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+7]
  716. vmlal.u32 q12,d29,d4[0]
  717. vmlal.u32 q13,d29,d4[1]
  718. vmlal.u32 q6,d29,d5[0]
  719. vmlal.u32 q7,d29,d5[1]
  720. vmlal.u32 q8,d29,d6[0]
  721. vmlal.u32 q9,d29,d6[1]
  722. vmlal.u32 q10,d29,d7[0]
  723. vmlal.u32 q11,d29,d7[1]
  724. vst1.64 {q12},[r7,:128]!
  725. vmlal.u32 q13,d28,d0[0]
  726. vld1.64 {q12},[r6,:128]
  727. vmlal.u32 q6,d28,d0[1]
  728. vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+7]
  729. vmlal.u32 q7,d28,d1[0]
  730. it ne
  731. addne r6,r6,#16 @ don't advance in last iteration
  732. vmlal.u32 q8,d28,d1[1]
  733. vmlal.u32 q9,d28,d2[0]
  734. vmlal.u32 q10,d28,d2[1]
  735. vmlal.u32 q11,d28,d3[0]
  736. vmlal.u32 q12,d28,d3[1]
  737. it eq
  738. subeq r1,r1,r5,lsl#2 @ rewind
  739. vmlal.u32 q13,d29,d4[0]
  740. vld1.32 {d28},[sp,:64] @ pull smashed b[8*i+0]
  741. vmlal.u32 q6,d29,d4[1]
  742. vld1.32 {d0-d3},[r1]!
  743. vmlal.u32 q7,d29,d5[0]
  744. add r10,sp,#8 @ rewind
  745. vmlal.u32 q8,d29,d5[1]
  746. vmlal.u32 q9,d29,d6[0]
  747. vmlal.u32 q10,d29,d6[1]
  748. vmlal.u32 q11,d29,d7[0]
  749. vst1.64 {q13},[r7,:128]!
  750. vmlal.u32 q12,d29,d7[1]
  751. bne .LNEON_8n_inner
  752. add r6,sp,#128
  753. vst1.64 {q6-q7},[r7,:256]!
  754. veor q2,q2,q2 @ d4-d5
  755. vst1.64 {q8-q9},[r7,:256]!
  756. veor q3,q3,q3 @ d6-d7
  757. vst1.64 {q10-q11},[r7,:256]!
  758. vst1.64 {q12},[r7,:128]
  759. subs r9,r9,#8
  760. vld1.64 {q6-q7},[r6,:256]!
  761. vld1.64 {q8-q9},[r6,:256]!
  762. vld1.64 {q10-q11},[r6,:256]!
  763. vld1.64 {q12-q13},[r6,:256]!
  764. itt ne
  765. subne r3,r3,r5,lsl#2 @ rewind
  766. bne .LNEON_8n_outer
  767. add r7,sp,#128
  768. vst1.64 {q2-q3}, [sp,:256]! @ start wiping stack frame
  769. vshr.u64 d10,d12,#16
  770. vst1.64 {q2-q3},[sp,:256]!
  771. vadd.u64 d13,d13,d10
  772. vst1.64 {q2-q3}, [sp,:256]!
  773. vshr.u64 d10,d13,#16
  774. vst1.64 {q2-q3}, [sp,:256]!
  775. vzip.16 d12,d13
  776. mov r8,r5
  777. b .LNEON_tail_entry
  778. .align 4
  779. .LNEON_tail:
  780. vadd.u64 d12,d12,d10
  781. vshr.u64 d10,d12,#16
  782. vld1.64 {q8-q9}, [r6, :256]!
  783. vadd.u64 d13,d13,d10
  784. vld1.64 {q10-q11}, [r6, :256]!
  785. vshr.u64 d10,d13,#16
  786. vld1.64 {q12-q13}, [r6, :256]!
  787. vzip.16 d12,d13
  788. .LNEON_tail_entry:
  789. vadd.u64 d14,d14,d10
  790. vst1.32 {d12[0]}, [r7, :32]!
  791. vshr.u64 d10,d14,#16
  792. vadd.u64 d15,d15,d10
  793. vshr.u64 d10,d15,#16
  794. vzip.16 d14,d15
  795. vadd.u64 d16,d16,d10
  796. vst1.32 {d14[0]}, [r7, :32]!
  797. vshr.u64 d10,d16,#16
  798. vadd.u64 d17,d17,d10
  799. vshr.u64 d10,d17,#16
  800. vzip.16 d16,d17
  801. vadd.u64 d18,d18,d10
  802. vst1.32 {d16[0]}, [r7, :32]!
  803. vshr.u64 d10,d18,#16
  804. vadd.u64 d19,d19,d10
  805. vshr.u64 d10,d19,#16
  806. vzip.16 d18,d19
  807. vadd.u64 d20,d20,d10
  808. vst1.32 {d18[0]}, [r7, :32]!
  809. vshr.u64 d10,d20,#16
  810. vadd.u64 d21,d21,d10
  811. vshr.u64 d10,d21,#16
  812. vzip.16 d20,d21
  813. vadd.u64 d22,d22,d10
  814. vst1.32 {d20[0]}, [r7, :32]!
  815. vshr.u64 d10,d22,#16
  816. vadd.u64 d23,d23,d10
  817. vshr.u64 d10,d23,#16
  818. vzip.16 d22,d23
  819. vadd.u64 d24,d24,d10
  820. vst1.32 {d22[0]}, [r7, :32]!
  821. vshr.u64 d10,d24,#16
  822. vadd.u64 d25,d25,d10
  823. vshr.u64 d10,d25,#16
  824. vzip.16 d24,d25
  825. vadd.u64 d26,d26,d10
  826. vst1.32 {d24[0]}, [r7, :32]!
  827. vshr.u64 d10,d26,#16
  828. vadd.u64 d27,d27,d10
  829. vshr.u64 d10,d27,#16
  830. vzip.16 d26,d27
  831. vld1.64 {q6-q7}, [r6, :256]!
  832. subs r8,r8,#8
  833. vst1.32 {d26[0]}, [r7, :32]!
  834. bne .LNEON_tail
  835. vst1.32 {d10[0]}, [r7, :32] @ top-most bit
  836. sub r3,r3,r5,lsl#2 @ rewind r3
  837. subs r1,sp,#0 @ clear carry flag
  838. add r2,sp,r5,lsl#2
  839. .LNEON_sub:
  840. ldmia r1!, {r4-r7}
  841. ldmia r3!, {r8-r11}
  842. sbcs r8, r4,r8
  843. sbcs r9, r5,r9
  844. sbcs r10,r6,r10
  845. sbcs r11,r7,r11
  846. teq r1,r2 @ preserves carry
  847. stmia r0!, {r8-r11}
  848. bne .LNEON_sub
  849. ldr r10, [r1] @ load top-most bit
  850. mov r11,sp
  851. veor q0,q0,q0
  852. sub r11,r2,r11 @ this is num*4
  853. veor q1,q1,q1
  854. mov r1,sp
  855. sub r0,r0,r11 @ rewind r0
  856. mov r3,r2 @ second 3/4th of frame
  857. sbcs r10,r10,#0 @ result is carry flag
  858. .LNEON_copy_n_zap:
  859. ldmia r1!, {r4-r7}
  860. ldmia r0, {r8-r11}
  861. it cc
  862. movcc r8, r4
  863. vst1.64 {q0-q1}, [r3,:256]! @ wipe
  864. itt cc
  865. movcc r9, r5
  866. movcc r10,r6
  867. vst1.64 {q0-q1}, [r3,:256]! @ wipe
  868. it cc
  869. movcc r11,r7
  870. ldmia r1, {r4-r7}
  871. stmia r0!, {r8-r11}
  872. sub r1,r1,#16
  873. ldmia r0, {r8-r11}
  874. it cc
  875. movcc r8, r4
  876. vst1.64 {q0-q1}, [r1,:256]! @ wipe
  877. itt cc
  878. movcc r9, r5
  879. movcc r10,r6
  880. vst1.64 {q0-q1}, [r3,:256]! @ wipe
  881. it cc
  882. movcc r11,r7
  883. teq r1,r2 @ preserves carry
  884. stmia r0!, {r8-r11}
  885. bne .LNEON_copy_n_zap
  886. mov sp,ip
  887. vldmia sp!,{d8-d15}
  888. ldmia sp!,{r4-r11}
  889. bx lr @ bx lr
  890. .size bn_mul8x_mont_neon,.-bn_mul8x_mont_neon
  891. #endif
  892. .asciz "Montgomery multiplication for ARMv4/NEON, CRYPTOGAMS by <appro@openssl.org>"
  893. .align 2
  894. #if __ARM_MAX_ARCH__>=7
  895. .comm OPENSSL_armcap_P,4,4
  896. #endif