1/* 2 * This file is part of the openHiTLS project. 3 * 4 * openHiTLS is licensed under the Mulan PSL v2. 5 * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 * You may obtain a copy of Mulan PSL v2 at: 7 * 8 * http://license.coscl.org.cn/MulanPSL2 9 * 10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13 * See the Mulan PSL v2 for more details. 14 */ 15 16#include "hitls_build.h" 17#ifdef HITLS_CRYPTO_BN 18 19.file "bn_mont_x86_64.S" 20.text 21 22.macro ADD_CARRY a b 23 addq \a,\b 24 adcq $0,%rdx 25.endm 26 27.macro SAVE_REGISTERS 28 pushq %r15 // Save non-volatile register. 29 pushq %r14 30 pushq %r13 31 pushq %r12 32 pushq %rbp 33 pushq %rbx 34.endm 35 36.macro RESTORE_REGISTERS 37 popq %rbx // Restore non-volatile register. 38 popq %rbp 39 popq %r12 40 popq %r13 41 popq %r14 42 popq %r15 43.endm 44 45/* 46* void MontMul_Asm(uint64_t *r, const uint64_t *a, const uint64_t *b, 47* const uint64_t *n, const uint64_t k0, uint32_t size); 48*/ 49.globl MontMul_Asm 50.type MontMul_Asm,@function 51.align 16 52MontMul_Asm: 53.cfi_startproc 54 testl $3,%r9d 55 jnz .LMontMul // If size is not divisible by 4, LMontMul. 56 cmpl $8,%r9d 57 jb .LMontMul // LMontMul 58 cmpq %rsi,%rdx 59 jne MontMul4 // if a != b, MontMul4 60 testl $7,%r9d 61 jz MontSqr8 // If size is divisible by 8,enter MontSqr8. 62 jmp MontMul4 63 64.align 16 65.LMontMul: 66 SAVE_REGISTERS // Save non-volatile register. 67 movq %rsp,%rax // rax stores the rsp 68 69 movq %r9, %r15 70 negq %r15 // r15 = -size 71 leaq -16(%rsp, %r15, 8), %r15 // r15 = rsp - size * 8 - 16 72 andq $-1024, %r15 // r15 The address is aligned down by 1 KB. 73 movq %rsp, %r14 // r14 = rsp 74 75 subq %r15,%r14 // __chkstk implemention, called when the stack size needs to exceed 4096. 76 // (the size of a page) to allocate more pages. 77 andq $-4096,%r14 // r14 4K down-align. 78 leaq (%r15,%r14),%rsp // rsp = r15 + r14 79 cmpq %r15,%rsp // If you want to allocate more than one page, go to Lmul_page_walk. 80 ja .LoopPage 81 jmp .LMulBody 82 83.align 16 84.LoopPage: 85 leaq -4096(%rsp),%rsp // rsp - 4096 each time until rsp < r15. 86 cmpq %r15,%rsp 87 ja .LoopPage 88 89.LMulBody: 90 movq %rax,8(%rsp,%r9,8) // Save the original rsp in the stack. 91 movq %rdx,%r13 // r13 = b 92 93 xorq %r11,%r11 // r11 = 0 94 xorq %r10,%r10 // r10 = 0 95 96 movq (%r13),%rbx // rbx = b[0] 97 movq (%rsi),%rax // rax = a[0] 98 mulq %rbx // (rdx, rax) = a[0] * b[0] 99 movq %rax,%r15 // r15 = t[0] = lo(a[0] * b[0]) 100 movq %rdx,%r14 // r14 = hi(a[0] * b[0]) 101 102 movq %r8,%rbp // rbp = k0 103 imulq %r15,%rbp // rbp = t[0] * k0 104 movq (%rcx),%rax // rax = n[0] 105 mulq %rbp // (rdx, rax) = t[0] * k0 * n[0] 106 ADD_CARRY %rax,%r15 // r15 = lo(t[0] * k0 * n[0]) + t[0] 107 108 leaq 1(%r10),%r10 // j++ 109 110.Loop1st: 111 movq (%rsi,%r10,8),%rax // rax = a[j] 112 movq %rdx,%r12 // r12 = hi(t[0] * k0 * n[0]) 113 114 mulq %rbx // (rdx, rax) = a[j] * b[0] 115 ADD_CARRY %rax,%r14 // r14 = hi(a[j - 1] * b[0]) + lo(a[j] * b[0]) 116 movq %rdx,%r15 // r15 = hi(a[j] * b[0]) 117 118 movq (%rcx,%r10,8),%rax // rax = n[j] 119 mulq %rbp // (rdx, rax) = t[0] * k0 * n[j] 120 leaq 1(%r10),%r10 // j++ 121 cmpq %r9,%r10 // if j != size, loop L1st 122 je .Loop1stSkip 123 124 ADD_CARRY %rax,%r12 // r12 = hi(t[0] * k0 * n[j]) + lo(t[0] * k0 * n[j]) 125 ADD_CARRY %r14,%r12 // r12 += lo(a[j] * b[0]) + hi(a[j] * b[0]) 126 movq %r12,-16(%rsp,%r10,8) // t[j - 2] = r13 127 movq %r15,%r14 // r14 = hi(a[j] * b[0]) 128 jmp .Loop1st 129 130.Loop1stSkip: 131 ADD_CARRY %rax,%r12 // r12 = hi(t[0] * k0 * n[j - 1]) + lo(t[0] * k0 * n[j]) 132 ADD_CARRY %r14,%r12 // r12 += hi(a[j - 1] * b[0]) + lo(a[j] * b[0]) 133 movq %r12,-16(%rsp,%r10,8) // t[j - 2] = r13 134 movq %r15,%r14 // r14 = hi(a[j] * b[0]) 135 136 movq %rdx,%r12 // r12 = hi(t[0] * k0 * n[j]) 137 xorq %rdx,%rdx // rdx = 0, Clearing the CF. 138 ADD_CARRY %r14,%r12 // r12 = hi(t[0] * k0 * n[j]) + hi(a[j] * b[0]) 139 movq %r12,-8(%rsp,%r9,8) // t[size - 1] = hi(t[0] * k0 * n[j]) + hi(a[j] * b[0]), save overflow bit. 140 movq %rdx,(%rsp,%r9,8) 141 142 leaq 1(%r11),%r11 // i++ 143 144.align 16 145.LoopOuter: 146 xorq %r10,%r10 // j = 0 147 movq (%rsi),%rax // rax = a[0] 148 movq (%r13,%r11,8),%rbx // rbx = b[i] 149 mulq %rbx // (rdx, rax) = a[0] * b[i] 150 movq (%rsp),%r15 // r15 = lo(a[0] * b[i]) + t[0] 151 ADD_CARRY %rax,%r15 152 movq %rdx,%r14 // r14 = hi(a[0] * b[i]) 153 154 movq %r8,%rbp // rbp = t[0] * k0 155 imulq %r15,%rbp 156 movq (%rcx),%rax // rax = n[0] 157 mulq %rbp // (rdx, rax) = t[0] * k0 * n[0] 158 ADD_CARRY %rax,%r15 // r15 = lo(t[0] * k0 * n[0]) 159 160 leaq 1(%r10),%r10 // j++ 161 162.align 16 163.LoopInner: 164 movq (%rsi,%r10,8),%rax // rax = a[j] 165 movq %rdx,%r12 // r12 = hi(t[0] * k0 * n[j]) 166 movq (%rsp,%r10,8),%r15 // r15 = t[j] 167 168 mulq %rbx // (rdx, rax) = a[1] * b[i] 169 ADD_CARRY %rax,%r14 // r14 = hi(a[0] * b[i]) + lo(a[1] * b[i]) 170 movq (%rcx,%r10,8),%rax // rax = n[j] 171 ADD_CARRY %r14,%r15 // r15 = a[j] * b[i] + t[j] 172 movq %rdx,%r14 173 leaq 1(%r10),%r10 // j++ 174 175 mulq %rbp // (rdx, rax) = t[0] * k0 * n[j] 176 cmpq %r9,%r10 // if j != size, loop Linner 177 je .LoopInnerSkip 178 179 ADD_CARRY %rax,%r12 // r12 = t[0] * k0 * n[j] 180 ADD_CARRY %r15,%r12 // r12 = a[j] * b[i] + t[j] + n[j] * t[0] * k0 181 movq %r12,-16(%rsp,%r10,8) // t[j - 2] = r13 182 jmp .LoopInner 183 184.LoopInnerSkip: 185 ADD_CARRY %rax,%r12 // r12 = t[0] * k0 * n[j] 186 ADD_CARRY %r15,%r12 // r12 = t[0] * k0 * n[j] + a[j] * b[i] + t[j] 187 movq (%rsp,%r10,8),%r15 // r15 = t[j] 188 movq %r12,-16(%rsp,%r10,8) // t[j - 2] 189 movq %rdx,%r12 // r12 = hi(t[0] * k0 * n[j]) 190 191 xorq %rdx,%rdx // rdx 0 192 ADD_CARRY %r14,%r12 // r12 = hi(a[1] * b[i]) + hi(t[0] * k0 * n[j]) 193 ADD_CARRY %r15,%r12 // r12 += t[j] 194 movq %r12,-8(%rsp,%r9,8) // t[size - 1] = r13 195 movq %rdx,(%rsp,%r9,8) // t[size] = CF 196 197 leaq 1(%r11),%r11 // i++ 198 cmpq %r9,%r11 // if size < i (unsigned) 199 jne .LoopOuter 200 201 xorq %r11,%r11 // r11 = 0, clear CF. 202 movq (%rsp),%rax // rax = t[0] 203 movq %r9,%r10 // r10 = size 204 205.align 16 206.LoopSub: 207 sbbq (%rcx,%r11,8),%rax // r[i] = t[i] - n[i] 208 movq %rax,(%rdi,%r11,8) 209 movq 8(%rsp,%r11,8),%rax // rax = t[i + 1] 210 211 leaq 1(%r11),%r11 // i++ 212 decq %r10 // j-- 213 jnz .LoopSub // if j != 0 214 215 sbbq $0,%rax // rax -= CF 216 movq $-1,%rbx 217 xorq %rax,%rbx // rbx = !t[i + 1] 218 xorq %r11,%r11 // r11 = 0 219 movq %r9,%r10 // r10 = size 220 221.LoopCopy: 222 movq (%rdi,%r11,8),%rcx // rcx = r[i] & t[i] 223 andq %rbx,%rcx 224 movq (%rsp,%r11,8),%rdx // rdx = CF & t[i] 225 andq %rax,%rdx 226 orq %rcx,%rdx 227 movq %rdx,(%rdi,%r11,8) // r[i] = t[i] 228 movq %r9,(%rsp,%r11,8) // t[i] = size 229 leaq 1(%r11),%r11 // i++ 230 subq $1,%r10 // j-- 231 jnz .LoopCopy // if j != 0 232 233 movq 8(%rsp,%r9,8),%rsi // rsi = pressed-stacked rsp. 234 movq $1,%rax // rax = 1 235 leaq (%rsi),%rsp // restore rsp. 236 RESTORE_REGISTERS // Restore non-volatile register. 237 ret 238.cfi_endproc 239.size MontMul_Asm,.-MontMul_Asm 240 241.type MontMul4,@function 242.align 16 243MontMul4: 244.cfi_startproc 245 SAVE_REGISTERS 246 movq %rsp,%rax // save rsp 247 248 movq %r9,%r15 249 negq %r15 250 leaq -32(%rsp,%r15,8),%r15 // Allocate space: size * 8 + 32 bytes. 251 andq $-1024,%r15 252 movq %rsp,%r14 253 254 subq %r15,%r14 // __chkstk implemention, called when the stack size needs to exceed 4096. 255 andq $-4096,%r14 256 leaq (%r15,%r14),%rsp 257 cmpq %r15,%rsp // If you want to allocate more than one page, go to LoopPage4x. 258 ja .LoopPage4x 259 jmp .LoopMul4x 260 261.LoopPage4x: 262 leaq -4096(%rsp),%rsp // rsp - 4096each time until rsp >= r10. 263 cmpq %r15,%rsp 264 ja .LoopPage4x 265 266.LoopMul4x: 267 xorq %r11,%r11 // i = 0 268 xorq %r10,%r10 // j = 0 269 270 movq %rax,8(%rsp,%r9,8) 271 movq %rdi,16(%rsp,%r9,8) // t[size + 2] = r 272 movq %rdx,%r13 // r13 = b 273 movq (%rsi),%rax // rax = a[0] 274 movq %r8,%rbp // rbp = k0 275 movq (%r13),%rbx // rbx = b[0] 276 277 /* 计算a[i] * b[0] * k[0] * n[j] */ 278 mulq %rbx // (rdx, rax) = a[0] * b[0] 279 movq %rax,%r15 // r15 = t[0] = lo(b[0] * a[0]) 280 movq (%rcx),%rax // rax = n[0] 281 282 imulq %r15,%rbp // rbp = t[0] * k0 283 movq %rdx,%r14 // r14 = hi(a[0] * b[0]) 284 285 mulq %rbp // (rdx, rax) = t[0] * k0 * n[0] 286 ADD_CARRY %rax,%r15 // r15 = lo(t[0] * k0 * n[0]) 287 movq 8(%rsi),%rax // rax = a[1] 288 movq %rdx,%rdi // rdi = hi(t[0] * k0 * n[0]) 289 290 mulq %rbx // (rdx, rax) = a[1] * b[0] 291 ADD_CARRY %rax,%r14 // r14 = lo(a[1] * b[0]) + hi(a[0] * b[0]) 292 movq 8(%rcx),%rax // rax = n[1] 293 movq %rdx,%r15 // r15 = hi(a[1] * b[0]) 294 295 mulq %rbp // (rdx, rax) = t[0] * k0 * n[1] 296 ADD_CARRY %rax,%rdi // rdi = lo(t[0] * k0 * n[1]) + hi(t[0] * k0 * n[0]) 297 movq 16(%rsi),%rax // rax = a[2] 298 ADD_CARRY %r14,%rdi // rdi += hi(a[0] * b[0]) + lo(a[1] * b[0]) 299 movq %rdx,%r12 // r12 = hi(t[0] * k0 * n[1]) 300 movq %rdi,(%rsp) // t[0] = rdi 301 302 leaq 4(%r10),%r10 // j += 4 303 304.align 16 305.Loop1st4x: 306 mulq %rbx // (rdx, rax) = a[2] * b[0] 307 ADD_CARRY %rax,%r15 // r15 = hi(a[1] * b[0]) + lo(a[2] * b[0]) 308 movq -16(%rcx,%r10,8),%rax // rax = n[j - 2] 309 movq %rdx,%r14 // r14 = hi[a[2] * b[0]] 310 311 mulq %rbp // (rdx, rax) = t[0] * k0 * n[j - 2] 312 ADD_CARRY %rax,%r12 // r12 = hi(t[0] * k0 * n[1]) + lo(t[0] * k0 * n[j - 2]) 313 movq -8(%rsi,%r10,8),%rax // rax = a[j - 1] 314 ADD_CARRY %r15,%r12 // r12 += hi(a[1] * b[0]) + lo(a[2] * b[0]) 315 movq %r12,-24(%rsp,%r10,8) // t[j - 3] = r13 316 movq %rdx,%rdi // rdi = hi(t[0] * k0 * n[j - 2]) 317 318 mulq %rbx // (rdx, rax) = a[j - 1] * b[0] 319 ADD_CARRY %rax,%r14 // r14 = hi[a[2] * b[0]] + lo(a[j - 1] * b[0]) 320 movq -8(%rcx,%r10,8),%rax // rax = n[j - 1] 321 movq %rdx,%r15 // r15 = hi(a[j - 1] * b[0]) 322 323 mulq %rbp // (rdx, rax) = t[0] * k0 * n[j - 1] 324 ADD_CARRY %rax,%rdi // rdi = hi(t[0] * k0 * n[j - 2]) + lo(t[0] * k0 * n[j - 1] 325 movq (%rsi,%r10,8),%rax // rax = a[j] 326 ADD_CARRY %r14,%rdi // rdi += hi[a[2] * b[0]] + lo(a[j - 1] * b[0]) 327 movq %rdi,-16(%rsp,%r10,8) // t[j - 2] = rdi 328 movq %rdx,%r12 // r12 = hi(t[0] * k0 * n[j - 1]) 329 330 mulq %rbx // (rdx, rax) = a[j] * b[0] 331 ADD_CARRY %rax,%r15 // r15 = hi(a[j - 1] * b[0]) + lo(a[j] * b[0]) 332 movq (%rcx,%r10,8),%rax // rax = n[j] 333 movq %rdx,%r14 // r14 = hi(a[j] * b[0]) 334 335 mulq %rbp // (rdx, rax) = t[0] * k0 * n[j] 336 ADD_CARRY %rax,%r12 // r12 = hi(t[0] * k0 * n[j - 1]) + lo(t[0] * k0 * n[j]) 337 movq 8(%rsi,%r10,8),%rax // rax = a[j + 1] 338 ADD_CARRY %r15,%r12 // r12 += hi(a[j - 1] * b[0]) + lo(a[j] * b[0]) 339 movq %r12,-8(%rsp,%r10,8) // t[j - 1] = r13 340 movq %rdx,%rdi // rdi = hi(t[0] * k0 * n[j]) 341 342 mulq %rbx // (rdx, rax) = a[j + 1] * b[0] 343 ADD_CARRY %rax,%r14 // r14 = hi(a[j] * b[0]) + lo(a[j + 1] * b[0]) 344 movq 8(%rcx,%r10,8),%rax // rax = n[j + 1] 345 movq %rdx,%r15 // r15 = hi(a[j + 1] * b[0]) 346 347 mulq %rbp // (rdx, rax) = t[0] * k0 * n[j + 1] 348 ADD_CARRY %rax,%rdi // rdi = hi(t[0] * k0 * n[j]) + lo(t[0] * k0 * n[j + 1]) 349 movq 16(%rsi,%r10,8),%rax // rax = a[j + 2] 350 ADD_CARRY %r14,%rdi // rdi += hi(a[j] * b[0]) + lo(a[j + 1] * b[0]) 351 movq %rdi,(%rsp,%r10,8) // t[j - 4] = rdi 352 movq %rdx,%r12 // r12 = hi(t[0] * k0 * n[j + 1]) 353 354 leaq 4(%r10),%r10 // j += 4 355 cmpq %r9,%r10 // if size != j 356 jb .Loop1st4x 357 358 mulq %rbx // (rdx, rax) = a[j - 2] * b[0] 359 ADD_CARRY %rax,%r15 // r15 = hi(a[j - 3] * b[0]) + lo(a[j - 2] * b[0]) 360 movq -16(%rcx,%r10,8),%rax // rax = n[j - 2] 361 movq %rdx,%r14 // r14 = hi(a[j - 2] * b[0]) 362 363 mulq %rbp // (rdx, rax) = t[0] * k0 * n[j - 2] 364 ADD_CARRY %rax,%r12 // r12 = hi(t[0] * k0 * n[j - 3]) + lo(t[0] * k0 * n[j - 2]) 365 movq -8(%rsi,%r10,8),%rax // rax = a[j - 1] 366 ADD_CARRY %r15,%r12 // r12 += hi(a[j - 3] * b[0]) + lo(a[j - 2] * b[0]) 367 movq %r12,-24(%rsp,%r10,8) // t[j - 3] = r13 368 movq %rdx,%rdi // rdi = hi(t[0] * k0 * n[j - 2]) 369 370 mulq %rbx // (rdx, rax) = a[j - 1] * b[0] 371 ADD_CARRY %rax,%r14 // r14 = hi(a[j - 2] * b[0]) + lo(a[j- 1] * b[0]) 372 movq -8(%rcx,%r10,8),%rax // rax = n[j - 1] 373 movq %rdx,%r15 // r15 = hi(a[j - 1] * b[0]) 374 375 mulq %rbp // (rdx, rax) = t[0] * k0 * n[j - 1] 376 ADD_CARRY %rax,%rdi // rdi = hi(t[0] * k0 * n[j - 2]) + lo(t[0] * k0 * n[j - 1]) 377 ADD_CARRY %r14,%rdi // rdi += hi(a[j - 2] * b[0]) + lo(a[j- 1] * b[0]) 378 movq %rdi,-16(%rsp,%r10,8) // t[j - 2] = rdi 379 movq %rdx,%r12 // r12 = hi(t[0] * k0 * n[j - 1]) 380 381 xorq %rdx,%rdx // rdx = 0 382 ADD_CARRY %r15,%r12 // r12 = hi(a[j - 1] * b[0]) + hi(t[0] * k0 * n[j - 1]) 383 movq %r12,-8(%rsp,%r10,8) // t[j - 1] = r13 384 movq %rdx,(%rsp,%r10,8) // t[j] = CF 385 386 leaq 1(%r11),%r11 // i++ 387.align 4 388.LoopOuter4x: 389 /* Calculate a[i] * b + q * N */ 390 movq (%rsi),%rax // rax = a[0] 391 movq (%r13,%r11,8),%rbx // rbx = b[i] 392 xorq %r10,%r10 // j = 0 393 movq (%rsp),%r15 // r15 = t[0] 394 movq %r8,%rbp // rbp = k0 395 mulq %rbx // (rdx, rax) = a[0] * b[i] 396 ADD_CARRY %rax,%r15 // r15 = lo(a[0] * b[i]) + t[0] 397 movq (%rcx),%rax // rax = n[0] 398 399 imulq %r15,%rbp // rbp = t[0] * k0 400 movq %rdx,%r14 // r14 = hi[a[0] * b[i]] 401 402 mulq %rbp // (rdx, rax) = t[0] * k0 * n[0] 403 ADD_CARRY %rax,%r15 // r15 = lo(t[0] * k0 * n[0]) 404 movq 8(%rsi),%rax // rax = a[1] 405 movq %rdx,%rdi // rdi = hi(t[0] * k0 * n[0]) 406 407 mulq %rbx // (rdx, rax) = a[1] * b[i] 408 ADD_CARRY %rax,%r14 // r14 = hi[a[0] * b[i]] + lo(a[1] * b[i]) 409 movq 8(%rcx),%rax // rax = n[1] 410 ADD_CARRY 8(%rsp),%r14 // r14 = t[1] 411 movq %rdx,%r15 // r15 = hi(a[1] * b[i]) 412 413 mulq %rbp // (rdx, rax) = t[0] * k0 * n[1] 414 ADD_CARRY %rax,%rdi // rdi = hi(t[0] * k0 * n[0]) + lo(t[0] * k0 * n[1]) 415 movq 16(%rsi),%rax // rax = a[2] 416 ADD_CARRY %r14,%rdi // rdi += t[1] 417 leaq 4(%r10),%r10 // j += 4 418 movq %rdi,(%rsp) // t[0] = rdi 419 movq %rdx,%r12 // r12 = hi(t[0] * k0 * n[1]) 420 421.align 16 422.Linner4x: 423 mulq %rbx // (rdx, rax) = a[2] * b[i] 424 ADD_CARRY %rax,%r15 // r15 = hi(a[1] * b[i]) + lo(a[2] * b[i]) 425 addq -16(%rsp,%r10,8),%r15 // r15 = t[j - 2] 426 adcq $0,%rdx 427 428 movq -16(%rcx,%r10,8),%rax // rax = n[j - 2] 429 movq %rdx,%r14 // r14 = hi(a[2] * b[i]) 430 mulq %rbp // (rdx, rax) = t[0] * k0 * n[j - 2] 431 ADD_CARRY %rax,%r12 // r12 = hi(t[0] * k0 * n[j - 3]) * lo(t[0] * k0 * n[j - 2]) 432 ADD_CARRY %r15,%r12 // r12 += t[j - 2] 433 movq %r12,-24(%rsp,%r10,8) // t[j - 3] = r13 434 movq %rdx,%rdi // rdi = hi(t[0] * k0 * n[j - 2]) 435 436 movq -8(%rsi,%r10,8),%rax // rax = a[j - 1] 437 mulq %rbx // (rdx, rax) = a[j - 1] * b[i] 438 ADD_CARRY %rax,%r14 // r14 = lo(a[j - 1] * b[i]) 439 addq -8(%rsp,%r10,8),%r14 // r14 += t[j - 1] 440 adcq $0,%rdx 441 movq %rdx,%r15 // r15 = hi(a[j - 1] * b[i]) 442 443 movq -8(%rcx,%r10,8),%rax // rax = n[j - 1] 444 mulq %rbp // (rdx, rax) = t[0] * k0 * n[j - 1] 445 ADD_CARRY %rax,%rdi // rdi = hi(t[0] * k0 * n[j - 2]) + lo(t[0] * k0 * n[j - 1]) 446 ADD_CARRY %r14,%rdi // rdi += t[j - 1] 447 movq %rdi,-16(%rsp,%r10,8) // t[j - 2] = rdi 448 movq %rdx,%r12 // r12 = hi(t[0] * k0 * n[j - 1]) 449 450 movq (%rsi,%r10,8),%rax // rax = a[j] 451 mulq %rbx // (rdx, rax) = a[j] * b[i] 452 ADD_CARRY %rax,%r15 // r15 = hi(a[j - 1] * b[i]) + lo(a[j] * b[i]) 453 addq (%rsp,%r10,8),%r15 // r15 = t[j] 454 adcq $0,%rdx 455 movq %rdx,%r14 // r14 = hi(a[j] * b[i]) 456 457 movq (%rcx,%r10,8),%rax // rax = n[j] 458 mulq %rbp // (rdx, rax) = t[0] * k0 * n[j] 459 ADD_CARRY %rax,%r12 // r12 = hi(t[0] * k0 * n[j - 1]) + lo(t[0] * k0 * n[j]) 460 ADD_CARRY %r15,%r12 // r12 += t[j] 461 movq %r12,-8(%rsp,%r10,8) // t[j - 1] = r13 462 movq %rdx,%rdi // rdi = hi(t[0] * k0 * n[j]) 463 464 movq 8(%rsi,%r10,8),%rax // rax = a[j + 1] 465 mulq %rbx // (rdx, rax) = a[j + 1] * b[i] 466 ADD_CARRY %rax,%r14 // r14 = hi(a[j] * b[i]) + lo(a[j + 1] * b[i]) 467 addq 8(%rsp,%r10,8),%r14 // r14 = t[j + 1] 468 adcq $0,%rdx 469 movq %rdx,%r15 // r15 = hi(a[j + 1] * b[i]) 470 471 movq 8(%rcx,%r10,8),%rax // rax = n[j + 1] 472 mulq %rbp // (rdx, rax) = t[0] * k0 * n[j + 1] 473 ADD_CARRY %rax,%rdi // rdi = hi(t[0] * k0 * n[j]) + lo(t[0] * k0 * n[j + 1]) 474 ADD_CARRY %r14,%rdi // rdi += t[j + 1] 475 movq %rdi,(%rsp,%r10,8) // t[j] = rdi 476 movq %rdx,%r12 // r12 = hi(t[0] * k0 * n[j + 1]) 477 movq 16(%rsi,%r10,8),%rax // rax = a[j + 2] 478 479 leaq 4(%r10),%r10 // j += 4 480 cmpq %r9,%r10 // if j != size 481 jb .Linner4x 482 483 mulq %rbx // (rdx, rax) = a[j - 2] * b[i] 484 ADD_CARRY %rax,%r15 // r15 = hi(a[j + 1] * b[i]) + lo(a[j - 2] * b[i]) 485 addq -16(%rsp,%r10,8),%r15 // r15 = t[j - 2] 486 adcq $0,%rdx 487 movq %rdx,%r14 // r14 = hi(a[j - 2] * b[i]) 488 489 movq -16(%rcx,%r10,8),%rax // rax = n[j - 2] 490 mulq %rbp // (rdx, rax) = t[0] * k0 * n[j - 2] 491 ADD_CARRY %rax,%r12 // r12 = hi(t[0] * k0 * n[j + 1]) + lo(t[0] * k0 * n[j - 2]) 492 ADD_CARRY %r15,%r12 // r12 += t[j - 2] 493 movq %r12,-24(%rsp,%r10,8) // t[j - 3] = r13 494 movq %rdx,%rdi // rdi = hi(t[0] * k0 * n[j - 2]) 495 496 movq -8(%rsi,%r10,8),%rax // rax = a[j - 1] 497 mulq %rbx // (rdx, rax) = a[j - 1] * b[i] 498 ADD_CARRY %rax,%r14 // r14 = hi(a[j - 2] * b[i]) + lo(a[j - 1] * b[i]) 499 addq -8(%rsp,%r10,8),%r14 // r14 = t[j - 1] 500 adcq $0,%rdx 501 leaq 1(%r11),%r11 // i++ 502 movq %rdx,%r15 // r15 = hi(a[j - 1] * b[i]) 503 504 movq -8(%rcx,%r10,8),%rax // rax = n[j - 1] 505 mulq %rbp // (rdx, rax) = t[0] * k0 * n[j - 1] 506 ADD_CARRY %rax,%rdi // rdi = hi(t[0] * k0 * n[j - 2]) + lo(t[0] * k0 * n[j - 1]) 507 ADD_CARRY %r14,%rdi // rdi += t[j - 1] 508 movq %rdi,-16(%rsp,%r10,8) // t[j - 2] = rdi 509 movq %rdx,%r12 // r12 = hi(t[0] * k0 * n[j - 1]) 510 511 xorq %rdx,%rdx // rdi = 0 512 ADD_CARRY %r15,%r12 // r12 = hi(t[0] * k0 * n[j - 1]) + r10 513 addq (%rsp,%r9,8),%r12 // r12 += t[size] 514 adcq $0,%rdx 515 movq %r12,-8(%rsp,%r10,8) // t[j - 1] = r13 516 movq %rdx,(%rsp,%r10,8) // t[j] = CF 517 518 cmpq %r9,%r11 // if i != size 519 jb .LoopOuter4x 520 521 movq 16(%rsp,%r9,8),%rdi // rdi = t[size + 2] 522 leaq -4(%r9),%r10 // j = size - 4 523 movq (%rsp),%rax // rax = t[0] 524 movq 8(%rsp),%rdx // rdx = t[1] 525 shrq $2,%r10 // r10 = (size - 4) / 4 526 leaq (%rsp),%rsi // rsi = t[0] 527 xorq %r11,%r11 // i = 0 528 529 subq (%rcx),%rax // rax = t[0] - n[0] 530 sbbq 8(%rcx),%rdx // rdx = t[1] - (n[1] + CF) 531 movq 16(%rsi),%rbx // rbx = t[2] 532 movq 24(%rsi),%rbp // rbp = t[3] 533 534 /* 计算 S-N */ 535.LoopSub4x: 536 movq %rax,(%rdi,%r11,8) // r[i] = n[0] 537 movq %rdx,8(%rdi,%r11,8) // r[i + 1] = n[1] 538 539 movq 32(%rsi,%r11,8),%rax // rax = t[i + 4] 540 movq 40(%rsi,%r11,8),%rdx // rdx = t[i + 5] 541 542 sbbq 16(%rcx,%r11,8),%rbx // rbx = t[2] - (n[i + 2] + CF) 543 sbbq 24(%rcx,%r11,8),%rbp // rbp = t[3] - (n[i + 3] + CF) 544 sbbq 32(%rcx,%r11,8),%rax // rax = t[i + 4] - (n[j + 4] + CF) 545 sbbq 40(%rcx,%r11,8),%rdx // rdx = t[i + 5] - (n[i + 5] + CF) 546 547 movq %rbx,16(%rdi,%r11,8) // r[i + 2] = rbx 548 movq %rbp,24(%rdi,%r11,8) // r[i + 3] = rbp 549 550 movq 48(%rsi,%r11,8),%rbx // rbx = t[i + 6] 551 movq 56(%rsi,%r11,8),%rbp // rbp = t[i + 7] 552 leaq 4(%r11),%r11 // i += 4 553 decq %r10 // j-- 554 jnz .LoopSub4x // if j != 0 555 556 sbbq 16(%rcx,%r11,8),%rbx // rbx = rbx = t[i + 6] - (n[i + 2] + CF) 557 sbbq 24(%rcx,%r11,8),%rbp // rbp = t[i + 7] - (n[i + 3] + CF) 558 559 movq %rax,(%rdi,%r11,8) // r[i] = rax 560 movq %rdx,8(%rdi,%r11,8) // r[i + 1] = rdx 561 movq %rbx,16(%rdi,%r11,8) // r[i + 2] = rbx 562 movq %rbp,24(%rdi,%r11,8) // r[i + 3] = rbp 563 564 movq 32(%rsi,%r11,8),%rax // rax = t[i + 4] 565 sbbq $0,%rax // rax -= CF 566 567 pxor %xmm2,%xmm2 // xmm0 = 0 568 movq %rax, %xmm0 569 pcmpeqd %xmm1,%xmm1 // xmm5 = -1 570 pshufd $0,%xmm0,%xmm0 571 movq %r9,%r10 // j = size 572 pxor %xmm0,%xmm1 573 shrq $2,%r10 // j = size / 4 574 xorl %eax,%eax // i = 0 575 576.align 16 577.LoopCopy4x: 578 579 movdqa (%rsp,%rax),%xmm5 // Copy the result to r. 580 movdqu (%rdi,%rax),%xmm3 581 pand %xmm0,%xmm5 582 pand %xmm1,%xmm3 583 movdqa 16(%rsp,%rax),%xmm4 584 movdqa %xmm2,(%rsp,%rax) 585 por %xmm3,%xmm5 586 movdqu 16(%rdi,%rax),%xmm3 587 movdqu %xmm5,(%rdi,%rax) 588 pand %xmm0,%xmm4 589 pand %xmm1,%xmm3 590 movdqa %xmm2,16(%rsp,%rax) 591 por %xmm3,%xmm4 592 movdqu %xmm4,16(%rdi,%rax) 593 leaq 32(%rax),%rax 594 decq %r10 // j-- 595 jnz .LoopCopy4x 596 movq 8(%rsp,%r9,8),%rsi // rsi = pressed-stacked rsp. 597 movq $1,%rax 598 leaq (%rsi),%rsp // Restore srsp. 599 RESTORE_REGISTERS 600 ret 601.cfi_endproc 602.size MontMul4,.-MontMul4 603 604.type MontSqr8,@function 605.align 32 606MontSqr8: 607.cfi_startproc 608 SAVE_REGISTERS 609 movq %rsp,%rax 610 611 movl %r9d,%r15d 612 shll $3,%r9d // Calculate size * 8 bytes. 613 shlq $5,%r15 // size * 8 * 4 614 negq %r9 615 616 leaq -64(%rsp,%r9,2),%r14 // r14 = rsp[size * 2 - 8] 617 subq %rsi,%r14 618 andq $4095,%r14 619 movq %rsp,%rbp 620 cmpq %r14,%r15 621 jae .Loop8xCheckstk 622 623 leaq 4032(,%r9,2),%r15 // r15 = 4096 - frame - 2 * size 624 subq %r15,%r14 625 movq $0,%r15 626 cmovcq %r15,%r14 627 628.Loop8xCheckstk: 629 subq %r14,%rbp 630 leaq -64(%rbp,%r9,2),%rbp // Allocate a frame + 2 x size. 631 632 andq $-64,%rbp // __checkstk implementation, 633 // which is invoked when the stack size needs to exceed one page. 634 movq %rsp,%r14 635 subq %rbp,%r14 636 andq $-4096,%r14 637 leaq (%r14,%rbp),%rsp 638 cmpq %rbp,%rsp 639 jbe .LoopMul8x 640 641.align 16 642.LoopPage8x: 643 leaq -4096(%rsp),%rsp // Change sp - 4096 each time until sp <= the space to be allocated 644 cmpq %rbp,%rsp 645 ja .LoopPage8x 646 647.LoopMul8x: 648 movq %r9,%r15 // r15 = -size * 8 649 negq %r9 // Restoresize. 650 movq %r8,32(%rsp) // Save the values of k0 and sp. 651 movq %rax,40(%rsp) 652 653 movq %rcx, %xmm1 // Pointer to saving n. 654 pxor %xmm2,%xmm2 // xmm0 = 0 655 movq %rdi, %xmm0 // Pointer to saving r. 656 movq %r15, %xmm5 // Save size. 657 call MontSqr8Inner 658 659 leaq (%rdi,%r9),%rbx // rbx = t[size] 660 movq %r9,%rcx // rcx = -size 661 movq %r9,%rdx // rdx = -size 662 movq %xmm0, %rdi // rdi = r 663 sarq $5,%rcx // rcx >>= 5 664 665.align 32 666/* T -= N */ 667.LoopSub8x: 668 movq (%rbx),%r13 // r13 = t[i] 669 movq 8(%rbx),%r12 // r12 = t[i + 1] 670 movq 16(%rbx),%r11 // r11 = t[i + 2] 671 movq 24(%rbx),%r10 // r10 = t[i + 3] 672 673 sbbq (%rbp),%r13 // r13 = t[i] - (n[i] + CF) 674 sbbq 8(%rbp),%r12 // r12 = t[i + 1] - (n[i + 1] + CF) 675 sbbq 16(%rbp),%r11 // r11 = t[i + 2] - (n[i + 2] + CF) 676 sbbq 24(%rbp),%r10 // r10 = t[i + 3] - (n[i + 3] + CF) 677 678 movq %r13,0(%rdi) // Assigning value to r. 679 movq %r12,8(%rdi) 680 movq %r11,16(%rdi) 681 movq %r10,24(%rdi) 682 683 leaq 32(%rbp),%rbp // n += 4 684 leaq 32(%rdi),%rdi // r += 4 685 leaq 32(%rbx),%rbx // t += 4 686 incq %rcx 687 jnz .LoopSub8x 688 689 sbbq $0,%rax // rax -= CF 690 leaq (%rbx,%r9),%rbx 691 leaq (%rdi,%r9),%rdi 692 693 movq %rax,%xmm0 694 pxor %xmm2,%xmm2 695 pshufd $0,%xmm0,%xmm0 696 movq 40(%rsp),%rsi // rsi = pressed-stacked rsp. 697 698.align 32 699.LoopCopy8x: 700 movdqa 0(%rbx),%xmm1 // Copy the result to r. 701 movdqa 16(%rbx),%xmm5 702 leaq 32(%rbx),%rbx 703 movdqu 0(%rdi),%xmm3 704 movdqu 16(%rdi),%xmm4 705 leaq 32(%rdi),%rdi 706 movdqa %xmm2,-32(%rbx) 707 movdqa %xmm2,-16(%rbx) 708 movdqa %xmm2,-32(%rbx,%rdx) 709 movdqa %xmm2,-16(%rbx,%rdx) 710 pcmpeqd %xmm0,%xmm2 711 pand %xmm0,%xmm1 712 pand %xmm0,%xmm5 713 pand %xmm2,%xmm3 714 pand %xmm2,%xmm4 715 pxor %xmm2,%xmm2 716 por %xmm1,%xmm3 717 por %xmm5,%xmm4 718 movdqu %xmm3,-32(%rdi) 719 movdqu %xmm4,-16(%rdi) 720 addq $32,%r9 721 jnz .LoopCopy8x 722 723 movq $1,%rax 724 leaq (%rsi),%rsp // Restore rsp. 725 RESTORE_REGISTERS // Restore non-volatile register. 726 ret 727.cfi_endproc 728.size MontSqr8,.-MontSqr8 729 730.type MontSqr8Inner,@function 731.align 32 732MontSqr8Inner: 733.cfi_startproc 734 leaq 32(%r15),%rbp // i = -size + 32 735 leaq (%rsi,%r9),%rsi // rsi = a[size] 736 movq %r9,%rcx // j = size 737 738 movq -32(%rsi,%rbp),%r11 // r11 = a[0] 739 movq -24(%rsi,%rbp),%r10 // r10 = a[1] 740 741 leaq 56(%rsp,%r9,2),%rdi // rdi = t[2 * size] 742 leaq -16(%rsi,%rbp),%rbx // rbx = a[2] 743 leaq -32(%rdi,%rbp),%rdi // rdi = t[2 * size - i] 744 745 movq %r10,%rax // rax = a[1] 746 mulq %r11 // (rdx, rax) = a[1] * a[0] 747 movq %rax,%r15 // r15 = lo(a[1] * a[0]) 748 movq %rdx,%r14 // r14 = hi(a[1] * a[0]) 749 movq %r15,-24(%rdi,%rbp) // t[1] = lo(a[1] * a[0]) 750 751 movq (%rbx),%rax // rax = a[2] 752 mulq %r11 // (rdx, rax) = a[2] * a[0] 753 ADD_CARRY %rax,%r14 // r14 = hi(a[1] * a[0]) + lo(a[2] * a[0]) 754 movq %r14,-16(%rdi,%rbp) // t[2] = hi(a[1] * a[0]) + lo(a[2] * a[0]) 755 movq %rdx,%r15 // r15 = hi(a[2] * a[0]) 756 757 movq (%rbx),%rax // rax = a[2] 758 mulq %r10 // (rdx, rax) = a[2] * a[1] 759 movq %rax,%r13 // r13 = lo(a[2] * a[1]) 760 movq %rdx,%r12 // r12 = hi(a[2] * a[1]) 761 762 leaq 8(%rbx),%rbx // rbx = a[3] 763 movq (%rbx),%rax // rax = a[3] 764 mulq %r11 // (rdx, rax) = a[3] * a[0] 765 ADD_CARRY %rax,%r15 // r15 = hi(a[2] * a[0]) + lo(a[3] * a[0]) 766 ADD_CARRY %r13,%r15 // r15 = hi(a[2] * a[0]) + lo(a[3] * a[0]) + lo(a[2] * a[1]) 767 movq %rdx,%r14 // r14 = hi(a[3] * a[0]) 768 769 movq (%rbx),%rax // rax = a[3] 770 leaq (%rbp),%rcx // j = i 771 movq %r15,-8(%rdi,%rcx) // t[3] = hi(a[2] * a[0]) + lo(a[3] * a[0]) + lo(a[2] * a[1]) 772 773.align 32 774.Loop1stSqr4x: 775 leaq (%rsi,%rcx),%rbx // rbx = a[4] 776 mulq %r10 // (rdx, rax) = a[3] * a[1] 777 ADD_CARRY %rax,%r12 // r12 = hi(a[2] * a[1]) + lo(a[3] * a[1]) 778 movq %rdx,%r13 // r13 = hi(a[3] * a[1]) 779 780 movq (%rbx),%rax // rax = a[4] 781 mulq %r11 // (rdx, rax) = a[4] * a[0] 782 ADD_CARRY %rax,%r14 // r14 = hi(a[3] * a[0]) + lo(a[4] * a[0]) 783 ADD_CARRY %r12,%r14 // r14 = hi(a[3] * a[0]) + lo(a[4] * a[0]) + lo(a[3] * a[1]) 784 785 movq (%rbx),%rax // rax = a[4] 786 movq %rdx,%r15 // r15 = hi(a[4] * a[0]) 787 mulq %r10 // (rdx, rax) = a[4] * a[1] 788 ADD_CARRY %rax,%r13 // r13 = hi(a[3] * a[1]) + lo(a[4] * a[1]) 789 movq %r14,(%rdi,%rcx) // t[4] = hi(a[3] * a[0]) + lo(a[4] * a[0]) + lo(a[3] * a[1]) 790 movq %rdx,%r12 // r12 = hi(a[4] * a[1]) 791 792 leaq 8(%rbx),%rbx // rbx = a[5] 793 movq (%rbx),%rax // rax = a[5] 794 mulq %r11 // (rdx, rax) = a[5] * a[0] 795 ADD_CARRY %rax,%r15 // r15 = hi(a[4] * a[0]) + lo(a[5] * a[0]) 796 ADD_CARRY %r13,%r15 // r15 = hi(a[4] * a[0]) + lo(a[5] * a[0]) + hi(a[3] * a[1]) + lo(a[4] * a[1]) 797 798 movq (%rbx),%rax // rax = a[5] 799 movq %rdx,%r14 // r14 = hi(a[5] * a[0]) 800 mulq %r10 // (rdx, rax) = a[5] * a[1] 801 ADD_CARRY %rax,%r12 // r12 = hi(a[4] * a[1]) + lo(a[5] * a[1]) 802 movq %r15,8(%rdi,%rcx) // t[5] = r10 803 movq %rdx,%r13 // r13 = hi(a[5] * a[1]) 804 805 leaq 8(%rbx),%rbx // rbx = a[6] 806 movq (%rbx),%rax // rax = a[6] 807 mulq %r11 // (rdx, rax) = a[6] * a[0] 808 ADD_CARRY %rax,%r14 // r14 = hi(a[5] * a[0]) + lo(a[6] * a[0]) 809 ADD_CARRY %r12,%r14 // r14 = hi(a[5] * a[0]) + lo(a[6] * a[0]) + hi(a[4] * a[1]) + lo(a[5] * a[1]) 810 811 movq (%rbx),%rax // rax = a[6] 812 movq %rdx,%r15 // r15 = hi(a[6] * a[0]) 813 mulq %r10 // (rdx, rax) = a[6] * a[1] 814 ADD_CARRY %rax,%r13 // r13 = lo(a[6] * a[1]) 815 movq %r14,16(%rdi,%rcx) // t[6] = r11 816 movq %rdx,%r12 // r12 = hi(a[6] * a[1]) 817 818 leaq 8(%rbx),%rbx // rbx = a[7] 819 movq (%rbx),%rax // rax = a[7] 820 mulq %r11 // (rdx, rax) = a[7] * a[0] 821 ADD_CARRY %rax,%r15 // r15 = hi(a[6] * a[0]) + lo(a[7] * a[0]) 822 ADD_CARRY %r13,%r15 // r15 = hi(a[6] * a[0]) + lo(a[7] * a[0]) + lo(a[6] * a[1]) 823 movq %r15,24(%rdi,%rcx) // t[7] = hi(a[6] * a[0]) + lo(a[7] * a[0]) + lo(a[6] * a[1]) 824 movq %rdx,%r14 // r14 = hi(a[7] * a[0]) 825 826 movq (%rbx),%rax // rax = a[7] 827 leaq 32(%rcx),%rcx // j += 2 828 cmpq $0,%rcx // if j != 0 829 jne .Loop1stSqr4x 830 831 mulq %r10 // (rdx, rax) = a[7] * a[1] 832 ADD_CARRY %rax,%r12 // r12 = hi(a[6] * a[1]) + lo(a[7] * a[1]) 833 leaq 16(%rbp),%rbp // i++ 834 ADD_CARRY %r14,%r12 // r12 = hi(a[6] * a[1]) + hi(a[7] * a[0]) + lo(a[7] * a[1]) 835 836 movq %r12,(%rdi) // t[8] = r13 837 movq %rdx,%r13 // r13 = hi(a[7] * a[1]) 838 movq %rdx,8(%rdi) // t[9] = hi(a[7] * a[1]) 839 840.align 32 841.LoopOuterSqr4x: 842 movq -32(%rsi,%rbp),%r11 // r11 = a[0] 843 movq -24(%rsi,%rbp),%r10 // r10 = a[1] 844 845 leaq -16(%rsi,%rbp),%rbx // rbx = a[2] 846 leaq 56(%rsp,%r9,2),%rdi // rdi = t[size * 2 - i] 847 leaq -32(%rdi,%rbp),%rdi 848 849 movq %r10,%rax // rax = a[1] 850 mulq %r11 // (rdx, rax) = a[1] * a[0] 851 movq -24(%rdi,%rbp),%r15 // r15 = t[1] 852 ADD_CARRY %rax,%r15 // r15 = lo(a[1] * a[0]) + t[1] 853 movq %r15,-24(%rdi,%rbp) // t[1] = r10 854 movq %rdx,%r14 // r14 = hi(a[1] * a[0]) 855 856 movq (%rbx),%rax // rax = a[2] 857 mulq %r11 // (rdx, rax) = a[2] * a[0] 858 ADD_CARRY %rax,%r14 // r14 = hi(a[1] * a[0]) + lo(a[2] * a[0]) 859 addq -16(%rdi,%rbp),%r14 // r14 = hi(a[1] * a[0]) + lo(a[2] * a[0]) + t[2] 860 adcq $0,%rdx // r10 += CF 861 movq %rdx,%r15 // r10 = hi(a[2] * a[0]) 862 movq %r14,-16(%rdi,%rbp) // t[2] = r11 863 864 xorq %r13,%r13 // Clear CF. 865 866 movq (%rbx),%rax // rax = a[2] 867 mulq %r10 // (rdx, rax) = a[2] * a[1] 868 ADD_CARRY %rax,%r13 // r13 = lo(a[2] * a[1]) 869 addq -8(%rdi,%rbp),%r13 // r13 = lo(a[2] * a[1]) + t[3] 870 adcq $0,%rdx 871 movq %rdx,%r12 // r12 = hi(a[2] * a[1]) 872 873 leaq 8(%rbx),%rbx // rbx = a[3] 874 movq (%rbx),%rax // rax = a[3] 875 mulq %r11 // (rdx, rax) = a[3] * a[0] 876 ADD_CARRY %rax,%r15 // r15 = hi(a[2] * a[0]) + lo(a[3] * a[0]) 877 ADD_CARRY %r13,%r15 // r15 = hi(a[2] * a[0]) + lo(a[3] * a[0]) + lo(a[2] * a[1]) + t[3] 878 879 movq (%rbx),%rax // rax = a[3] 880 leaq (%rbp),%rcx // j = i 881 movq %r15,-8(%rdi,%rbp) // t[3] = r10 882 movq %rdx,%r14 // r14 = hi(a[3] * a[0]) 883 884.align 32 885.LoopInnerSqr4x: 886 leaq (%rsi,%rcx),%rbx // rbx = a[4] 887 mulq %r10 // (rdx, rax) = a[3] * a[1] 888 ADD_CARRY %rax,%r12 // r12 = hi(a[2] * a[1]) + lo(a[3] * a[1]) 889 movq (%rbx),%rax // rax = a[4] 890 movq %rdx,%r13 // r13 = hi(a[3] * a[1]) 891 addq (%rdi,%rcx),%r12 // r12 = hi(a[2] * a[1]) + lo(a[3] * a[1]) + t[4] 892 adcq $0,%rdx // r13 += CF 893 movq %rdx,%r13 // r13 = hi(a[3] * a[1]) 894 895 mulq %r11 // (rdx, rax) = a[4] * a[0] 896 ADD_CARRY %rax,%r14 // r14 = hi(a[3] * a[0]) + lo(a[4] * a[0]) 897 ADD_CARRY %r12,%r14 // r14 = hi(a[3] * a[0]) + lo(a[4] * a[0]) + hi(a[2] * a[1]) + lo(a[3] * a[1]) + t[4] 898 movq %r14,(%rdi,%rcx) // t[4] = r11 899 movq %rdx,%r15 // r15 = hi(a[4] * a[0]) 900 901 movq (%rbx),%rax // rax = a[4] 902 mulq %r10 // (rdx, rax) = a[4] * a[1] 903 ADD_CARRY %rax,%r13 // r13 = hi(a[3] * a[1]) + lo(a[4] * a[1]) 904 addq 8(%rdi,%rcx),%r13 // r13 = hi(a[3] * a[1]) + lo(a[4] * a[1]) + t[5] 905 adcq $0,%rdx // r12 += CF 906 907 leaq 8(%rbx),%rbx // rbx = a[5] 908 movq (%rbx),%rax // rax = a[5] 909 movq %rdx,%r12 // r12 = hi(a[4] * a[1]) 910 mulq %r11 // (rdx, rax) = a[5] * a[0] 911 ADD_CARRY %rax,%r15 // r15 = hi(a[4] * a[0]) + lo(a[5] * a[0]) 912 ADD_CARRY %r13,%r15 // r15 = hi(a[4] * a[0]) + lo(a[5] * a[0]) + hi(a[3] * a[1]) + lo(a[4] * a[1]) + t[5] 913 movq %r15,8(%rdi,%rcx) // t[5] = r10 914 movq %rdx,%r14 // r14 = hi(a[5] * a[0]) 915 916 movq (%rbx),%rax // rax = a[5] 917 leaq 16(%rcx),%rcx // j++ 918 cmpq $0,%rcx // if j != 0 919 jne .LoopInnerSqr4x 920 921 mulq %r10 // (rdx, rax) = a[5] * a[1] 922 ADD_CARRY %rax,%r12 // r12 = hi(a[4] * a[1]) + lo(a[5] * a[1]) 923 ADD_CARRY %r14,%r12 // r12 = hi(a[4] * a[1]) + lo(a[5] * a[1]) + hi(a[5] * a[0]) 924 925 movq %r12,(%rdi) // t[6] = r13 926 movq %rdx,%r13 // r13 = hi(a[5] * a[1]) 927 movq %rdx,8(%rdi) // t[7] = hi(a[5] * a[1]) 928 929 addq $16,%rbp // i++ 930 jnz .LoopOuterSqr4x // if i != 0 931 932 movq -32(%rsi),%r11 // r11 = a[0] 933 leaq 56(%rsp,%r9,2),%rdi // rdi = t[2 * size] 934 movq -24(%rsi),%rax // rax = a[1] 935 leaq -32(%rdi,%rbp),%rdi // rdi = t[2 * size - i] 936 movq -16(%rsi),%rbx // rbx = a[2] 937 movq %rax,%r10 // r10 = a[1] 938 939 mulq %r11 // (rdx, rax) = a[1] * a[0] 940 ADD_CARRY %rax,%r15 // r15 = lo(a[1] * a[0]) + t[1] 941 942 movq %rbx,%rax // rax = a[2] 943 movq %rdx,%r14 // r14 = hi(a[1] * a[0]) 944 mulq %r11 // (rdx, rax) = a[2] * a[0] 945 ADD_CARRY %rax,%r14 // r14 = hi(a[1] * a[0]) + lo(a[2] * a[0]) 946 movq %r15,-24(%rdi) // t[1] = r10 947 ADD_CARRY %r12,%r14 // r14 = lo(a[2] * a[0]) + t[2] 948 949 movq %rbx,%rax // rax = a[2] 950 movq %rdx,%r15 // r15 = hi(a[2] * a[0]) 951 mulq %r10 // (rdx, rax) = a[2] * a[1] 952 ADD_CARRY %rax,%r13 // r13 = lo(a[2] * a[1]) + t[3] 953 movq %r14,-16(%rdi) // t[2] = r11 954 movq %rdx,%r12 // r12 = hi(a[2] * a[1]) 955 956 movq -8(%rsi),%rbx // rbx = a[3] 957 movq %rbx,%rax // rax = a[3] 958 mulq %r11 // (rdx, rax) = a[3] * a[0] 959 ADD_CARRY %rax,%r15 // r15 = hi(a[2] * a[0]) + lo(a[3] * a[0]) 960 ADD_CARRY %r13,%r15 // r15 = hi(a[2] * a[0]) + lo(a[3] * a[0]) + lo(a[2] * a[1]) + t[3] 961 962 movq %rbx,%rax // rax = a[3] 963 movq %r15,-8(%rdi) // t[3] = r10 964 movq %rdx,%r14 // r14 = hi(a[3] * a[0]) 965 mulq %r10 // (rdx, rax) = a[3] * a[1] 966 ADD_CARRY %rax,%r12 // r12 = hi(a[2] * a[1]) + lo(a[3] * a[1]) 967 ADD_CARRY %r14,%r12 // r12 = hi(a[3] * a[0]) + hi(a[2] * a[1]) + lo(a[3] * a[1]) 968 969 movq %r12,(%rdi) // t[4] = r13 970 movq %rdx,%r13 // r13 = hi(a[3] * a[1]) 971 movq %rdx,8(%rdi) // t[5] = hi(a[3] * a[1]) 972 973 movq -16(%rsi),%rax // rax = a[2] 974 mulq %rbx // (rdx, rax) = a[3] * a[2] 975 addq $16,%rbp 976 xorq %r11,%r11 977 subq %r9,%rbp // i = 16 - size 978 xorq %r10,%r10 979 980 ADD_CARRY %r13,%rax // rax = hi(a[3] * a[1]) + lo(a[3] * a[2]) 981 movq %rax,8(%rdi) // t[5] = hi(a[3] * a[1]) + lo(a[3] * a[2]) 982 movq %rdx,16(%rdi) // t[6] = hi(a[3] * a[2]) 983 movq %r10,24(%rdi) // t[7] = 0 984 985 movq -16(%rsi,%rbp),%rax // rax = a[0] 986 leaq 56(%rsp),%rdi // rdi = t[0] 987 xorq %r15,%r15 988 movq 8(%rdi),%r14 // r14 = t[1] 989 990 leaq (%r11,%r15,2),%r13 991 shrq $63,%r15 // Cyclically shifts 63 bits to the right to obtain the lower bits. 992 leaq (%rcx,%r14,2),%r12 // r12 = t[1] * 2 993 shrq $63,%r14 // r14 = t[1] >> 63 994 orq %r15,%r12 // r12 = t[1] * 2 995 movq 16(%rdi),%r15 // r15 = t[2] 996 movq %r14,%r11 // r11 = t[1] >> 63 997 mulq %rax // (rdx, rax) = a[0] * a[0] 998 negq %r10 // If the value is not 0, CF is set to 1. 999 adcq %rax,%r13 // r13 = lo(a[0] * a[0]) 1000 movq 24(%rdi),%r14 // r14 = t[3] 1001 movq %r13,(%rdi) // t[0] = 0 1002 adcq %rdx,%r12 // r12 = t[1] * 2 + hi(a[0] * a[0]) 1003 1004 leaq (%r11,%r15,2),%rbx // rbx = t[2] * 2 + t[1] >> 63 1005 movq -8(%rsi,%rbp),%rax // rax = a[1] 1006 movq %r12,8(%rdi) // t[1] = t[1] * 2 + hi(a[0] * a[0]) 1007 sbbq %r10,%r10 // r10 = -CF clear CF 1008 shrq $63,%r15 // r15 = t[2] >> 63 1009 leaq (%rcx,%r14,2),%r8 // r8 = t[3] * 2 1010 shrq $63,%r14 // r14 = t[3] >> 63 1011 orq %r15,%r8 // r8 = (t[3] * 2) + (t[2] >> 63) 1012 movq 32(%rdi),%r15 // r15 = t[4] 1013 movq %r14,%r11 // r11 = t[3] >> 63 1014 mulq %rax // (rdx, rax) = a[1] * a[1] 1015 negq %r10 // If the value is not 0, CF is set to 1. 1016 movq 40(%rdi),%r14 // r14 = t[5] 1017 adcq %rax,%rbx // rbx = t[2] * 2 + t[1] >> 63 + lo(a[1] * a[1]) 1018 movq (%rsi,%rbp),%rax // rax = a[2] 1019 movq %rbx,16(%rdi) // t[2] = t[2] * 2 + t[1] >> 63 + lo(a[1] * a[1]) 1020 adcq %rdx,%r8 // r8 = t[3] * 2 + t[2] >> 63 + hi(a[1] * a[1]) 1021 leaq 16(%rbp),%rbp // i++ 1022 movq %r8,24(%rdi) // t[3] = r8 1023 sbbq %r10,%r10 // r10 = -CF clear CF. 1024 leaq 64(%rdi),%rdi // t += 64 1025 1026.align 32 1027.LoopShiftAddSqr4x: 1028 leaq (%r11,%r15,2),%r13 // r13 = t[4] * 2 + t[3] >> 63 1029 shrq $63,%r15 // r15 = t[4] >> 63 1030 leaq (%rcx,%r14,2),%r12 // r12 = t[5] * 2 1031 shrq $63,%r14 // r14 = t[5] >> 63 1032 orq %r15,%r12 // r12 = (t[5] * 2) + t[4] >> 63 1033 movq -16(%rdi),%r15 // r15 = t[6] 1034 movq %r14,%r11 // r11 = t[5] >> 63 1035 mulq %rax // (rdx, rax) = a[2] * a[2] 1036 negq %r10 // r10 = CF 1037 movq -8(%rdi),%r14 // r14 = t[7] 1038 adcq %rax,%r13 // r13 = t[4] * 2 + t[3] >> 63 + lo(a[2] * a[2]) 1039 movq %r13,-32(%rdi) // t[4] = r12 1040 adcq %rdx,%r12 // r12 = (t[5] * 2) + t[4] >> 63 + hi(a[2] * a[2]) 1041 1042 leaq (%r11,%r15,2),%rbx // rbx = t[6] * 2 + t[5] >> 63 1043 movq -8(%rsi,%rbp),%rax // rax = a[3] 1044 movq %r12,-24(%rdi) // t[5] = hi(a[2] * a[2]) 1045 sbbq %r10,%r10 // r10 = -CF 1046 shrq $63,%r15 // r15 = t[6] >> 63 1047 leaq (%rcx,%r14,2),%r8 // r8 = t[7] * 2 1048 shrq $63,%r14 // r14 = t[7] >> 63 1049 orq %r15,%r8 // r8 = t[7] * 2 + t[6] >> 63 1050 movq 0(%rdi),%r15 // r15 = t[8] 1051 movq %r14,%r11 // r11 = t[7] >> 63 1052 mulq %rax // (rdx, rax) = a[3] * a[3] 1053 negq %r10 // r10 = CF 1054 movq 8(%rdi),%r14 // r14 = t[9] 1055 adcq %rax,%rbx // rbx = t[6] * 2 + t[5] >> 63 + lo(a[3] * a[3]) 1056 movq %rbx,-16(%rdi) // t[6] = rbx 1057 adcq %rdx,%r8 // r8 = t[7] * 2 + t[6] >> 63 + hi(a[3] * a[3]) 1058 1059 leaq (%r11,%r15,2),%r13 // r13 = t[8] * 2 + t[7] >> 63 1060 movq %r8,-8(%rdi) // t[7] = hi(a[3] * a[3]) 1061 movq (%rsi,%rbp),%rax // rax = a[4] 1062 sbbq %r10,%r10 // r10 = -CF 1063 shrq $63,%r15 // r15 = t[8] >> 63 1064 leaq (%rcx,%r14,2),%r12 // r12 = t[9] * 2 1065 shrq $63,%r14 // r14 = t[9] >> 63 1066 orq %r15,%r12 // r12 = t[9] * 2 + t[8] >> 63 1067 movq 16(%rdi),%r15 // r15 = t[10] 1068 movq %r14,%r11 // r11 = t[9] >> 63 1069 mulq %rax // (rdx, rax) = a[4] * a[4] 1070 negq %r10 // r10 = -CF 1071 movq 24(%rdi),%r14 // r14 = t[11] 1072 adcq %rax,%r13 // r13 = t[8] * 2 + t[7] >> 63 + lo(a[4] * a[4]) 1073 movq %r13,(%rdi) // t[8] = r12 1074 adcq %rdx,%r12 // r12 = t[9] * 2 + t[8] >> 63 + hi(a[4] * a[4]) 1075 1076 leaq (%r11,%r15,2),%rbx // rbx = t[10] * 2 + t[9] >> 63 1077 movq 8(%rsi,%rbp),%rax // rax = a[5] 1078 movq %r12,8(%rdi) // t[9] = r13 1079 sbbq %r10,%r10 // r10 = -CF 1080 shrq $63,%r15 // r15 = t[10] >> 63 1081 leaq (%rcx,%r14,2),%r8 // r8 = t[11] * 2 1082 shrq $63,%r14 // r14 = t[11] >> 63 1083 orq %r15,%r8 // r8 = t[11] * 2 + t[10] >> 63 1084 movq 32(%rdi),%r15 // r15 = t[12] 1085 movq %r14,%r11 // r11 = t[11] >> 63 1086 mulq %rax // (rdx, rax) = a[5] * a[5] 1087 negq %r10 // r10 = CF 1088 movq 40(%rdi),%r14 // r14 = t[13] 1089 adcq %rax,%rbx // rbx = t[10] * 2 + t[9] >> 63 + lo(a[5] * a[5]) 1090 movq 16(%rsi,%rbp),%rax // rax = a[6] 1091 movq %rbx,16(%rdi) // t[10] = rbx 1092 adcq %rdx,%r8 // r8 = t[11] * 2 + t[10] >> 63 + hi(a[5] * a[5]) 1093 movq %r8,24(%rdi) // t[11] = r8 1094 sbbq %r10,%r10 // r10 = -CF 1095 leaq 64(%rdi),%rdi // t += 64 1096 addq $32,%rbp // i += 4 1097 jnz .LoopShiftAddSqr4x // if i != 0 1098 1099 leaq (%r11,%r15,2),%r13 // r13 = t[12] * 2 + t[11] >> 63 1100 shrq $63,%r15 // r15 = t[12] >> 63 1101 leaq (%rcx,%r14,2),%r12 // r12 = t[13] * 2 1102 shrq $63,%r14 // r14 = t[13] >> 63 1103 orq %r15,%r12 // r12 = t[13] * 2 + t[12] >> 63 1104 movq -16(%rdi),%r15 // r15 = t[14] 1105 movq %r14,%r11 // r11 = t[13] >> 63 1106 mulq %rax // (rdx, rax) = a[6] * a[6] 1107 negq %r10 // r10 = CF 1108 movq -8(%rdi),%r14 // r14 = t[15] 1109 adcq %rax,%r13 // r13 = t[12] * 2 + t[11] >> 63 + lo(a[6] * a[6]) 1110 movq %r13,-32(%rdi) // t[12] = r12 1111 adcq %rdx,%r12 // r12 = t[13] * 2 + t[12] >> 63 + hi(a[6] * a[6]) 1112 1113 leaq (%r11,%r15,2),%rbx // rbx = t[14] * 2 + t[13] >> 63 1114 movq -8(%rsi),%rax // rax = a[7] 1115 movq %r12,-24(%rdi) // t[13] = r13 1116 sbbq %r10,%r10 // r10 = -CF 1117 shrq $63,%r15 // r15 = t[14] >> 63 1118 leaq (%rcx,%r14,2),%r8 // r8 = t[15] * 2 1119 shrq $63,%r14 // r14 = t[15] >> 63 1120 orq %r15,%r8 // r8 = t[15] * 2 + t[14] >> 63 1121 mulq %rax // (rdx, rax) = a[7] * a[7] 1122 negq %r10 // r10 = CF 1123 adcq %rax,%rbx // rbx = t[14] * 2 + t[13] >> 63 + lo(a[7] * a[7]) 1124 adcq %rdx,%r8 // r8 = t[15] * 2 + t[14] >> 63 + hi(a[7] * a[7]) 1125 movq %rbx,-16(%rdi) // t[14] = rbx 1126 movq %r8,-8(%rdi) // t[15] = r8 1127 1128 movq %xmm1,%rbp // rbp = n 1129 xorq %rax,%rax // rax = 0 1130 leaq (%r9,%rbp),%rcx // rcx = n[size] 1131 leaq 56(%rsp,%r9,2),%rdx // rdx = t[size * 2] 1132 movq %rcx,8(%rsp) 1133 leaq 56(%rsp,%r9),%rdi 1134 movq %rdx,16(%rsp) 1135 negq %r9 1136 1137.align 32 1138.LoopReduceSqr8x: 1139 leaq (%rdi,%r9),%rdi // rdi = t[] 1140 1141 movq (%rdi),%rbx // rbx = t[0] 1142 movq 8(%rdi),%r9 // r9 = t[1] 1143 movq 16(%rdi),%r15 // r15 = t[2] 1144 movq 24(%rdi),%r14 // r14 = t[3] 1145 movq 32(%rdi),%r13 // r13 = t[4] 1146 movq 40(%rdi),%r12 // r12 = t[5] 1147 movq 48(%rdi),%r11 // r11 = t[6] 1148 movq 56(%rdi),%r10 // r10 = t[7] 1149 movq %rax,(%rdx) // Store the highest carry bit. 1150 leaq 64(%rdi),%rdi // rdi = t[8] 1151 1152 movq %rbx,%r8 // r8 = t[0] 1153 imulq 40(%rsp),%rbx // rbx = k0 * t[0] 1154 movl $8,%ecx 1155 1156.align 32 1157.LoopReduce8x: 1158 movq (%rbp),%rax // rax = n[0] 1159 mulq %rbx // (rdx, rax) = t[0] * k0 * n[0] 1160 negq %r8 // r8 = -t[0], If t[0] is not 0, set CF to 1. 1161 movq %rdx,%r8 // r8 = hi(t[0] * k0 * n[0]) 1162 adcq $0,%r8 // r8 += CF 1163 1164 movq 8(%rbp),%rax // rax = n[1] 1165 mulq %rbx // (rdx, rax) = t[0] * k0 * n[1] 1166 movq %rbx,48(%rsp,%rcx,8) 1167 ADD_CARRY %rax,%r9 // r9 = t[1] + lo(t[0] * k0 * n[1]) 1168 ADD_CARRY %r9,%r8 // r8 = hi(t[0] * k0 * n[0]) + lo(t[0] * k0 * n[1]) + t[1] 1169 1170 movq 16(%rbp),%rax // rax = n[2] 1171 movq %rdx,%r9 // r9 = hi(t[0] * k0 * n[1]) 1172 mulq %rbx // (rdx, rax) = t[0] * k0 * n[2] 1173 ADD_CARRY %rax,%r15 // r15 = lo(t[0] * k0 * n[2]) + t[2] 1174 ADD_CARRY %r15,%r9 // r9 = hi(t[0] * k0 * n[1]) + lo(t[0] * k0 * n[2]) + t[2] 1175 movq 40(%rsp),%rsi // rsi = k0 1176 movq %rdx,%r15 // r15 = hi(t[0] * k0 * n[2]) 1177 1178 movq 24(%rbp),%rax // rax = n[3] 1179 mulq %rbx // (rdx, rax) = t[0] * k0 * n[3] 1180 ADD_CARRY %rax,%r14 // r14 = lo(t[0] * k0 * n[3]) 1181 imulq %r8,%rsi // rsi = k0 * r8 1182 ADD_CARRY %r14,%r15 // r15 = hi(t[0] * k0 * n[2]) + lo(t[0] * k0 * n[3]) 1183 movq %rdx,%r14 // r14 = hi(t[0] * k0 * n[3]) 1184 1185 movq 32(%rbp),%rax // rax = n[4] 1186 mulq %rbx // (rdx, rax) = t[0] * k0 * n[4] 1187 ADD_CARRY %rax,%r13 // r13 = lo(t[0] * k0 * n[4]) + t[4] 1188 ADD_CARRY %r13,%r14 // r14 = hi(t[0] * k0 * n[3]) + lo(t[0] * k0 * n[4]) + t[4]、 1189 1190 movq 40(%rbp),%rax // rax = n[5] 1191 movq %rdx,%r13 // r13 = hi(t[0] * k0 * n[4]) 1192 mulq %rbx // (rdx, rax) = t[0] * k0 * n[5] 1193 ADD_CARRY %rax,%r12 // r12 = lo(t[0] * k0 * n[5]) + t[5] 1194 ADD_CARRY %r12,%r13 // r13 = hi(t[0] * k0 * n[4]) + lo(t[0] * k0 * n[5]) + t[5] 1195 1196 movq 48(%rbp),%rax // rax = n[6] 1197 movq %rdx,%r12 // r12 = hi(t[0] * k0 * n[5]) 1198 mulq %rbx // (rdx, rax) = t[0] * k0 * n[6] 1199 ADD_CARRY %rax,%r11 // r11 = lo(t[0] * k0 * n[6]) + t[6] 1200 ADD_CARRY %r11,%r12 // r12 = hi(t[0] * k0 * n[5]) + lo(t[0] * k0 * n[6]) + t[6] 1201 1202 movq 56(%rbp),%rax // rax = n[7] 1203 movq %rdx,%r11 // r11 = hi(t[0] * k0 * n[6]) 1204 mulq %rbx // (rdx, rax) = t[0] * k0 * n[7] 1205 movq %rsi,%rbx // rbx = k0 * r8 1206 ADD_CARRY %rax,%r10 // r10 = lo(t[0] * k0 * n[7]) + t[7] 1207 ADD_CARRY %r10,%r11 // r11 = hi(t[0] * k0 * n[6]) + lo(t[0] * k0 * n[7]) + t[7] 1208 movq %rdx,%r10 // r10 = hi(t[0] * k0 * n[7]) 1209 1210 decl %ecx // ecx-- 1211 jnz .LoopReduce8x // if ecx != 0 1212 1213 leaq 64(%rbp),%rbp // rbp += 64, n Pointer Offset. 1214 xorq %rax,%rax // rax = 0 1215 movq 16(%rsp),%rdx // rdx = t[size * 2] 1216 cmpq 8(%rsp),%rbp // rbp = n[size] 1217 jae .LoopEndCondMul8x 1218 1219 addq (%rdi),%r8 // r8 += t[0] 1220 adcq 8(%rdi),%r9 // r9 += t[1] 1221 adcq 16(%rdi),%r15 // r15 += t[2] 1222 adcq 24(%rdi),%r14 // r14 += t[3] 1223 adcq 32(%rdi),%r13 // r13 += t[4] 1224 adcq 40(%rdi),%r12 // r12 += t[5] 1225 adcq 48(%rdi),%r11 // r11 += t[6] 1226 adcq 56(%rdi),%r10 // r10 += t[7] 1227 sbbq %rsi,%rsi // rsi = -CF 1228 1229 movq 112(%rsp),%rbx // rbx = t[0] * k0, 48 + 56 + 8 1230 movl $8,%ecx 1231 1232.align 32 1233.LoopLastSqr8x: 1234 movq (%rbp),%rax // rax = n[0] 1235 mulq %rbx // (rdx, rax) = t[0] * k0 * n[0] 1236 ADD_CARRY %rax,%r8 // r8 += lo(t[0] * k0 * n[0]) 1237 movq %r8,(%rdi) // t[0] = r8 1238 leaq 8(%rdi),%rdi // t++ 1239 movq %rdx,%r8 // r8 = hi(t[0] * k0 * n[0]) 1240 1241 movq 8(%rbp),%rax // rax = n[1] 1242 mulq %rbx // (rdx, rax) = t[0] * k0 * n[1] 1243 ADD_CARRY %rax,%r9 // r9 += lo(t[0] * k0 * n[1]) 1244 ADD_CARRY %r9,%r8 // r8 = hi(t[0] * k0 * n[0]) + r9 1245 1246 movq 16(%rbp),%rax // rax = n[2] 1247 movq %rdx,%r9 // r9 = hi(t[0] * k0 * n[1]) 1248 mulq %rbx // (rdx, rax) = t[0] * k0 * n[2] 1249 ADD_CARRY %rax,%r15 // r15 += lo(t[0] * k0 * n[2]) 1250 ADD_CARRY %r15,%r9 // r9 = hi(t[0] * k0 * n[1]) + r10 1251 1252 movq 24(%rbp),%rax // rax = n[3] 1253 movq %rdx,%r15 // r15 = hi(t[0] * k0 * n[2]) 1254 mulq %rbx // (rdx, rax) = t[0] * k0 * n[3] 1255 ADD_CARRY %rax,%r14 // r14 += lo(t[0] * k0 * n[3]) 1256 ADD_CARRY %r14,%r15 // r15 = hi(t[0] * k0 * n[2]) + r11 1257 1258 movq 32(%rbp),%rax // rax = n[4] 1259 movq %rdx,%r14 // r14 = hi(t[0] * k0 * n[3]) 1260 mulq %rbx // (rdx, rax) = t[0] * k0 * n[4] 1261 ADD_CARRY %rax,%r13 // r13 += lo(t[0] * k0 * n[4]) 1262 ADD_CARRY %r13,%r14 // r14 = hi(t[0] * k0 * n[3]) + r12 1263 1264 movq 40(%rbp),%rax // rax = n[5] 1265 movq %rdx,%r13 // r13 = hi(t[0] * k0 * n[4]) 1266 mulq %rbx // (rdx, rax) = t[0] * k0 * n[5] 1267 ADD_CARRY %rax,%r12 // r12 += lo(t[0] * k0 * n[5]) 1268 ADD_CARRY %r12,%r13 // r13 = hi(t[0] * k0 * n[4]) + r13 1269 1270 movq 48(%rbp),%rax // rax = n[6] 1271 movq %rdx,%r12 // r12 = hi(t[0] * k0 * n[5]) 1272 mulq %rbx // (rdx, rax) = t[0] * k0 * n[6] 1273 ADD_CARRY %rax,%r11 // r11 += lo(t[0] * k0 * n[6]) 1274 ADD_CARRY %r11,%r12 // r12 = hi(t[0] * k0 * n[5]) + r14 1275 1276 movq 56(%rbp),%rax // rax = n[7] 1277 movq %rdx,%r11 // r11 = hi(t[0] * k0 * n[6]) 1278 mulq %rbx // (rdx, rax) = t[0] * k0 * n[7] 1279 movq 40(%rsp,%rcx,8),%rbx // rbx = t[i] * k0 1280 ADD_CARRY %rax,%r10 // r10 += lo(t[0] * k0 * n[7]) 1281 ADD_CARRY %r10,%r11 // r11 = hi(t[0] * k0 * n[6]) + r10 1282 movq %rdx,%r10 // r10 = hi(t[0] * k0 * n[7]) 1283 1284 decl %ecx // ecx-- 1285 jnz .LoopLastSqr8x // if ecx != 0 1286 1287 leaq 64(%rbp),%rbp // n += 8 1288 movq 16(%rsp),%rdx // rdx = t[size * 2] 1289 cmpq 8(%rsp),%rbp // Check whether rbp is at the end of the n array. If yes, exit the loop. 1290 jae .LoopSqrBreak8x 1291 1292 movq 112(%rsp),%rbx // rbx = t[0] * k0 1293 negq %rsi // rsi = CF 1294 movq (%rbp),%rax // rax = = n[0] 1295 adcq (%rdi),%r8 // r8 = t[0] 1296 adcq 8(%rdi),%r9 // r9 = t[1] 1297 adcq 16(%rdi),%r15 // r15 = t[2] 1298 adcq 24(%rdi),%r14 // r14 = t[3] 1299 adcq 32(%rdi),%r13 // r13 = t[4] 1300 adcq 40(%rdi),%r12 // r12 = t[5] 1301 adcq 48(%rdi),%r11 // r11 = t[6] 1302 adcq 56(%rdi),%r10 // r10 = t[7] 1303 sbbq %rsi,%rsi // rsi = -CF 1304 1305 movl $8,%ecx // ecx = 8 1306 jmp .LoopLastSqr8x 1307 1308.align 32 1309.LoopSqrBreak8x: 1310 xorq %rax,%rax // rax = 0 1311 addq (%rdx),%r8 // r8 += Highest carry bit. 1312 adcq $0,%r9 // r9 += CF 1313 adcq $0,%r15 // r15 += CF 1314 adcq $0,%r14 // r14 += CF 1315 adcq $0,%r13 // r13 += CF 1316 adcq $0,%r12 // r12 += CF 1317 adcq $0,%r11 // r11 += CF 1318 adcq $0,%r10 // r10 += CF 1319 adcq $0,%rax // rax += CF 1320 1321 negq %rsi // rsi = CF 1322.LoopEndCondMul8x: 1323 adcq (%rdi),%r8 // r8 += t[0] 1324 adcq 8(%rdi),%r9 // r9 += t[1] 1325 adcq 16(%rdi),%r15 // r15 += t[2] 1326 adcq 24(%rdi),%r14 // r14 += t[3] 1327 adcq 32(%rdi),%r13 // r13 += t[4] 1328 adcq 40(%rdi),%r12 // r12 += t[5] 1329 adcq 48(%rdi),%r11 // r11 += t[6] 1330 adcq 56(%rdi),%r10 // r10 += t[7] 1331 adcq $0,%rax // rax += CF 1332 movq -8(%rbp),%rcx // rcx = n[7] 1333 xorq %rsi,%rsi // rsi = 0 1334 1335 movq %xmm1,%rbp // rbp = n 1336 movq %r8,(%rdi) // Save the calculated result back to t[]. 1337 movq %r9,8(%rdi) 1338 movq %xmm5,%r9 1339 movq %r15,16(%rdi) 1340 movq %r14,24(%rdi) 1341 movq %r13,32(%rdi) 1342 movq %r12,40(%rdi) 1343 movq %r11,48(%rdi) 1344 movq %r10,56(%rdi) 1345 leaq 64(%rdi),%rdi // t += 8 1346 1347 cmpq %rdx,%rdi // Cycle the entire t[]. 1348 jb .LoopReduceSqr8x 1349 ret 1350.cfi_endproc 1351.size MontSqr8Inner,.-MontSqr8Inner 1352 1353#endif 1354