| /* |
| * mpvecdigmul(mpdigit *b, int n, mpdigit m, mpdigit *p) |
| * |
| * p += b*m |
| * |
| * each step look like: |
| * hi,lo = m*b[i] |
| * lo += oldhi + carry |
| * hi += carry |
| * p[i] += lo |
| * oldhi = hi |
| * |
| * the registers are: |
| * hi = DX - constrained by hardware |
| * lo = AX - constrained by hardware |
| * b+n = SI - can't be BP |
| * p+n = DI - can't be BP |
| * i-n = BP |
| * m = BX |
| * oldhi = CX |
| * |
| */ |
| .text |
| |
| .p2align 2,0x90 |
| .globl mpvecdigmuladd |
| .type mpvecdigmuladd, @function |
| mpvecdigmuladd: |
| /* Prelude */ |
| pushl %ebp |
| movl %ebx, -4(%esp) /* save on stack */ |
| movl %esi, -8(%esp) |
| movl %edi, -12(%esp) |
| |
| movl 8(%esp), %esi /* b */ |
| movl 12(%esp), %ecx /* n */ |
| movl 16(%esp), %ebx /* m */ |
| movl 20(%esp), %edi /* p */ |
| movl %ecx, %ebp |
| negl %ebp /* BP = -n */ |
| shll $2, %ecx |
| addl %ecx, %esi /* SI = b + n */ |
| addl %ecx, %edi /* DI = p + n */ |
| xorl %ecx, %ecx |
| _muladdloop: |
| movl (%esi, %ebp, 4), %eax /* lo = b[i] */ |
| mull %ebx /* hi, lo = b[i] * m */ |
| addl %ecx,%eax /* lo += oldhi */ |
| jae _muladdnocarry1 |
| incl %edx /* hi += carry */ |
| _muladdnocarry1: |
| addl %eax, (%edi, %ebp, 4) /* p[i] += lo */ |
| jae _muladdnocarry2 |
| incl %edx /* hi += carry */ |
| _muladdnocarry2: |
| movl %edx, %ecx /* oldhi = hi */ |
| incl %ebp /* i++ */ |
| jnz _muladdloop |
| xorl %eax, %eax |
| addl %ecx, (%edi, %ebp, 4) /* p[n] + oldhi */ |
| adcl %eax, %eax /* return carry out of p[n] */ |
| |
| /* Postlude */ |
| movl -4(%esp), %ebx /* restore from stack */ |
| movl -8(%esp), %esi |
| movl -12(%esp), %edi |
| movl %esp, %ebp |
| leave |
| ret |