Hi
The functions mpn_addadd mpn_addsub and mpn_subadd are currently not availible
on all machines , this is because of possible aliasing between the various
params , which would require temp space allocations
eg
calling mpn_addadd(t,x,y,z) which would be done as mpn_add(t,x,y) and then
mpn_add(t,t,z)
and if z=t then we overwrite z before we can use it
this would normally require a temp space allocation in the function addadd
which would then mean it's not a speedup
However if we split the aliasing cases up we can avoid this , see attached
files , not very well tested yet so I may of missed a few cases
When I've tested them , I'll change all the branches to pointer swapping and
boolean logic
So we can have addadd on every machine , which would simplify quite a bit code
Jason
--
You received this message because you are subscribed to the Google Groups
"mpir-devel" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/mpir-devel?hl=en.
#include "mpir.h"
#include "gmp-impl.h"
mp_limb_t mpn_addadd_n(mp_ptr t,mp_srcptr x,mp_srcptr y,mp_srcptr z,mp_size_t n)
{mp_limb_t ret;
if(t==x && t==y && t==z)
{
#ifdef HAVE_NATIVE_mpn_addlsh1_n
return mpn_addlsh1_n(t,x,y,n);
#else
return mpn_mul_1(t,x,n,3);
#endif
}
if(t==x && t==y)
{ret=mpn_add_n(t,x,y,n);
ret+=mpn_add_n(t,t,z,n);
return ret;
}
if(t==x && t==z)
{ret=mpn_add_n(t,x,z,n);
ret+=mpn_add_n(t,t,y,n);
return ret;
}
if(t==y && t==z)
{ret=mpn_add_n(t,y,z,n);
ret+=mpn_add_n(t,t,x,n);
return ret;
}
if(t==x)
{ret=mpn_add_n(t,x,y,n);
ret+=mpn_add_n(t,t,z,n);
return ret;
}
if(t==y)
{ret=mpn_add_n(t,y,x,n);
ret+=mpn_add_n(t,t,z,n);
return ret;
}
if(t==z)
{ret=mpn_add_n(t,z,x,n);
ret+=mpn_add_n(t,t,y,n);
return ret;
}
ret=mpn_add_n(t,z,x,n);
ret+=mpn_add_n(t,t,y,n);
return ret;
}
#include "mpir.h"
#include "gmp-impl.h"
// t=x+y-z
int mpn_addsub_n(mp_ptr t,mp_srcptr x,mp_srcptr y,mp_srcptr z,mp_size_t n)
{mp_limb_t ret;
if(t==x && t==y && t==z)
{
return 0;
}
if(t==x && t==y)
{ret=mpn_add_n(t,x,y,n);
ret-=mpn_sub_n(t,t,z,n);
return ret;
}
if(t==x && t==z)
{ret=-mpn_sub_n(t,x,z,n);
ret+=mpn_add_n(t,t,y,n);
return ret;
}
if(t==y && t==z)
{ret=-mpn_sub_n(t,y,z,n);
ret+=mpn_add_n(t,t,x,n);
return ret;
}
if(t==x)
{ret=mpn_add_n(t,x,y,n);
ret-=mpn_sub_n(t,t,z,n);
return ret;
}
if(t==y)
{ret=mpn_add_n(t,y,x,n);
ret-=mpn_sub_n(t,t,z,n);
return ret;
}
if(t==z)
{ret=-mpn_sub_n(t,x,z,n);
ret+=mpn_add_n(t,t,y,n);
return ret;
}
ret=mpn_add_n(t,x,y,n);
ret-=mpn_sub_n(t,t,z,n);
return ret;
}
#include "mpir.h"
#include "gmp-impl.h"
//t=x-y-z
mp_limb_t mpn_subadd_n(mp_ptr t,mp_srcptr x,mp_srcptr y,mp_srcptr z,mp_size_t n)
{mp_limb_t ret;
if(t==x && t==y && t==z)
{
return mpn_neg(t,z,n);
}
if(t==x && t==y)
{ret=mpn_sub_n(t,x,y,n);
ret+=mpn_sub_n(t,t,z,n);
return ret;
}
if(t==x && t==z)
{ret=mpn_sub_n(t,x,z,n);
ret+=mpn_sub_n(t,t,y,n);
return ret;
}
if(t==y && t==z)
{ret=mpn_add_n(t,y,z,n);
ret+=mpn_sub_n(t,x,t,n);// checkcarry
return ret;
}
if(t==x)
{ret=mpn_sub_n(t,x,y,n);
ret+=mpn_sub_n(t,t,z,n);
return ret;
}
if(t==y)
{ret=mpn_sub_n(t,x,y,n);
ret+=mpn_sub_n(t,t,z,n);
return ret;
}
if(t==z)
{ret=mpn_sub_n(t,x,z,n);
ret+=mpn_sub_n(t,t,y,n);
return ret;
}
ret=mpn_sub_n(t,x,z,n);
ret+=mpn_sub_n(t,t,y,n);
return ret;
}