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 3 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. If not, see http://www.gnu.org/licenses/. 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)