2
; mpi_x86.asm - assembly language implementation of s_mpv_ functions.
4
; The contents of this file are subject to the Mozilla Public
5
; License Version 1.1 (the "License"); you may not use this file
6
; except in compliance with the License. You may obtain a copy of
7
; the License at http://www.mozilla.org/MPL/
9
; Software distributed under the License is distributed on an "AS
10
; IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11
; implied. See the License for the specific language governing
12
; rights and limitations under the License.
14
; The Original Code is the Netscape security libraries.
16
; The Initial Developer of the Original Code is Netscape
17
; Communications Corporation. Portions created by Netscape are
18
; Copyright (C) 2000 Netscape Communications Corporation. All
23
; Alternatively, the contents of this file may be used under the
24
; terms of the GNU General Public License Version 2 or later (the
25
; "GPL"), in which case the provisions of the GPL are applicable
26
; instead of those above. If you wish to allow use of your
27
; version of this file only under the terms of the GPL and not to
28
; allow others to use your version of this file under the MPL,
29
; indicate your decision by deleting the provisions above and
30
; replace them with the notice and other provisions required by
31
; the GPL. If you do not delete the provisions above, a recipient
32
; may use your version of this file under either the MPL or the
34
; $Id: mpi_x86.asm,v 1.1 2000/09/02 05:33:15 nelsonb%netscape.com Exp $
39
ASSUME CS: FLAT, DS: FLAT, SS: FLAT
42
; ebp - 36: caller's esi
43
; ebp - 32: caller's edi
51
; ebp + 0: caller's ebp
52
; ebp + 4: return address
54
; ebp + 12: a_len argument
55
; ebp + 16: b argument
56
; ebp + 20: c argument
66
_s_mpv_mul_d PROC NEAR
74
mov ecx,[ebp+12] ; ecx = a_len
77
je L_2 ; jmp if a_len == 0
78
mov esi,[ebp+8] ; esi = a
81
lodsd ; eax = [ds:esi]; esi += 4
82
mov edx,[ebp+16] ; edx = b
83
mul edx ; edx:eax = Phi:Plo = a_i * b
85
add eax,ebx ; add carry (ebx) to edx:eax
87
mov ebx,edx ; high half of product becomes next carry
89
stosd ; [es:edi] = ax; edi += 4;
91
jnz L_1 ; jmp if a_len != 0
93
mov [edi],ebx ; *c = carry
102
; ebp - 36: caller's esi
103
; ebp - 32: caller's edi
111
; ebp + 0: caller's ebp
112
; ebp + 4: return address
113
; ebp + 8: a argument
114
; ebp + 12: a_len argument
115
; ebp + 16: b argument
116
; ebp + 20: c argument
124
public _s_mpv_mul_d_add
125
_s_mpv_mul_d_add PROC NEAR
132
mov ebx,0 ; carry = 0
133
mov ecx,[ebp+12] ; ecx = a_len
136
je L_4 ; jmp if a_len == 0
137
mov esi,[ebp+8] ; esi = a
140
lodsd ; eax = [ds:esi]; esi += 4
141
mov edx,[ebp+16] ; edx = b
142
mul edx ; edx:eax = Phi:Plo = a_i * b
144
add eax,ebx ; add carry (ebx) to edx:eax
146
mov ebx,[edi] ; add in current word from *c
149
mov ebx,edx ; high half of product becomes next carry
151
stosd ; [es:edi] = ax; edi += 4;
153
jnz L_3 ; jmp if a_len != 0
155
mov [edi],ebx ; *c = carry
162
_s_mpv_mul_d_add ENDP
164
; ebp - 36: caller's esi
165
; ebp - 32: caller's edi
173
; ebp + 0: caller's ebp
174
; ebp + 4: return address
175
; ebp + 8: a argument
176
; ebp + 12: a_len argument
177
; ebp + 16: b argument
178
; ebp + 20: c argument
186
public _s_mpv_mul_d_add_prop
187
_s_mpv_mul_d_add_prop PROC NEAR
194
mov ebx,0 ; carry = 0
195
mov ecx,[ebp+12] ; ecx = a_len
198
je L_6 ; jmp if a_len == 0
200
mov esi,[ebp+8] ; esi = a
202
lodsd ; eax = [ds:esi]; esi += 4
203
mov edx,[ebp+16] ; edx = b
204
mul edx ; edx:eax = Phi:Plo = a_i * b
206
add eax,ebx ; add carry (ebx) to edx:eax
208
mov ebx,[edi] ; add in current word from *c
211
mov ebx,edx ; high half of product becomes next carry
213
stosd ; [es:edi] = ax; edi += 4;
215
jnz L_5 ; jmp if a_len != 0
217
cmp ebx,0 ; is carry zero?
219
mov eax,[edi] ; add in current word from *c
221
stosd ; [es:edi] = ax; edi += 4;
224
mov eax,[edi] ; add in current word from *c
226
stosd ; [es:edi] = ax; edi += 4;
235
_s_mpv_mul_d_add_prop ENDP
237
; ebp - 20: caller's esi
238
; ebp - 16: caller's edi
241
; ebp - 4: a_len local
242
; ebp + 0: caller's ebp
243
; ebp + 4: return address
244
; ebp + 8: pa argument
245
; ebp + 12: a_len argument
246
; ebp + 16: ps argument
256
public _s_mpv_sqr_add_prop
257
_s_mpv_sqr_add_prop PROC NEAR
264
mov ebx,0 ; carry = 0
265
mov ecx,[ebp+12] ; a_len
266
mov edi,[ebp+16] ; edi = ps
268
je L_11 ; jump if a_len == 0
270
mov esi,[ebp+8] ; esi = pa
272
lodsd ; eax = [ds:si]; si += 4;
275
add eax,ebx ; add "carry"
278
add eax,ebx ; add low word from result
280
stosd ; [es:di] = eax; di += 4;
281
adc edx,ebx ; add high word from result
285
stosd ; [es:di] = eax; di += 4;
287
jnz L_10 ; jmp if a_len != 0
289
cmp ebx,0 ; is carry zero?
291
mov eax,[edi] ; add in current word from *c
293
stosd ; [es:edi] = ax; edi += 4;
296
mov eax,[edi] ; add in current word from *c
298
stosd ; [es:edi] = ax; edi += 4;
307
_s_mpv_sqr_add_prop ENDP
310
; Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized
311
; so its high bit is 1. This code is from NSPR.
313
; mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,
314
; mp_digit *qp, mp_digit *rp)
316
; Dump of assembler code for function s_mpv_div_2dx1d:
318
; esp + 0: Caller's ebx
319
; esp + 4: return address
320
; esp + 8: Nhi argument
321
; esp + 12: Nlo argument
322
; esp + 16: divisor argument
323
; esp + 20: qp argument
324
; esp + 24: rp argument
333
public _s_mpv_div_2dx1d
334
_s_mpv_div_2dx1d PROC NEAR
344
xor eax,eax ; return zero
348
_s_mpv_div_2dx1d ENDP