~ubuntu-branches/ubuntu/intrepid/ecl/intrepid

« back to all changes in this revision

Viewing changes to msvc/gmp/mpn/amd64i/aorsmul_1.asm

  • Committer: Bazaar Package Importer
  • Author(s): Peter Van Eynde
  • Date: 2007-04-09 11:51:51 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20070409115151-ql8cr0kalzx1jmla
Tags: 0.9i-20070324-2
Upload to unstable. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
;
 
2
; AMD64 mpn_add_n/mpn_sub_n -- mpn add or subtract.
 
3
;
 
4
;  Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
 
5
;   
 
6
;  This file is part of the GNU MP Library.
 
7
;   
 
8
;  The GNU MP Library is free software; you can redistribute it and/or
 
9
;  modify it under the terms of the GNU Lesser General Public License as
 
10
;  published by the Free Software Foundation; either version 2.1 of the
 
11
;  License, or (at your option) any later version.
 
12
;   
 
13
;  The GNU MP Library is distributed in the hope that it will be useful,
 
14
;  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
16
;  Lesser General Public License for more details.
 
17
;   
 
18
;  You should have received a copy of the GNU Lesser General Public
 
19
;  License along with the GNU MP Library; see the file COPYING.LIB.  If
 
20
;  not, write to the Free Software Foundation, Inc., 59 Temple Place -
 
21
;  Suite 330, Boston, MA 02111-1307, USA.
 
22
;
 
23
;  Adapted by Brian Gladman AMD64 using the Microsoft VC++ v8 64-bit 
 
24
;  compiler and the YASM assembler.
 
25
;
 
26
;  Calling interface:
 
27
;
 
28
;  mp_limb_t __gmpn_<op>mul_1(                  <op> = add or sub
 
29
;               mp_ptr dst,                             ecx
 
30
;               mp_srcptr src,                  edx
 
31
;               mp_size_t size,                  r8                 
 
32
;               mp_limb_t mult                   r9
 
33
;  )
 
34
;
 
35
;  mp_limb_t __gmpn_<op>mul_1c(
 
36
;               mp_ptr dst,                             ecx
 
37
;               mp_srcptr src,                  edx
 
38
;               mp_size_t size,                  r8                  
 
39
;               mp_limb_t mult,                  r9
 
40
;               mp_limb_t carry  [rsp+0x28]
 
41
;  )
 
42
;
 
43
; Calculate src[size] multiplied by mult[1] and add to /subtract from dst[size] and 
 
44
; return the carry or borrow from the top of the result
 
45
 
 
46
%define dst             rcx
 
47
%define len      r8
 
48
%define mlt              r9
 
49
%define src             r10
 
50
%define cry             r11
 
51
 
 
52
%define UNROLL_LOG2                     4
 
53
%define UNROLL_COUNT            (1 << UNROLL_LOG2)
 
54
%define UNROLL_MASK                     (UNROLL_COUNT - 1)
 
55
%define UNROLL_BYTES            (8 * UNROLL_COUNT)
 
56
%define UNROLL_THRESHOLD        9
 
57
 
 
58
%if UNROLL_BYTES >= 256
 
59
%error unroll count is too large
 
60
%elif UNROLL_BYTES >= 128
 
61
%define off     128
 
62
%else
 
63
%define off     0
 
64
%endif
 
65
 
 
66
 
 
67
%macro  mac_sub 4
 
68
 
 
69
        global  %1%3
 
70
        global  %1%4
 
71
 
 
72
%ifdef DLL
 
73
        export  %1%3
 
74
        export  %1%4
 
75
%define         PIC
 
76
%endif
 
77
 
 
78
%1%3:
 
79
        movsxd  len,r8d
 
80
        mov             src,rdx                         ; source ptr
 
81
        xor             cry,cry                         ; carry = 0
 
82
        dec             len                                     ; test for one limb only
 
83
        jnz             %%0                                     ; if more than one
 
84
        mov             rax,[src]                       ; get limb value
 
85
        mul             mlt                                     ; rax * mlt -> rdx (hi), rax (lo)
 
86
        %2              [dst],rax                       ; add/sub from destination
 
87
        adc             rdx,byte 0                      ; add any carry into high word
 
88
        mov             rax,rdx                         ; and return the carry value
 
89
        ret
 
90
%1%4:
 
91
        movsxd  len,r8d
 
92
        mov             src,rdx                         ; source pointer
 
93
        mov             cry,[rsp+0x28]          ; carry value
 
94
        dec             len                                     ; test for one limb
 
95
        jnz             %%0                                     ; if more than one
 
96
        mov             rax,[src]                       ; get limb value
 
97
        mul             mlt                                     ; rax * mlt -> rdx (hi), rax (lo)
 
98
        add             rax,cry                         ; add in input carry
 
99
        adc             rdx,byte 0                      ; propagate it into rdx
 
100
        %2              [dst],rax                       ; add or subtract rax from dest limb
 
101
        adc             rdx,byte 0                      ; propagate carry into high word
 
102
        mov             rax,rdx
 
103
        ret
 
104
 
 
105
%%0:
 
106
        cmp             len,byte UNROLL_THRESHOLD
 
107
        mov             rax,[src]                       ; first limb of source
 
108
        ja              %%2                                     ; unroll for many limbs
 
109
        lea             src,[src+len*8+8]       ; next source limb
 
110
        lea             dst,[dst+len*8]         ; current dst limb
 
111
        neg             len
 
112
%%1:    
 
113
        mul             mlt                                     ; multiply current src limb -> rxx, rax
 
114
        add             rax,cry                         ; add in carry
 
115
        adc             rdx,byte 0                      ; propagate carry into rdx
 
116
        %2              [dst+len*8],rax         ; add or subtract rax from dest limb
 
117
        mov             rax,[src+len*8]         ; get next source limb
 
118
        adc             rdx,byte 0                      ; add carry or borrow into high word
 
119
        inc             len                                     ; go to next limb
 
120
        mov             cry,rdx                         ; high word -> carry
 
121
        jnz             %%1
 
122
        mul             mlt                                     ; one more limb to do
 
123
        add             rax,cry
 
124
        adc             rdx,byte 0
 
125
        %2              [dst],rax               
 
126
        adc             rdx,byte 0
 
127
        mov             rax,rdx                         ; return carry value as a limb
 
128
        ret
 
129
 
 
130
%define jmp_val rbp                             ; jump into code sequence
 
131
%define rep_cnt rbx                             ; repeats for full sequence
 
132
%define cry_hi  rsi                             ; second carry for alternate block
 
133
 
 
134
%%2:
 
135
        push    rbp
 
136
        push    rbx
 
137
        push    rsi
 
138
        lea             rep_cnt,[len-2]
 
139
        dec             len
 
140
        shr             rep_cnt,UNROLL_LOG2
 
141
        neg             len
 
142
        and             len,UNROLL_MASK
 
143
        mov             jmp_val,len
 
144
        mov             cry_hi,len                      ; cry_hi and jmp_val are temporary
 
145
        shl             jmp_val,2                       ; values for calculating the jump
 
146
        shl             cry_hi,4                        ; offset into the unrolled code
 
147
%ifdef PIC
 
148
        lea             cry_hi,[cry_hi+jmp_val]
 
149
        lea             jmp_val,[%%3 wrt rip]
 
150
        lea             jmp_val,[jmp_val+cry_hi]
 
151
%else
 
152
        lea     jmp_val,[cry_hi+jmp_val+%%3]
 
153
%endif
 
154
        neg             len
 
155
        mul             mlt
 
156
        add             cry,rax                         ; initial carry, becomes low carry
 
157
        adc             rdx,byte 0
 
158
        mov             cry_hi,rdx
 
159
        test    len,1
 
160
        mov             rax,[src+8]                     ; src second limb
 
161
        lea             src,[src+len*8+off+16]
 
162
        lea             dst,[dst+len*8+off]
 
163
        cmovnz  cry_hi,cry                      ; high, low carry other way around
 
164
        cmovnz  cry,rdx
 
165
        xor             len,len
 
166
        jmp             jmp_val
 
167
 
 
168
%%3:
 
169
%define CHUNK_COUNT     2
 
170
%assign i 0
 
171
%rep    UNROLL_COUNT / CHUNK_COUNT
 
172
%assign disp0   8 * i * CHUNK_COUNT - off
 
173
 
 
174
        mul             mlt
 
175
        %2              [byte dst+disp0],cry
 
176
        mov             cry,len                                         ; len = 0
 
177
        adc             cry_hi,rax
 
178
        mov             rax,[byte src+disp0]
 
179
        adc             cry,rdx 
 
180
        mul             mlt
 
181
        %2              [byte dst+disp0+8],cry_hi
 
182
        mov             cry_hi,len                                      ; len = 0
 
183
        adc             cry,rax
 
184
        mov             rax,[byte src+disp0+8]
 
185
        adc             cry_hi,rdx
 
186
 
 
187
%assign i       i + 1
 
188
%endrep
 
189
 
 
190
        dec             rep_cnt
 
191
        lea             src,[src+UNROLL_BYTES]
 
192
        lea             dst,[dst+UNROLL_BYTES]
 
193
        jns             %%3
 
194
        mul             mlt
 
195
        %2              [dst-off],cry
 
196
        adc             rax,cry_hi
 
197
        adc             rdx,len
 
198
        %2              [dst-off+8],rax
 
199
        adc             rdx,len
 
200
        mov             rax,rdx
 
201
        pop             rsi
 
202
        pop             rbx
 
203
        pop             rbp
 
204
        ret
 
205
 
 
206
%endmacro
 
207
 
 
208
        bits 64
 
209
        text
 
210
        
 
211
        mac_sub __g,add,mpn_addmul_1,mpn_addmul_1c
 
212
        mac_sub __g,sub,mpn_submul_1,mpn_submul_1c
 
213
 
 
214
        end