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