KGC_TEST/KGCAPP/3rdparty/miracl/source/mrmuldv.ppc

169 lines
3.3 KiB
Plaintext

/* GCC inline assembly version for Linux */
#include "miracl.h"
mr_small muldiv(a,b,c,m,rp)
mr_small a,b,c,m;
mr_small *rp;
{
int i;
mr_small d,q=0,r=0;
d=m-a;
for (i=MIRACL/4;i>0;i--)
{ /* do it bit by bit */
r<<=1;
if ((mr_utype)c<0) r++;
c<<=1;
q<<=1;
if ((mr_utype)b<0)
{
if (r>=m) { r-=d; q++; }
else r+=a;
}
if (r>=m) { r-=m; q++; }
b<<=1;
r<<=1;
if ((mr_utype)c<0) r++;
c<<=1;
q<<=1;
if ((mr_utype)b<0)
{
if (r>=m) { r-=d; q++; }
else r+=a;
}
if (r>=m) { r-=m; q++; }
b<<=1;
r<<=1;
if ((mr_utype)c<0) r++;
c<<=1;
q<<=1;
if ((mr_utype)b<0)
{
if (r>=m) { r-=d; q++; }
else r+=a;
}
if (r>=m) { r-=m; q++; }
b<<=1;
r<<=1;
if ((mr_utype)c<0) r++;
c<<=1;
q<<=1;
if ((mr_utype)b<0)
{
if (r>=m) { r-=d; q++; }
else r+=a;
}
if (r>=m) { r-=m; q++; }
b<<=1;
}
*rp=r;
return q;
}
mr_small muldvm(a,c,m,rp)
mr_small a,c,m;
mr_small *rp;
{ /* modified Blakely-Sloan */
register int i,carry;
register mr_small q=0,r=0;
r=a;
for (i=MIRACL/4;i>0;i--)
{ /* do it bit by bit */
carry=0;
if ((mr_utype)r<0) carry=1;
r<<=1;
if ((mr_utype)c<0) r++;
c<<=1;
q<<=1;
if (carry || r>=m) { r-=m; q++; }
carry=0;
if ((mr_utype)r<0) carry=1;
r<<=1;
if ((mr_utype)c<0) r++;
c<<=1;
q<<=1;
if (carry || r>=m) { r-=m; q++; }
carry=0;
if ((mr_utype)r<0) carry=1;
r<<=1;
if ((mr_utype)c<0) r++;
c<<=1;
q<<=1;
if (carry || r>=m) { r-=m; q++; }
carry=0;
if ((mr_utype)r<0) carry=1;
r<<=1;
if ((mr_utype)c<0) r++;
c<<=1;
q<<=1;
if (carry || r>=m) { r-=m; q++; }
}
*rp=r;
return q;
}
void muldvd2(mr_small a,mr_small b,mr_small *c,mr_small *rp)
{
__asm__ __volatile__ (
"mulld %%r16,%0,%1\n"
"mulhdu %%r17,%0,%1\n"
"ld %%r18,0(%2)\n"
"addc %%r16,%%r18,%%r16\n"
"addze %%r17,%%r17\n"
"ld %%r19,0(%3)\n"
"addc %%r16,%%r19,%%r16\n"
"addze %%r17,%%r17\n"
"std %%r16,0(%3)\n"
"std %%r17,0(%2)\n"
:
: "r"(a),"r"(b),"r"(c),"r"(rp)
: "r16","r17","r18","r19","memory"
);
}
mr_small muldvd(mr_small a,mr_small b,mr_small c,mr_small *rp)
{
mr_small q;
__asm__ __volatile__ (
"mulld %%r16,%1,%2\n"
"mulhdu %%r17,%1,%2\n"
"addc %%r16,%3,%%r16\n"
"addze %%r17,%%r17\n"
"std %%r16,0(%4)\n"
"or %0,%%r17,%%r17\n"
: "=r"(q)
: "r"(a),"r"(b),"r"(c),"r"(rp)
: "r16","r17","memory"
);
return q;
}
/*
mr_small test(mr_small a,mr_small b,mr_small c,mr_small *rp)
{
mr_small q;
q=a*b+c+*rp;
*rp=q;
return q;
}
int main()
{
mr_small a,b,c,q,r;
printf("sizeof(mr_small)= %d\n",sizeof(mr_small));
a=(mr_small)-1;
b=(mr_small)-1;
c=0;
q=0;
r=0;
q=muldvd(a,b,c,&r);
muldvd2(a,b,&c,&r);
printf("c= %lx r= %lx\n",c,r);
}
*/