e3c8bb575f019667b7b748d04df92743fe5663ff
[platform/upstream/gmp.git] / mpn / x86_64 / coreisbr / aorrlshC_n.asm
1 dnl  AMD64 mpn_addlshC_n -- rp[] = up[] + (vp[] << C)
2 dnl  AMD64 mpn_rsblshC_n -- rp[] = (vp[] << C) - up[]
3
4 dnl  Copyright 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
5
6 dnl  This file is part of the GNU MP Library.
7
8 dnl  The GNU MP Library is free software; you can redistribute it and/or modify
9 dnl  it under the terms of the GNU Lesser General Public License as published
10 dnl  by the Free Software Foundation; either version 3 of the License, or (at
11 dnl  your option) any later version.
12
13 dnl  The GNU MP Library is distributed in the hope that it will be useful, but
14 dnl  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 dnl  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16 dnl  License for more details.
17
18 dnl  You should have received a copy of the GNU Lesser General Public License
19 dnl  along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.
20
21
22 C            cycles/limb
23 C AMD K8,K9      ?
24 C AMD K10        ?
25 C Intel P4       ?
26 C Intel core2    3.25
27 C Intel NHM      4
28 C Intel SBR      2  C (or 1.95 when L(top)'s alignment = 16 (mod 32))
29 C Intel atom     ?
30 C VIA nano       ?
31
32 C This code probably runs close to optimally on Sandy Bridge (using 4-way
33 C unrolling).  It also runs reasonably well on Core 2, but it runs poorly on
34 C all other processors, including Nehalem.
35
36 C INPUT PARAMETERS
37 define(`rp',    `%rdi')
38 define(`up',    `%rsi')
39 define(`vp',    `%rdx')
40 define(`n',     `%rcx')
41 define(`cy',    `%r8')
42
43 ABI_SUPPORT(DOS64)
44 ABI_SUPPORT(STD64)
45
46 ASM_START()
47         TEXT
48         ALIGN(16)
49 PROLOGUE(func_nc)
50         FUNC_ENTRY(4)
51 IFDOS(` mov     56(%rsp), %r8   ')
52         push    %rbp
53         mov     cy, %rax
54         neg     %rax                    C set msb on carry
55         xor     R32(%rbp), R32(%rbp)    C limb carry
56         mov     (vp), %r8
57         shrd    $RSH, %r8, %rbp
58         mov     R32(n), R32(%r9)
59         and     $3, R32(%r9)
60         je      L(b00)
61         cmp     $2, R32(%r9)
62         jc      L(b01)
63         je      L(b10)
64         jmp     L(b11)
65 EPILOGUE()
66
67         ALIGN(16)
68 PROLOGUE(func_n)
69         FUNC_ENTRY(4)
70         push    %rbp
71         xor     R32(%rbp), R32(%rbp)    C limb carry
72         mov     (vp), %r8
73         shrd    $RSH, %r8, %rbp
74         mov     R32(n), R32(%rax)
75         and     $3, R32(%rax)
76         je      L(b00)
77         cmp     $2, R32(%rax)
78         jc      L(b01)
79         je      L(b10)
80
81 L(b11): mov     8(vp), %r9
82         shrd    $RSH, %r9, %r8
83         mov     16(vp), %r10
84         shrd    $RSH, %r10, %r9
85         add     R32(%rax), R32(%rax)    C init carry flag
86         ADCSBB  (up), %rbp
87         ADCSBB  8(up), %r8
88         ADCSBB  16(up), %r9
89         mov     %rbp, (rp)
90         mov     %r8, 8(rp)
91         mov     %r9, 16(rp)
92         mov     %r10, %rbp
93         lea     24(up), up
94         lea     24(vp), vp
95         lea     24(rp), rp
96         sbb     R32(%rax), R32(%rax)    C save carry flag
97         sub     $3, n
98         ja      L(top)
99         jmp     L(end)
100
101 L(b01): add     R32(%rax), R32(%rax)    C init carry flag
102         ADCSBB  (up), %rbp
103         mov     %rbp, (rp)
104         mov     %r8, %rbp
105         lea     8(up), up
106         lea     8(vp), vp
107         lea     8(rp), rp
108         sbb     R32(%rax), R32(%rax)    C save carry flag
109         sub     $1, n
110         ja      L(top)
111         jmp     L(end)
112
113 L(b10): mov     8(vp), %r9
114         shrd    $RSH, %r9, %r8
115         add     R32(%rax), R32(%rax)    C init carry flag
116         ADCSBB  (up), %rbp
117         ADCSBB  8(up), %r8
118         mov     %rbp, (rp)
119         mov     %r8, 8(rp)
120         mov     %r9, %rbp
121         lea     16(up), up
122         lea     16(vp), vp
123         lea     16(rp), rp
124         sbb     R32(%rax), R32(%rax)    C save carry flag
125         sub     $2, n
126         ja      L(top)
127         jmp     L(end)
128
129         ALIGN(16)
130 L(top): mov     (vp), %r8
131         shrd    $RSH, %r8, %rbp
132 L(b00): mov     8(vp), %r9
133         shrd    $RSH, %r9, %r8
134         mov     16(vp), %r10
135         shrd    $RSH, %r10, %r9
136         mov     24(vp), %r11
137         shrd    $RSH, %r11, %r10
138         lea     32(vp), vp
139         add     R32(%rax), R32(%rax)    C restore carry flag
140         ADCSBB  (up), %rbp
141         ADCSBB  8(up), %r8
142         ADCSBB  16(up), %r9
143         ADCSBB  24(up), %r10
144         lea     32(up), up
145         mov     %rbp, (rp)
146         mov     %r8, 8(rp)
147         mov     %r9, 16(rp)
148         mov     %r10, 24(rp)
149         mov     %r11, %rbp
150         lea     32(rp), rp
151         sbb     R32(%rax), R32(%rax)    C save carry flag
152         sub     $4, n
153         jnz     L(top)
154
155 L(end): shr     $RSH, %rbp
156         add     R32(%rax), R32(%rax)    C restore carry flag
157         ADCSBB  $0, %rbp
158         mov     %rbp, %rax
159         pop     %rbp
160         FUNC_EXIT()
161         ret
162 EPILOGUE()