]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libmp/amd64/mpvecdigmulsub.s
kernel: implement portable userinit() and simplify process creation
[plan9front.git] / sys / src / libmp / amd64 / mpvecdigmulsub.s
1 /*
2  *      mpvecdigmulsub(mpdigit *b, int n, mpdigit m, mpdigit *p)
3  *
4  *      p -= b*m
5  *
6  *      each step look like:
7  *              hi,lo = m*b[i]
8  *              lo += oldhi + carry
9  *              hi += carry
10  *              p[i] += lo
11  *              oldhi = hi
12  *
13  *      the registers are:
14  *              hi = DX         - constrained by hardware
15  *              lo = AX         - constrained by hardware
16  *              b = SI          - can't be BP
17  *              p = DI          - can't be BP
18  *              i = BP
19  *              n = CX          - constrained by LOOP instr
20  *              m = BX
21  *              oldhi = R8
22  *              
23  */
24 TEXT    mpvecdigmulsub(SB),$0
25         MOVQ    RARG,SI
26         MOVL    n+8(FP),CX
27         MOVL    m+16(FP),BX
28         MOVQ    p+24(FP),DI
29         XORL    BP,BP
30         MOVL    BP,R8
31 _mulsubloop:
32         MOVL    (SI)(BP*4),AX           /* lo = b[i] */
33         MULL    BX                      /* hi, lo = b[i] * m */
34         ADDL    R8,AX           /* lo += oldhi */
35         ADCL    $0, DX          /* hi += carry */
36         SUBL    AX,(DI)(BP*4)
37         ADCL    $0, DX          /* hi += carry */
38         MOVL    DX,R8
39         INCL    BP
40         LOOP    _mulsubloop
41         MOVL    CX, AX
42         SUBL    R8,(DI)(BP*4)
43         SBBQ    CX, AX
44         ORQ     $1, AX
45         RET