1/
2/ This Source Code Form is subject to the terms of the Mozilla Public
3/ License, v. 2.0. If a copy of the MPL was not distributed with this
4/ file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
6.text
7
8 /  ebp - 36:	caller's esi
9 /  ebp - 32:	caller's edi
10 /  ebp - 28:
11 /  ebp - 24:
12 /  ebp - 20:
13 /  ebp - 16:
14 /  ebp - 12:
15 /  ebp - 8:
16 /  ebp - 4:
17 /  ebp + 0:	caller's ebp
18 /  ebp + 4:	return address
19 /  ebp + 8:	a	argument
20 /  ebp + 12:	a_len	argument
21 /  ebp + 16:	b	argument
22 /  ebp + 20:	c	argument
23 /  registers:
24 / 	eax:
25 /	ebx:	carry
26 /	ecx:	a_len
27 /	edx:
28 /	esi:	a ptr
29 /	edi:	c ptr
30.globl	s_mpv_mul_d
31.type	s_mpv_mul_d,@function
32s_mpv_mul_d:
33    push   %ebp
34    mov    %esp,%ebp
35    sub    $28,%esp
36    push   %edi
37    push   %esi
38    push   %ebx
39    movl   $0,%ebx		/ carry = 0
40    mov    12(%ebp),%ecx	/ ecx = a_len
41    mov    20(%ebp),%edi
42    cmp    $0,%ecx
43    je     L2			/ jmp if a_len == 0
44    mov    8(%ebp),%esi		/ esi = a
45    cld
46L1:
47    lodsl			/ eax = [ds:esi]; esi += 4
48    mov    16(%ebp),%edx	/ edx = b
49    mull   %edx			/ edx:eax = Phi:Plo = a_i * b
50
51    add    %ebx,%eax		/ add carry (%ebx) to edx:eax
52    adc    $0,%edx
53    mov    %edx,%ebx		/ high half of product becomes next carry
54
55    stosl			/ [es:edi] = ax; edi += 4;
56    dec    %ecx			/ --a_len
57    jnz    L1			/ jmp if a_len != 0
58L2:
59    mov    %ebx,0(%edi)		/ *c = carry
60    pop    %ebx
61    pop    %esi
62    pop    %edi
63    leave
64    ret
65    nop
66
67 /  ebp - 36:	caller's esi
68 /  ebp - 32:	caller's edi
69 /  ebp - 28:
70 /  ebp - 24:
71 /  ebp - 20:
72 /  ebp - 16:
73 /  ebp - 12:
74 /  ebp - 8:
75 /  ebp - 4:
76 /  ebp + 0:	caller's ebp
77 /  ebp + 4:	return address
78 /  ebp + 8:	a	argument
79 /  ebp + 12:	a_len	argument
80 /  ebp + 16:	b	argument
81 /  ebp + 20:	c	argument
82 /  registers:
83 / 	eax:
84 /	ebx:	carry
85 /	ecx:	a_len
86 /	edx:
87 /	esi:	a ptr
88 /	edi:	c ptr
89.globl	s_mpv_mul_d_add
90.type	s_mpv_mul_d_add,@function
91s_mpv_mul_d_add:
92    push   %ebp
93    mov    %esp,%ebp
94    sub    $28,%esp
95    push   %edi
96    push   %esi
97    push   %ebx
98    movl   $0,%ebx		/ carry = 0
99    mov    12(%ebp),%ecx	/ ecx = a_len
100    mov    20(%ebp),%edi
101    cmp    $0,%ecx
102    je     L4			/ jmp if a_len == 0
103    mov    8(%ebp),%esi		/ esi = a
104    cld
105L3:
106    lodsl			/ eax = [ds:esi]; esi += 4
107    mov    16(%ebp),%edx	/ edx = b
108    mull   %edx			/ edx:eax = Phi:Plo = a_i * b
109
110    add    %ebx,%eax		/ add carry (%ebx) to edx:eax
111    adc    $0,%edx
112    mov    0(%edi),%ebx		/ add in current word from *c
113    add    %ebx,%eax
114    adc    $0,%edx
115    mov    %edx,%ebx		/ high half of product becomes next carry
116
117    stosl			/ [es:edi] = ax; edi += 4;
118    dec    %ecx			/ --a_len
119    jnz    L3			/ jmp if a_len != 0
120L4:
121    mov    %ebx,0(%edi)		/ *c = carry
122    pop    %ebx
123    pop    %esi
124    pop    %edi
125    leave
126    ret
127    nop
128
129 /  ebp - 36:	caller's esi
130 /  ebp - 32:	caller's edi
131 /  ebp - 28:
132 /  ebp - 24:
133 /  ebp - 20:
134 /  ebp - 16:
135 /  ebp - 12:
136 /  ebp - 8:
137 /  ebp - 4:
138 /  ebp + 0:	caller's ebp
139 /  ebp + 4:	return address
140 /  ebp + 8:	a	argument
141 /  ebp + 12:	a_len	argument
142 /  ebp + 16:	b	argument
143 /  ebp + 20:	c	argument
144 /  registers:
145 / 	eax:
146 /	ebx:	carry
147 /	ecx:	a_len
148 /	edx:
149 /	esi:	a ptr
150 /	edi:	c ptr
151.globl	s_mpv_mul_d_add_prop
152.type	s_mpv_mul_d_add_prop,@function
153s_mpv_mul_d_add_prop:
154    push   %ebp
155    mov    %esp,%ebp
156    sub    $28,%esp
157    push   %edi
158    push   %esi
159    push   %ebx
160    movl   $0,%ebx		/ carry = 0
161    mov    12(%ebp),%ecx	/ ecx = a_len
162    mov    20(%ebp),%edi
163    cmp    $0,%ecx
164    je     L6			/ jmp if a_len == 0
165    cld
166    mov    8(%ebp),%esi		/ esi = a
167L5:
168    lodsl			/ eax = [ds:esi]; esi += 4
169    mov    16(%ebp),%edx	/ edx = b
170    mull   %edx			/ edx:eax = Phi:Plo = a_i * b
171
172    add    %ebx,%eax		/ add carry (%ebx) to edx:eax
173    adc    $0,%edx
174    mov    0(%edi),%ebx		/ add in current word from *c
175    add    %ebx,%eax
176    adc    $0,%edx
177    mov    %edx,%ebx		/ high half of product becomes next carry
178
179    stosl			/ [es:edi] = ax; edi += 4;
180    dec    %ecx			/ --a_len
181    jnz    L5			/ jmp if a_len != 0
182L6:
183    cmp    $0,%ebx		/ is carry zero?
184    jz     L8
185    mov    0(%edi),%eax		/ add in current word from *c
186    add	   %ebx,%eax
187    stosl			/ [es:edi] = ax; edi += 4;
188    jnc    L8
189L7:
190    mov    0(%edi),%eax		/ add in current word from *c
191    adc	   $0,%eax
192    stosl			/ [es:edi] = ax; edi += 4;
193    jc     L7
194L8:
195    pop    %ebx
196    pop    %esi
197    pop    %edi
198    leave
199    ret
200    nop
201
202 /  ebp - 20:	caller's esi
203 /  ebp - 16:	caller's edi
204 /  ebp - 12:
205 /  ebp - 8:	carry
206 /  ebp - 4:	a_len	local
207 /  ebp + 0:	caller's ebp
208 /  ebp + 4:	return address
209 /  ebp + 8:	pa	argument
210 /  ebp + 12:	a_len	argument
211 /  ebp + 16:	ps	argument
212 /  ebp + 20:
213 /  registers:
214 / 	eax:
215 /	ebx:	carry
216 /	ecx:	a_len
217 /	edx:
218 /	esi:	a ptr
219 /	edi:	c ptr
220
221.globl	s_mpv_sqr_add_prop
222.type	s_mpv_sqr_add_prop,@function
223s_mpv_sqr_add_prop:
224     push   %ebp
225     mov    %esp,%ebp
226     sub    $12,%esp
227     push   %edi
228     push   %esi
229     push   %ebx
230     movl   $0,%ebx		/ carry = 0
231     mov    12(%ebp),%ecx	/ a_len
232     mov    16(%ebp),%edi	/ edi = ps
233     cmp    $0,%ecx
234     je     L11			/ jump if a_len == 0
235     cld
236     mov    8(%ebp),%esi	/ esi = pa
237L10:
238     lodsl			/ %eax = [ds:si]; si += 4;
239     mull   %eax
240
241     add    %ebx,%eax		/ add "carry"
242     adc    $0,%edx
243     mov    0(%edi),%ebx
244     add    %ebx,%eax		/ add low word from result
245     mov    4(%edi),%ebx
246     stosl			/ [es:di] = %eax; di += 4;
247     adc    %ebx,%edx		/ add high word from result
248     movl   $0,%ebx
249     mov    %edx,%eax
250     adc    $0,%ebx
251     stosl			/ [es:di] = %eax; di += 4;
252     dec    %ecx		/ --a_len
253     jnz    L10			/ jmp if a_len != 0
254L11:
255    cmp    $0,%ebx		/ is carry zero?
256    jz     L14
257    mov    0(%edi),%eax		/ add in current word from *c
258    add	   %ebx,%eax
259    stosl			/ [es:edi] = ax; edi += 4;
260    jnc    L14
261L12:
262    mov    0(%edi),%eax		/ add in current word from *c
263    adc	   $0,%eax
264    stosl			/ [es:edi] = ax; edi += 4;
265    jc     L12
266L14:
267    pop    %ebx
268    pop    %esi
269    pop    %edi
270    leave
271    ret
272    nop
273
274 /
275 / Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized
276 / so its high bit is 1.   This code is from NSPR.
277 /
278 / mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,
279 / 		          mp_digit *qp, mp_digit *rp)
280
281 /  esp +  0:   Caller's ebx
282 /  esp +  4:	return address
283 /  esp +  8:	Nhi	argument
284 /  esp + 12:	Nlo	argument
285 /  esp + 16:	divisor	argument
286 /  esp + 20:	qp	argument
287 /  esp + 24:   rp	argument
288 /  registers:
289 / 	eax:
290 /	ebx:	carry
291 /	ecx:	a_len
292 /	edx:
293 /	esi:	a ptr
294 /	edi:	c ptr
295 /
296
297.globl	s_mpv_div_2dx1d
298.type	s_mpv_div_2dx1d,@function
299s_mpv_div_2dx1d:
300       push   %ebx
301       mov    8(%esp),%edx
302       mov    12(%esp),%eax
303       mov    16(%esp),%ebx
304       div    %ebx
305       mov    20(%esp),%ebx
306       mov    %eax,0(%ebx)
307       mov    24(%esp),%ebx
308       mov    %edx,0(%ebx)
309       xor    %eax,%eax		/ return zero
310       pop    %ebx
311       ret
312       nop
313
314