[BACK]Return to ddN.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / asm

File: [local] / OpenXM_contrib2 / asir2000 / asm / ddN.c (download)

Revision 1.14, Thu Mar 29 01:32:50 2018 UTC (6 years, 1 month ago) by noro
Branch: MAIN
CVS Tags: HEAD
Changes since 1.13: +534 -534 lines

Changed a tab to two space charaters.

/*
 * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED 
 * All rights reserved.
 * 
 * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
 * non-exclusive and royalty-free license to use, copy, modify and
 * redistribute, solely for non-commercial and non-profit purposes, the
 * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
 * conditions of this Agreement. For the avoidance of doubt, you acquire
 * only a limited right to use the SOFTWARE hereunder, and FLL or any
 * third party developer retains all rights, including but not limited to
 * copyrights, in and to the SOFTWARE.
 * 
 * (1) FLL does not grant you a license in any way for commercial
 * purposes. You may use the SOFTWARE only for non-commercial and
 * non-profit purposes only, such as academic, research and internal
 * business use.
 * (2) The SOFTWARE is protected by the Copyright Law of Japan and
 * international copyright treaties. If you make copies of the SOFTWARE,
 * with or without modification, as permitted hereunder, you shall affix
 * to all such copies of the SOFTWARE the above copyright notice.
 * (3) An explicit reference to this SOFTWARE and its copyright owner
 * shall be made on your publication or presentation in any form of the
 * results obtained by use of the SOFTWARE.
 * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
 * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
 * for such modification or the source code of the modified part of the
 * SOFTWARE.
 * 
 * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
 * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
 * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
 * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
 * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
 * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
 * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
 * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
 * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
 * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
 * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
 * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
 * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
 * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
 * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
 *
 * $OpenXM: OpenXM_contrib2/asir2000/asm/ddN.c,v 1.14 2018/03/29 01:32:50 noro Exp $
*/
#ifndef FBASE
#define FBASE
#endif

#include "ca.h"
#include "base.h"
#include "inline.h"

#if defined(__GNUC__)
unsigned int divn_1(unsigned int *p,int s,unsigned int d,unsigned int *r)  __attribute__ ((noinline));
void muln_1(unsigned int *p,int s,unsigned int d,unsigned int *r)  __attribute__ ((noinline));
#endif

void divn(N n1,N n2,N *nq,N *nr)
{
  int tmp,b;
  int i,j,d1,d2,dd;
  unsigned int *m1,*m2;
  unsigned int uq,ur,msw;
  N q,r,t1,t2;

  if ( !n2 )
    error("divn: divsion by 0");
  else if ( !n1 ) {
    *nq = 0; *nr = 0;
  } else if ( UNIN(n2) ) {
    COPY(n1,*nq); *nr = 0;
  } else if ( (d1 = PL(n1)) < (d2 = PL(n2)) ) {
    COPY(n1,*nr); *nq = 0;
  } else if ( d2 == 1 ) {
    if ( d1 == 1 ) {
      DQR(BD(n1)[0],BD(n2)[0],uq,ur)
      STON(uq,*nq); STON(ur,*nr);
    } else {
      ur = divin(n1,BD(n2)[0],nq); STON(ur,*nr);
    }
    return;
  } else if ( (d1 == d2) && ((tmp = cmpn(n1,n2)) <= 0) )
    if ( !tmp ) {
      *nr = 0; COPY(ONEN,*nq);
    } else {
      COPY(n1,*nr); *nq = 0;
    }
  else {
    msw = BD(n2)[d2-1];
    for ( i = BSH-1; !(msw&(((unsigned int)1)<<i)); i-- ); i++;
    b = BSH-i;
    if ( b ) {
      bshiftn(n1,-b,&t1); bshiftn(n2,-b,&t2);
    } else {
      COPY(n1,t1); COPY(n2,t2);
    }
    m1 = (unsigned int *)ALLOCA((PL(t1)+1)*sizeof(unsigned int));  
    bcopy(BD(t1),m1,PL(t1)*sizeof(unsigned int)); m1[PL(t1)] = 0;
    m2 = BD(t2); dd = d1-d2;
    *nq = q = NALLOC(dd+1); INITRC(q);
    divnmain(d1,d2,m1,m2,BD(q)); FREEN(t1); FREEN(t2);
    PL(q) = (BD(q)[dd]?dd+1:dd);
    if ( !PL(q) ) {
      FREEN(q);
    }
    for ( j = d2-1; (j >= 0) && (m1[j] == 0); j--);
    if ( j == -1 ) 
      *nr = 0;
    else {
      r = NALLOC(j+1); INITRC(r); PL(r) = j+1;
      bcopy(m1,BD(r),(j+1)*sizeof(unsigned int));
      if ( b ) {
        bshiftn(r,b,nr); FREEN(r);
      } else
        *nr = r;
    }
  }
}

void divsn(N n1,N n2,N *nq)
{
  int d1,d2,dd,i,b;
  unsigned int *m1,*m2;
  unsigned int uq,msw;
  N q,t1,t2;

  if ( !n1 )
    *nq = 0;
  else if ( UNIN(n2) ) {
    COPY(n1,*nq);
  } else if ( (d1 = PL(n1)) < (d2 = PL(n2)) ) 
    error("divsn: cannot happen");
  else if ( d2 == 1 ) {
    if ( d1 == 1 ) {
      uq = BD(n1)[0] / BD(n2)[0]; STON(uq,*nq);
    } else 
      divin(n1,BD(n2)[0],nq);
  } else {
    msw = BD(n2)[d2-1];
    for ( i = BSH-1; !(msw&(((unsigned int)1)<<i)); i-- ); i++;
    b = BSH-i;
    if ( b ) {
      bshiftn(n1,-b,&t1); bshiftn(n2,-b,&t2);
    } else {
      COPY(n1,t1); COPY(n2,t2);
    }
    m1 = (unsigned int *)ALLOCA((PL(t1)+1)*sizeof(unsigned int));  
    bcopy(BD(t1),m1,PL(t1)*sizeof(unsigned int)); m1[PL(t1)] = 0;
    m2 = BD(t2); dd = d1-d2;
    *nq = q = NALLOC(dd+1); INITRC(q);
    divnmain(d1,d2,m1,m2,BD(q));
    FREEN(t1); FREEN(t2);
    PL(q) = (BD(q)[dd]?dd+1:dd);
    if ( !PL(q) )
      FREEN(q);
  }
}

void remn(N n1,N n2,N *nr)
{
  int d1,d2,tmp;
  unsigned int uq,ur;
  N q;

  if ( !n2 )
    error("remn: divsion by 0");
  else if ( !n1 || UNIN(n2) )
    *nr = 0;
  else if ( (d1 = PL(n1)) < (d2 = PL(n2)) ) {
    COPY(n1,*nr);
  } else if ( d2 == 1 ) {
    if ( d1 == 1 ) {
      DQR(BD(n1)[0],BD(n2)[0],uq,ur)
      STON(ur,*nr);
    } else {
      ur = rem(n1,BD(n2)[0]); UTON(ur,*nr);
    }
    return;
  } else if ( (d1 == d2) && ((tmp = cmpn(n1,n2)) <= 0) )
    if ( !tmp ) {
      *nr = 0; 
    } else {
      COPY(n1,*nr);
    }
  else
    divn(n1,n2,&q,nr);
}

/* d = 2^(32*words)-lower */

void remn_special(N a,N d,int bits,unsigned int lower,N *b)
{
  int words;
  N r;
  int rl,i;
  unsigned int c,tmp;
  unsigned int *rb,*src,*dst;

  if ( cmpn(a,d) < 0 ) {
    *b = a;
    return;
  }
  words = bits>>5;
  r = NALLOC(PL(a)); dupn(a,r);
  rl = PL(r); rb = BD(r);
  while ( rl > words ) {
    src = rb+words;
    dst = rb;
    i = rl-words;
    for ( c = 0; i > 0; i--, src++, dst++ ) {
      DMA2(*src,lower,c,*dst,c,*dst)
      *src = 0;
    }
    for ( ; c; dst++ ) {
      tmp = *dst + c;
      c = tmp < c ? 1 : 0;
      *dst = tmp;
    }
    rl = dst-rb;
  }
  for ( i = words-1; i >= 0 && !rb[i]; i-- );
  PL(r) = i + 1;
  if ( cmpn(r,d) >= 0 ) {
    tmp = rb[0]-BD(d)[0];
    UTON(tmp,*b);
  } else
    *b = r;
}
void mulin(N n,unsigned int d,unsigned int *p)
{
  unsigned int carry;
  unsigned int *m,*me;

  bzero((char *)p,(int)((PL(n)+1)*sizeof(int)));
  for ( carry = 0, m = BD(n), me = m+PL(n); m < me; p++, m++ ) {
    DMA2(*m,d,*p,carry,carry,*p)
  }
  *p = carry;
}

unsigned int divin(N n,unsigned int dvr,N *q)
{
  int d;
  unsigned int up;
  unsigned int *m,*mq,*md;
  N nq;

  d = PL(n); m = BD(n);
  if ( ( d == 1 ) && ( dvr > *m ) ) {
    *q = 0;
    return *m;
  }
  *q = nq = NALLOC(d); INITRC(nq);
  for ( md = m+d-1, mq = BD(nq)+d-1, up = 0; md >= m; md--, mq-- ) {
    DSAB(dvr,up,*md,*mq,up)
  }
  PL(nq) = (BD(nq)[d-1]?d:d-1);
  if ( !PL(nq) )
    FREEN(nq);
  return ( up );
}

void bprintn(N n)
{
  int l,i;
  unsigned int *b;

  if ( !n )
    printf("0");
  else {
    l = PL(n); b = BD(n);
    for ( i = l-1; i >= 0; i-- )
      printf("%010u|",b[i]);
  }
}

void bxprintn(N n)
{
  int l,i;
  unsigned int *b;

  if ( !n )
    printf("0");
  else {
    l = PL(n); b = BD(n);
    for ( i = l-1; i >= 0; i-- )
      printf("%08x|",b[i]);
  }
}

#if (defined(_M_IX86) || defined(i386)) && !defined(__MINGW32__)
void muln(N n1,N n2,N *nr)
{
  unsigned int tmp,carry,mul;
  unsigned int *p1,*m1,*m2;
  int i,d1,d2,d;
  N r;

  if ( !n1 || !n2 )
    *nr = 0;
  else if ( UNIN(n1) ) 
    COPY(n2,*nr);
  else if ( UNIN(n2) )
    COPY(n1,*nr);
  else if ( (PL(n1) == 1) && (PL(n2) == 1) ) {
    DM(*BD(n1),*BD(n2),carry,tmp)
    if ( carry ) {
      *nr = r = NALLOC(2); INITRC(r);
      PL(r) = 2; p1 = BD(r); *p1++ = tmp; *p1 = carry;
    } else
      STON(tmp,*nr);
  } else {
    d1 = PL(n1); d2 = PL(n2);
    d = d1+d2;
    *nr = r = NALLOC(d); INITRC(r);
    bzero((char *)BD(r),(int)((d1+d2)*sizeof(int)));
    for ( i = 0, m1 = BD(n1), m2 = BD(n2); i < d2; i++, m2++ )
      if ( mul = *m2 )
        muln_1(m1,d1,mul,BD(r)+i);
    PL(r) = (BD(r)[d-1]?d:d-1);
  }
}

void _muln(N n1,N n2,N nr)
{
  unsigned int mul;
  unsigned int *m1,*m2;
  int i,d1,d2,d;

  if ( !n1 || !PL(n1) || !n2 || !PL(n2) )
    PL(nr) = 0;
  else if ( UNIN(n1) ) 
    dupn(n2,nr);
  else if ( UNIN(n2) )
    dupn(n1,nr);
  else {
    d1 = PL(n1); d2 = PL(n2);
    d = d1+d2;
    bzero((char *)BD(nr),(int)((d1+d2)*sizeof(int)));
    for ( i = 0, m1 = BD(n1), m2 = BD(n2); i < d2; i++, m2++ )
      if ( mul = *m2 )
        muln_1(m1,d1,mul,BD(nr)+i);
    PL(nr) = (BD(nr)[d-1]?d:d-1);
  }
}

void muln_1(unsigned int *p,int s,unsigned int d,unsigned int *r)
{
  /* esi : p, edi : r, carry : ebx, s : ecx */
#if defined(_M_IX86)
  __asm {
  push esi
  push edi
  mov esi,p
  mov edi,r
  mov ecx,s
  xor ebx,ebx
  Lstart_muln:
  mov eax,DWORD PTR [esi]
  mul d
  add eax,DWORD PTR [edi]
  adc edx,0
  add eax,ebx
  adc edx,0
  mov DWORD PTR[edi],eax
  mov ebx,edx
  lea  esi,DWORD PTR [esi+4]
  lea  edi,DWORD PTR [edi+4]
  dec ecx
  jnz Lstart_muln
  mov DWORD PTR [edi],ebx
  pop edi
  pop esi
  }
#else
  asm volatile("\
  pushl  %%ebx;\
  movl  %0,%%esi;\
  movl  %1,%%edi;\
  movl  $0,%%ebx;\
  Lstart_muln:;\
  movl  (%%esi),%%eax;\
  mull  %2;\
  addl  (%%edi),%%eax;\
  adcl  $0,%%edx;\
  addl  %%ebx,%%eax;\
  adcl  $0,%%edx;\
  movl  %%eax,(%%edi);\
  movl  %%edx,%%ebx;\
  leal  4(%%esi),%%esi;\
  leal  4(%%edi),%%edi;\
  decl  %3;\
  jnz    Lstart_muln;\
  movl  %%ebx,(%%edi);\
  popl  %%ebx"\
  :\
  :"m"(p),"m"(r),"m"(d),"m"(s)\
  :"eax","edx","esi","edi");
#endif
}

void divnmain(int d1,int d2,unsigned int *m1,unsigned int *m2,unsigned int *q)
{
  int i,j;
  UL r,ltmp;
  unsigned int l,ur;
  unsigned int *n1,*n2;
  unsigned int u,qhat;
  unsigned int v1,v2;

  v1 = m2[d2-1]; v2 = m2[d2-2];
#if 0
  if ( v1 == (1<<31) && !v2 ) {
    divnmain_special(d1,d2,m1,m2,q);
    return;
  }
#endif
  for ( j = d1-d2, m1 += j, q += j; j >= 0; j--, q--, m1-- ) {
    n1 = m1+d2; n2 = m1+d2-1;
       if ( *n1 == v1 ) {
            qhat = ULBASE - 1;
      r = (UL)*n1 + (UL)*n2;
       } else {
      DSAB(v1,*n1,*n2,qhat,ur)
      r = (UL)ur;
    }
    DM(v2,qhat,u,l)
       while ( 1 ) {
           if ((r > (UL)u) || ((r == (UL)u) && (*(n1-2) >= l))) 
        break;
      if ( l >= v2 )
        l -= v2;
      else {
        l = (unsigned int)((UL)l+(ULBASE-(UL)v2)); u--;
      }
          r += v1; qhat--;
       }
    if ( qhat ) {
      u = divn_1(m2,d2,qhat,m1);
      if ( *(m1+d2) < u ) {
        for ( i = d2, qhat--, ur = 0, n1 = m1, n2 = m2; 
          i > 0; i--, n1++, n2++ ) {
          ltmp = (UL)*n1 + (UL)*n2 + (UL)ur;
          *n1 = (unsigned int)(ltmp & BMASK);
          ur = (unsigned int)(ltmp >> BSH);
        }
      }
      *n1 = 0; 
    }
    *q = qhat;
  }
}

void divnmain_special(int d1,int d2,unsigned int *m1,unsigned int *m2,unsigned int *q)
{
  int i,j;
  UL ltmp;
  unsigned int ur;
  unsigned int *n1,*n2;
  unsigned int u,qhat;
  unsigned int v1,v2;

  v1 = m2[d2-1]; v2 = 0;
  for ( j = d1-d2, m1 += j, q += j; j >= 0; j--, q--, m1-- ) {
    n1 = m1+d2; n2 = m1+d2-1;
    qhat = ((*n1)<<1)|((*n2)>>31);
    if ( qhat ) {
      u = divn_1(m2,d2,qhat,m1);
      if ( *(m1+d2) < u ) {
        for ( i = d2, qhat--, ur = 0, n1 = m1, n2 = m2; 
          i > 0; i--, n1++, n2++ ) {
          ltmp = (UL)*n1 + (UL)*n2 + (UL)ur;
          *n1 = (unsigned int)(ltmp & BMASK);
          ur = (unsigned int)(ltmp >> BSH);
        }
      }
      *n1 = 0; 
    }
    *q = qhat;
  }
}

unsigned int divn_1(unsigned int *p,int s,unsigned int d,unsigned int *r)
{
/*
  unsigned int borrow,l;

  for ( borrow = 0; s--; p++, r++ ) {
    DMA(*p,d,borrow,borrow,l)
    if ( *r >= l )
      *r -= l;
    else {
      *r = (unsigned int)((UL)*r+(ULBASE-(UL)l)); borrow++;
    }
  }
  return borrow;
*/
  /* esi : p, edi : r, borrow : ebx, s : ecx */
#if defined(_M_IX86)
  __asm {
  push esi
  push edi
  mov esi,p
  mov edi,r
  mov ecx,s
  xor ebx,ebx
  Lstart_divn:
  mov eax,DWORD PTR [esi]
  mul d
  add eax,ebx
  adc edx,0
  sub DWORD PTR [edi],eax
  adc edx,0
  mov ebx,edx
  lea  esi,DWORD PTR [esi+4]
  lea  edi,DWORD PTR [edi+4]
  dec ecx
  jnz Lstart_divn
  mov eax,ebx
  pop edi
  pop esi
  }
  /* return value is in eax. */
#else
  unsigned int borrow;

  asm volatile("\
  pushl  %%ebx;\
  movl  %1,%%esi;\
  movl  %2,%%edi;\
  movl  $0,%%ebx;\
  Lstart_divn:;\
  movl  (%%esi),%%eax;\
  mull  %3;\
  addl  %%ebx,%%eax;\
  adcl  $0,%%edx;\
  subl  %%eax,(%%edi);\
  adcl  $0,%%edx;\
  movl  %%edx,%%ebx;\
  leal  4(%%esi),%%esi;\
  leal  4(%%edi),%%edi;\
  decl  %4;\
  jnz    Lstart_divn;\
  movl  %%ebx,%0;\
  popl  %%ebx"\
  :"=m"(borrow)\
  :"m"(p),"m"(r),"m"(d),"m"(s)\
  :"eax","edx","esi","edi");

  return borrow;
#endif
}

#else

void muln(N n1,N n2,N *nr)
{
  unsigned int tmp,carry,mul;
  unsigned int *p1,*pp,*m1,*m2;
  int i,j,d1,d2;
  N r;

  if ( !n1 || !n2 )
    *nr = 0;
  else if ( UNIN(n1) ) 
    COPY(n2,*nr);
  else if ( UNIN(n2) )
    COPY(n1,*nr);
  else if ( (PL(n1) == 1) && (PL(n2) == 1) ) {
    DM(*BD(n1),*BD(n2),carry,tmp)
    if ( carry ) {
      *nr = r = NALLOC(2); INITRC(r);
      PL(r) = 2; p1 = BD(r); *p1++ = tmp; *p1 = carry;
    } else
      STON(tmp,*nr);
  } else {
    d1 = PL(n1); d2 = PL(n2);
    *nr = r = NALLOC(d1+d2); INITRC(r);
    bzero((char *)BD(r),(int)((d1+d2)*sizeof(int)));
    for ( i = 0, m1 = BD(n1), m2 = BD(n2); i < d2; i++, m2++ )
      if ( mul = *m2 ) {
        for ( j = d1, carry = 0, p1 = m1, pp = BD(r)+i;
          j--; pp++ ) {
          DMA2(*p1++,mul,*pp,carry,carry,*pp)
        }
        *pp = carry;
      }
    PL(r) = (carry?d1+d2:d1+d2-1);
  }
}

void _muln(N n1,N n2,N nr)
{
  unsigned int carry=0,mul;
  unsigned int *p1,*pp,*m1,*m2;
  int i,j,d1,d2;

  if ( !n1 || !PL(n1) || !n2 || !PL(n2) )
    PL(nr) = 0;
  else if ( UNIN(n1) ) 
    dupn(n2,nr);
  else if ( UNIN(n2) )
    dupn(n1,nr);
  else {
    d1 = PL(n1); d2 = PL(n2);
    bzero((char *)BD(nr),(int)((d1+d2)*sizeof(int)));
    for ( i = 0, m1 = BD(n1), m2 = BD(n2); i < d2; i++, m2++ )
      if ( mul = *m2 ) {
        for ( j = d1, carry = 0, p1 = m1, pp = BD(nr)+i;
          j--; pp++ ) {
          DMA2(*p1++,mul,*pp,carry,carry,*pp)
        }
        *pp = carry;
      }
    PL(nr) = (carry?d1+d2:d1+d2-1);
  }
}

/* r[0...s] = p[0...s-1]*d */

void muln_1(unsigned int *p,int s,unsigned int d,unsigned int *r)
{
  unsigned int carry;

  for ( carry = 0; s--; p++, r++ ) {
    DMA2(*p,d,carry,*r,carry,*r)
  }
  *r = carry;
}

void divnmain(int d1,int d2,unsigned int *m1,unsigned int *m2,unsigned int *q)
{
  int i,j;
  UL r,ltmp;
  unsigned int l,ur;
  unsigned int *n1,*n2;
  unsigned int u,qhat;
  unsigned int v1,v2;

  v1 = m2[d2-1]; v2 = m2[d2-2];
  for ( j = d1-d2, m1 += j, q += j; j >= 0; j--, q--, m1-- ) {
    n1 = m1+d2; n2 = m1+d2-1;
       if ( *n1 == v1 ) {
            qhat = ULBASE - 1;
      r = (UL)*n1 + (UL)*n2;
       } else {
      DSAB(v1,*n1,*n2,qhat,ur)
      r = (UL)ur;
    }
    DM(v2,qhat,u,l)
       while ( 1 ) {
           if ((r > (UL)u) || ((r == (UL)u) && (*(n1-2) >= l))) 
        break;
      if ( l >= v2 )
        l -= v2;
      else {
        l = (unsigned int)((UL)l+(ULBASE-(UL)v2)); u--;
      }
          r += v1; qhat--;
       }
    if ( qhat ) {
      u = divn_1(m2,d2,qhat,m1);
      if ( *(m1+d2) < u ) {
        for ( i = d2, qhat--, ur = 0, n1 = m1, n2 = m2; 
          i > 0; i--, n1++, n2++ ) {
          ltmp = (UL)*n1 + (UL)*n2 + (UL)ur;
          *n1 = (unsigned int)(ltmp & BMASK);
          ur = (unsigned int)(ltmp >> BSH);
        }
      }
      *n1 = 0; 
    }
    *q = qhat;
  }
}

unsigned int divn_1(unsigned int *p,int s,unsigned int d,unsigned int *r)
{
  unsigned int borrow,l;

  for ( borrow = 0; s--; p++, r++ ) {
    DMA(*p,d,borrow,borrow,l)
    if ( *r >= l )
      *r -= l;
    else {
      *r = (unsigned int)((UL)*r+(ULBASE-(UL)l)); borrow++;
    }
  }
  return borrow;
}
#endif