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 mpir-devel@googlegroups.com. To unsubscribe from this group, send email to mpir-devel+unsubscr...@googlegroups.com. 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; }