/* | |
* mpvecdigmulsub(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 = SI - can't be BP | |
* p = DI - can't be BP | |
* i = BP | |
* n = CX - constrained by LOOP instr | |
* m = BX | |
* oldhi = EX | |
* | |
*/ | |
.text | |
.p2align 2,0x90 | |
.globl mpvecdigmulsub | |
mpvecdigmulsub: | |
/* Prelude */ | |
pushl %ebp /* save on stack */ | |
pushl %ebx | |
pushl %esi | |
pushl %edi | |
leal 20(%esp), %ebp /* %ebp = FP for now */ | |
movl 0(%ebp), %esi /* b */ | |
movl 4(%ebp), %ecx /* n */ | |
movl 8(%ebp), %ebx /* m */ | |
movl 12(%ebp), %edi /* p */ | |
xorl %ebp, %ebp | |
pushl %ebp | |
_mulsubloop: | |
movl (%esi, %ebp, 4),%eax /* lo = b[i] */ | |
mull %ebx /* hi, lo = b[i] * m */ | |
addl 0(%esp), %eax /* lo += oldhi */ | |
jae _mulsubnocarry1 | |
incl %edx /* hi += carry */ | |
_mulsubnocarry1: | |
subl %eax, (%edi, %ebp, 4) | |
jae _mulsubnocarry2 | |
incl %edx /* hi += carry */ | |
_mulsubnocarry2: | |
movl %edx, 0(%esp) | |
incl %ebp | |
loop _mulsubloop | |
popl %eax | |
subl %eax, (%edi, %ebp, 4) | |
jae _mulsubnocarry3 | |
movl $-1, %eax | |
jmp done | |
_mulsubnocarry3: | |
movl $1, %eax | |
done: | |
/* Postlude */ | |
popl %edi | |
popl %esi | |
popl %ebx | |
popl %ebp | |
ret | |