117 lines
3.0 KiB
NASM
117 lines
3.0 KiB
NASM
|
dnl HP-PA 2.0 64-bit mpn_udiv_qrnnd_r.
|
||
|
|
||
|
dnl Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
|
||
|
|
||
|
dnl This file is part of the GNU MP Library.
|
||
|
|
||
|
dnl The GNU MP Library is free software; you can redistribute it and/or modify
|
||
|
dnl it under the terms of the GNU Lesser General Public License as published
|
||
|
dnl by the Free Software Foundation; either version 2.1 of the License, or (at
|
||
|
dnl your option) any later version.
|
||
|
|
||
|
dnl The GNU MP Library is distributed in the hope that it will be useful, but
|
||
|
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||
|
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||
|
dnl License for more details.
|
||
|
|
||
|
dnl You should have received a copy of the GNU Lesser General Public License
|
||
|
dnl along with the GNU MP Library; see the file COPYING.LIB. If not, write
|
||
|
dnl to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
|
dnl Boston, MA 02110-1301, USA.
|
||
|
|
||
|
include(`../config.m4')
|
||
|
|
||
|
C This runs at about 280 cycles on both PA8000 and PA8500, corresponding to a
|
||
|
C bit more than 4 cycles/bit.
|
||
|
|
||
|
C INPUT PARAMETERS
|
||
|
define(`n1',`%r26')
|
||
|
define(`n0',`%r25')
|
||
|
define(`d',`%r24')
|
||
|
define(`remptr',`%r23')
|
||
|
|
||
|
define(`q',`%r28')
|
||
|
define(`dn',`%r29')
|
||
|
|
||
|
define(`old_divstep',
|
||
|
`add,dc n0,n0,n0
|
||
|
add,dc n1,n1,n1
|
||
|
sub,*<< n1,d,%r22
|
||
|
copy %r22,n1')
|
||
|
|
||
|
define(`divstep',
|
||
|
`add n0,n0,n0
|
||
|
add,dc n1,n1,n1
|
||
|
sub n1,d,%r1
|
||
|
add,dc q,q,q
|
||
|
cmpclr,*<< n1,d,%r0
|
||
|
copy %r1,n1
|
||
|
')
|
||
|
|
||
|
ifdef(`HAVE_ABI_2_0w',
|
||
|
` .level 2.0w
|
||
|
',` .level 2.0
|
||
|
')
|
||
|
PROLOGUE(mpn_udiv_qrnnd_r)
|
||
|
ifdef(`HAVE_ABI_2_0n',
|
||
|
` depd %r25,31,32,%r26
|
||
|
depd %r23,31,32,%r24
|
||
|
copy %r24,%r25
|
||
|
ldd -56(%r30),%r24
|
||
|
ldw -60(%r30),%r23
|
||
|
')
|
||
|
ldi 0,q
|
||
|
cmpib,*>= 0,d,L(large_divisor)
|
||
|
ldi 8,%r31 C setup loop counter
|
||
|
|
||
|
sub %r0,d,dn
|
||
|
LDEF(Loop)
|
||
|
divstep divstep divstep divstep divstep divstep divstep divstep
|
||
|
addib,<> -1,%r31,L(Loop)
|
||
|
nop
|
||
|
|
||
|
ifdef(`HAVE_ABI_2_0n',
|
||
|
` copy %r28,%r29
|
||
|
extrd,u %r28,31,32,%r28
|
||
|
')
|
||
|
bve (%r2)
|
||
|
std n1,0(remptr) C store remainder
|
||
|
|
||
|
LDEF(large_divisor)
|
||
|
extrd,u n0,63,1,%r19 C save lsb of dividend
|
||
|
shrpd n1,n0,1,n0 C n0 = lo(n1n0 >> 1)
|
||
|
shrpd %r0,n1,1,n1 C n1 = hi(n1n0 >> 1)
|
||
|
extrd,u d,63,1,%r20 C save lsb of divisor
|
||
|
shrpd %r0,d,1,d C d = floor(orig_d / 2)
|
||
|
add,l %r20,d,d C d = ceil(orig_d / 2)
|
||
|
|
||
|
sub %r0,d,dn
|
||
|
LDEF(Loop2)
|
||
|
divstep divstep divstep divstep divstep divstep divstep divstep
|
||
|
addib,<> -1,%r31,L(Loop2)
|
||
|
nop
|
||
|
|
||
|
cmpib,*= 0,%r20,L(even_divisor)
|
||
|
shladd n1,1,%r19,n1 C shift in omitted dividend lsb
|
||
|
|
||
|
add d,d,d C restore orig...
|
||
|
sub d,%r20,d C ...d value
|
||
|
sub %r0,d,dn C r21 = -d
|
||
|
|
||
|
add,*nuv n1,q,n1 C fix remainder for omitted divisor lsb
|
||
|
add,l n1,dn,n1 C adjust remainder if rem. fix carried
|
||
|
add,dc %r0,q,q C adjust quotient accordingly
|
||
|
|
||
|
sub,*<< n1,d,%r0 C remainder >= divisor?
|
||
|
add,l n1,dn,n1 C adjust remainder
|
||
|
add,dc %r0,q,q C adjust quotient
|
||
|
|
||
|
LDEF(even_divisor)
|
||
|
ifdef(`HAVE_ABI_2_0n',
|
||
|
` copy %r28,%r29
|
||
|
extrd,u %r28,31,32,%r28
|
||
|
')
|
||
|
bve (%r2)
|
||
|
std n1,0(remptr) C store remainder
|
||
|
EPILOGUE(mpn_udiv_qrnnd_r)
|