#include "gmp.h" // This is an AltiVec-enhanced mpn_lshift() routine // To compile with gcc, use the -faltivec flag in addition to any other flags mp_limb_t mpn_lshift(mp_limb_t *rp, const mp_limb_t *sp, mp_size_t n, unsigned int count) { int i, lshift_int, rshift_int; lshift_int = count; rshift_int = 32 - count; if(n > 3) { vector unsigned int lshift, rshift, zero, temp, temp2, carry_shift; vector unsigned int *a = (vector unsigned int*)sp, *result = (vector unsigned int*)rp; zero = (vector unsigned int)(0); temp = vec_lde(0, &count); temp2 = vec_perm(temp, zero, vec_lvsl(0, &count)); lshift = vec_splat(temp2, 0); rshift = vec_sub((vector unsigned int)(32), lshift); carry_shift = zero; for(i = 0; i < (n >> 2); i++) { temp = vec_sl(a[i], lshift); temp2 = vec_sr(a[i], rshift); result[i] = vec_or(temp, vec_sld(carry_shift, temp2, 12)); carry_shift = temp2; } for(i = ((n >> 2) << 2); i < n; i++) { rp[i] = (sp[i] << lshift_int) | (sp[i - 1] >> rshift_int); } }else{ // n <= 3 rp[0] = sp[0] << lshift_int; for(i = 1; i < n; i++) { rp[i] = (sp[i] << lshift_int) | (sp[i - 1] >> rshift_int); } } return (sp[n - 1] >> (32 - count)); }