michael@0: / michael@0: / This Source Code Form is subject to the terms of the Mozilla Public michael@0: / License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: / file, You can obtain one at http://mozilla.org/MPL/2.0/. michael@0: michael@0: .text michael@0: michael@0: / ebp - 36: caller's esi michael@0: / ebp - 32: caller's edi michael@0: / ebp - 28: michael@0: / ebp - 24: michael@0: / ebp - 20: michael@0: / ebp - 16: michael@0: / ebp - 12: michael@0: / ebp - 8: michael@0: / ebp - 4: michael@0: / ebp + 0: caller's ebp michael@0: / ebp + 4: return address michael@0: / ebp + 8: a argument michael@0: / ebp + 12: a_len argument michael@0: / ebp + 16: b argument michael@0: / ebp + 20: c argument michael@0: / registers: michael@0: / eax: michael@0: / ebx: carry michael@0: / ecx: a_len michael@0: / edx: michael@0: / esi: a ptr michael@0: / edi: c ptr michael@0: .globl s_mpv_mul_d michael@0: .type s_mpv_mul_d,@function michael@0: s_mpv_mul_d: michael@0: push %ebp michael@0: mov %esp,%ebp michael@0: sub $28,%esp michael@0: push %edi michael@0: push %esi michael@0: push %ebx michael@0: movl $0,%ebx / carry = 0 michael@0: mov 12(%ebp),%ecx / ecx = a_len michael@0: mov 20(%ebp),%edi michael@0: cmp $0,%ecx michael@0: je L2 / jmp if a_len == 0 michael@0: mov 8(%ebp),%esi / esi = a michael@0: cld michael@0: L1: michael@0: lodsl / eax = [ds:esi]; esi += 4 michael@0: mov 16(%ebp),%edx / edx = b michael@0: mull %edx / edx:eax = Phi:Plo = a_i * b michael@0: michael@0: add %ebx,%eax / add carry (%ebx) to edx:eax michael@0: adc $0,%edx michael@0: mov %edx,%ebx / high half of product becomes next carry michael@0: michael@0: stosl / [es:edi] = ax; edi += 4; michael@0: dec %ecx / --a_len michael@0: jnz L1 / jmp if a_len != 0 michael@0: L2: michael@0: mov %ebx,0(%edi) / *c = carry michael@0: pop %ebx michael@0: pop %esi michael@0: pop %edi michael@0: leave michael@0: ret michael@0: nop michael@0: michael@0: / ebp - 36: caller's esi michael@0: / ebp - 32: caller's edi michael@0: / ebp - 28: michael@0: / ebp - 24: michael@0: / ebp - 20: michael@0: / ebp - 16: michael@0: / ebp - 12: michael@0: / ebp - 8: michael@0: / ebp - 4: michael@0: / ebp + 0: caller's ebp michael@0: / ebp + 4: return address michael@0: / ebp + 8: a argument michael@0: / ebp + 12: a_len argument michael@0: / ebp + 16: b argument michael@0: / ebp + 20: c argument michael@0: / registers: michael@0: / eax: michael@0: / ebx: carry michael@0: / ecx: a_len michael@0: / edx: michael@0: / esi: a ptr michael@0: / edi: c ptr michael@0: .globl s_mpv_mul_d_add michael@0: .type s_mpv_mul_d_add,@function michael@0: s_mpv_mul_d_add: michael@0: push %ebp michael@0: mov %esp,%ebp michael@0: sub $28,%esp michael@0: push %edi michael@0: push %esi michael@0: push %ebx michael@0: movl $0,%ebx / carry = 0 michael@0: mov 12(%ebp),%ecx / ecx = a_len michael@0: mov 20(%ebp),%edi michael@0: cmp $0,%ecx michael@0: je L4 / jmp if a_len == 0 michael@0: mov 8(%ebp),%esi / esi = a michael@0: cld michael@0: L3: michael@0: lodsl / eax = [ds:esi]; esi += 4 michael@0: mov 16(%ebp),%edx / edx = b michael@0: mull %edx / edx:eax = Phi:Plo = a_i * b michael@0: michael@0: add %ebx,%eax / add carry (%ebx) to edx:eax michael@0: adc $0,%edx michael@0: mov 0(%edi),%ebx / add in current word from *c michael@0: add %ebx,%eax michael@0: adc $0,%edx michael@0: mov %edx,%ebx / high half of product becomes next carry michael@0: michael@0: stosl / [es:edi] = ax; edi += 4; michael@0: dec %ecx / --a_len michael@0: jnz L3 / jmp if a_len != 0 michael@0: L4: michael@0: mov %ebx,0(%edi) / *c = carry michael@0: pop %ebx michael@0: pop %esi michael@0: pop %edi michael@0: leave michael@0: ret michael@0: nop michael@0: michael@0: / ebp - 36: caller's esi michael@0: / ebp - 32: caller's edi michael@0: / ebp - 28: michael@0: / ebp - 24: michael@0: / ebp - 20: michael@0: / ebp - 16: michael@0: / ebp - 12: michael@0: / ebp - 8: michael@0: / ebp - 4: michael@0: / ebp + 0: caller's ebp michael@0: / ebp + 4: return address michael@0: / ebp + 8: a argument michael@0: / ebp + 12: a_len argument michael@0: / ebp + 16: b argument michael@0: / ebp + 20: c argument michael@0: / registers: michael@0: / eax: michael@0: / ebx: carry michael@0: / ecx: a_len michael@0: / edx: michael@0: / esi: a ptr michael@0: / edi: c ptr michael@0: .globl s_mpv_mul_d_add_prop michael@0: .type s_mpv_mul_d_add_prop,@function michael@0: s_mpv_mul_d_add_prop: michael@0: push %ebp michael@0: mov %esp,%ebp michael@0: sub $28,%esp michael@0: push %edi michael@0: push %esi michael@0: push %ebx michael@0: movl $0,%ebx / carry = 0 michael@0: mov 12(%ebp),%ecx / ecx = a_len michael@0: mov 20(%ebp),%edi michael@0: cmp $0,%ecx michael@0: je L6 / jmp if a_len == 0 michael@0: cld michael@0: mov 8(%ebp),%esi / esi = a michael@0: L5: michael@0: lodsl / eax = [ds:esi]; esi += 4 michael@0: mov 16(%ebp),%edx / edx = b michael@0: mull %edx / edx:eax = Phi:Plo = a_i * b michael@0: michael@0: add %ebx,%eax / add carry (%ebx) to edx:eax michael@0: adc $0,%edx michael@0: mov 0(%edi),%ebx / add in current word from *c michael@0: add %ebx,%eax michael@0: adc $0,%edx michael@0: mov %edx,%ebx / high half of product becomes next carry michael@0: michael@0: stosl / [es:edi] = ax; edi += 4; michael@0: dec %ecx / --a_len michael@0: jnz L5 / jmp if a_len != 0 michael@0: L6: michael@0: cmp $0,%ebx / is carry zero? michael@0: jz L8 michael@0: mov 0(%edi),%eax / add in current word from *c michael@0: add %ebx,%eax michael@0: stosl / [es:edi] = ax; edi += 4; michael@0: jnc L8 michael@0: L7: michael@0: mov 0(%edi),%eax / add in current word from *c michael@0: adc $0,%eax michael@0: stosl / [es:edi] = ax; edi += 4; michael@0: jc L7 michael@0: L8: michael@0: pop %ebx michael@0: pop %esi michael@0: pop %edi michael@0: leave michael@0: ret michael@0: nop michael@0: michael@0: / ebp - 20: caller's esi michael@0: / ebp - 16: caller's edi michael@0: / ebp - 12: michael@0: / ebp - 8: carry michael@0: / ebp - 4: a_len local michael@0: / ebp + 0: caller's ebp michael@0: / ebp + 4: return address michael@0: / ebp + 8: pa argument michael@0: / ebp + 12: a_len argument michael@0: / ebp + 16: ps argument michael@0: / ebp + 20: michael@0: / registers: michael@0: / eax: michael@0: / ebx: carry michael@0: / ecx: a_len michael@0: / edx: michael@0: / esi: a ptr michael@0: / edi: c ptr michael@0: michael@0: .globl s_mpv_sqr_add_prop michael@0: .type s_mpv_sqr_add_prop,@function michael@0: s_mpv_sqr_add_prop: michael@0: push %ebp michael@0: mov %esp,%ebp michael@0: sub $12,%esp michael@0: push %edi michael@0: push %esi michael@0: push %ebx michael@0: movl $0,%ebx / carry = 0 michael@0: mov 12(%ebp),%ecx / a_len michael@0: mov 16(%ebp),%edi / edi = ps michael@0: cmp $0,%ecx michael@0: je L11 / jump if a_len == 0 michael@0: cld michael@0: mov 8(%ebp),%esi / esi = pa michael@0: L10: michael@0: lodsl / %eax = [ds:si]; si += 4; michael@0: mull %eax michael@0: michael@0: add %ebx,%eax / add "carry" michael@0: adc $0,%edx michael@0: mov 0(%edi),%ebx michael@0: add %ebx,%eax / add low word from result michael@0: mov 4(%edi),%ebx michael@0: stosl / [es:di] = %eax; di += 4; michael@0: adc %ebx,%edx / add high word from result michael@0: movl $0,%ebx michael@0: mov %edx,%eax michael@0: adc $0,%ebx michael@0: stosl / [es:di] = %eax; di += 4; michael@0: dec %ecx / --a_len michael@0: jnz L10 / jmp if a_len != 0 michael@0: L11: michael@0: cmp $0,%ebx / is carry zero? michael@0: jz L14 michael@0: mov 0(%edi),%eax / add in current word from *c michael@0: add %ebx,%eax michael@0: stosl / [es:edi] = ax; edi += 4; michael@0: jnc L14 michael@0: L12: michael@0: mov 0(%edi),%eax / add in current word from *c michael@0: adc $0,%eax michael@0: stosl / [es:edi] = ax; edi += 4; michael@0: jc L12 michael@0: L14: michael@0: pop %ebx michael@0: pop %esi michael@0: pop %edi michael@0: leave michael@0: ret michael@0: nop michael@0: michael@0: / michael@0: / Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized michael@0: / so its high bit is 1. This code is from NSPR. michael@0: / michael@0: / mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor, michael@0: / mp_digit *qp, mp_digit *rp) michael@0: michael@0: / esp + 0: Caller's ebx michael@0: / esp + 4: return address michael@0: / esp + 8: Nhi argument michael@0: / esp + 12: Nlo argument michael@0: / esp + 16: divisor argument michael@0: / esp + 20: qp argument michael@0: / esp + 24: rp argument michael@0: / registers: michael@0: / eax: michael@0: / ebx: carry michael@0: / ecx: a_len michael@0: / edx: michael@0: / esi: a ptr michael@0: / edi: c ptr michael@0: / michael@0: michael@0: .globl s_mpv_div_2dx1d michael@0: .type s_mpv_div_2dx1d,@function michael@0: s_mpv_div_2dx1d: michael@0: push %ebx michael@0: mov 8(%esp),%edx michael@0: mov 12(%esp),%eax michael@0: mov 16(%esp),%ebx michael@0: div %ebx michael@0: mov 20(%esp),%ebx michael@0: mov %eax,0(%ebx) michael@0: mov 24(%esp),%ebx michael@0: mov %edx,0(%ebx) michael@0: xor %eax,%eax / return zero michael@0: pop %ebx michael@0: ret michael@0: nop michael@0: