fast_muls.c
void mul_va128128_std(mzd_t *res, mzd_t *V, mzd_t *A, int clear)
{
//	unsigned arows = A->nrows;
	unsigned acols = A->ncols;
	unsigned vcols = V->ncols;
	unsigned vrows = V->nrows;
//	uint64_t vcolmask = vcols == 128 ? ~0ull : (1ull << (vcols - 64)) - 1ull;
//	uint64_t acolmask = acols == 128 ? ~0ull : (1ull << (acols - 64)) - 1ull;
	
	for (int j = 0; j < vrows; j++)
	{
		uint64_t mlo, mhi;
		uint64_t acc0lo = 0;
		uint64_t acc0hi = 0;
		uint64_t acc1lo = 0;
		uint64_t acc1hi = 0;
		uint64_t vlo = mzd_read_bits(V, j, 0, 64);
		uint64_t vhi = mzd_read_bits(V, j, 64, vcols-64);
//		uint64_t vhi = mzd_read_bits(V, j, 64, 64) & vcolmask;
//		uint64_t vlo = *(V->rows[j]); // FIXME: always correct?
//		uint64_t vhi = *(V->rows[j]+1); // FIXME: always correct?

		vlo = ~vlo;
		vhi = ~vhi;
		for (int i = 0; i < 64; i++)
		{
			mlo = (vlo & 1) - 1;
			mhi = (vhi & 1) - 1;
			acc0lo ^= (mlo & mzd_read_bits(A, i, 0, 64));
//			acc0hi ^= (mlo & mzd_read_bits(A, i, 64, acols-64));
			acc0hi ^= (mlo & mzd_read_bits(A, i, 64, 64)); // leftover is simply not copied
//			acc0lo ^= (mlo & *(A->rows[i])); // FIXME: always correct?
//			acc0hi ^= (mlo & *(A->rows[i]+1)); // FIXME: always correct?
			if (i+64 < vcols)
			{
				acc1lo ^= (mhi & mzd_read_bits(A, i+64, 0, 64));
//				acc1hi ^= (mhi & mzd_read_bits(A, i+64, 64, acols-64));
				acc1hi ^= (mhi & mzd_read_bits(A, i+64, 64, 64)); // ditto
//				acc1lo ^= (mhi & *(A->rows[i+64])); // FIXME: always correct?
//				acc1hi ^= (mhi & *(A->rows[i+64]+1)); // FIXME: always correct?
			}
			vlo >>= 1;
			vhi >>= 1;
		}
		if (clear)
		{
			mzd_and_bits(res, j, 0, 64, 0);
//			mzd_and_bits(res, j, 64, acols-64, 0);
			mzd_and_bits(res, j, 64, 64, 0);
		}
		mzd_xor_bits(res, j, 0, 64, acc0lo);
		mzd_xor_bits(res, j, 0, 64, acc1lo);
		mzd_xor_bits(res, j, 64, acols - 64, acc0hi);
		mzd_xor_bits(res, j, 64, acols - 64, acc1hi);
	}

	return;
}
/*
 * All input allocated
 * if clear, reset res before adding the result
 * Computes VxA, where A is at most 128x128
 * Warning: also needs V to have > 64 columns (otherwise, a smaller implementation is selected)
 * Warning: also needs A to have > 64 columns (otherwise, a smaller implementation is selected)
 */
All input allocated
if clear, reset res before adding the result
Computes VxA, where A is at most 128x128
Warning: also needs V to have > 64 columns (otherwise, a smaller implementation is selected)
Warning: also needs A to have > 64 columns (otherwise, a smaller implementation is selected)
All input allocated if clear reset res before adding the result Computes VxA where A is at most 128x128 Warning : also needs V to have > 64 columns ( otherwise a smaller implementation is selected ) Warning : also needs A to have > 64 columns ( otherwise a smaller implementation is selected )
void mul_va128128_std(mzd_t *res, mzd_t *V, mzd_t *A, int clear)
{
	unsigned acols = A->ncols;
	unsigned vcols = V->ncols;
	unsigned vrows = V->nrows;
	for (int j = 0; j < vrows; j++)
	{
		uint64_t mlo, mhi;
		uint64_t acc0lo = 0;
		uint64_t acc0hi = 0;
		uint64_t acc1lo = 0;
		uint64_t acc1hi = 0;
		uint64_t vlo = mzd_read_bits(V, j, 0, 64);
		uint64_t vhi = mzd_read_bits(V, j, 64, vcols-64);
		vlo = ~vlo;
		vhi = ~vhi;
		for (int i = 0; i < 64; i++)
		{
			mlo = (vlo & 1) - 1;
			mhi = (vhi & 1) - 1;
			acc0lo ^= (mlo & mzd_read_bits(A, i, 0, 64));
			acc0hi ^= (mlo & mzd_read_bits(A, i, 64, 64)); 
			if (i+64 < vcols)
			{
				acc1lo ^= (mhi & mzd_read_bits(A, i+64, 0, 64));
				acc1hi ^= (mhi & mzd_read_bits(A, i+64, 64, 64)); 
			}
			vlo >>= 1;
			vhi >>= 1;
		}
		if (clear)
		{
			mzd_and_bits(res, j, 0, 64, 0);
			mzd_and_bits(res, j, 64, 64, 0);
		}
		mzd_xor_bits(res, j, 0, 64, acc0lo);
		mzd_xor_bits(res, j, 0, 64, acc1lo);
		mzd_xor_bits(res, j, 64, acols - 64, acc0hi);
		mzd_xor_bits(res, j, 64, acols - 64, acc1hi);
	}
	return;
}
void mul_va128128_std ( mzd_t * res , mzd_t * V , mzd_t * A , int clear ) { unsigned acols = A -> ncols ; unsigned vcols = V -> ncols ; unsigned vrows = V -> nrows ; for ( int j = 0 ; j < vrows ; j ++ ) { uint64_t mlo , mhi ; uint64_t acc0lo = 0 ; uint64_t acc0hi = 0 ; uint64_t acc1lo = 0 ; uint64_t acc1hi = 0 ; uint64_t vlo = mzd_read_bits ( V , j , 0 , 64 ) ; uint64_t vhi = mzd_read_bits ( V , j , 64 , vcols - 64 ) ; vlo = ~ vlo ; vhi = ~ vhi ; for ( int i = 0 ; i < 64 ; i ++ ) { mlo = ( vlo & 1 ) - 1 ; mhi = ( vhi & 1 ) - 1 ; acc0lo ^= ( mlo & mzd_read_bits ( A , i , 0 , 64 ) ) ; acc0hi ^= ( mlo & mzd_read_bits ( A , i , 64 , 64 ) ) ; if ( i + 64 < vcols ) { acc1lo ^= ( mhi & mzd_read_bits ( A , i + 64 , 0 , 64 ) ) ; acc1hi ^= ( mhi & mzd_read_bits ( A , i + 64 , 64 , 64 ) ) ; } vlo >>= 1 ; vhi >>= 1 ; } if ( clear ) { mzd_and_bits ( res , j , 0 , 64 , 0 ) ; mzd_and_bits ( res , j , 64 , 64 , 0 ) ; } mzd_xor_bits ( res , j , 0 , 64 , acc0lo ) ; mzd_xor_bits ( res , j , 0 , 64 , acc1lo ) ; mzd_xor_bits ( res , j , 64 , acols - 64 , acc0hi ) ; mzd_xor_bits ( res , j , 64 , acols - 64 , acc1hi ) ; } return ; }
All input allocated
 if clear, reset res before adding the result
 Computes VxA, where A is at most 128x128
 Warning: also needs V to have > 64 columns (otherwise, a smaller implementation is selected)
 Warning: also needs A to have > 64 columns (otherwise, a smaller implementation is selected)
All input allocated if clear reset res before adding the result Computes VxA where A is at most 128x128 Warning : also needs V to have > 64 columns ( otherwise a smaller implementation is selected ) Warning : also needs A to have > 64 columns ( otherwise a smaller implementation is selected )
//	unsigned arows = A->nrows; //	uint64_t vcolmask = vcols == 128 ? ~0ull : (1ull << (vcols - 64)) - 1ull; //	uint64_t acolmask = acols == 128 ? ~0ull : (1ull << (acols - 64)) - 1ull; //		uint64_t vhi = mzd_read_bits(V, j, 64, 64) & vcolmask; //		uint64_t vlo = *(V->rows[j]); // FIXME: always correct? //		uint64_t vhi = *(V->rows[j]+1); // FIXME: always correct? //			acc0hi ^= (mlo & mzd_read_bits(A, i, 64, acols-64)); // leftover is simply not copied //			acc0lo ^= (mlo & *(A->rows[i])); // FIXME: always correct? //			acc0hi ^= (mlo & *(A->rows[i]+1)); // FIXME: always correct? //				acc1hi ^= (mhi & mzd_read_bits(A, i+64, 64, acols-64)); // ditto //				acc1lo ^= (mhi & *(A->rows[i+64])); // FIXME: always correct? //				acc1hi ^= (mhi & *(A->rows[i+64]+1)); // FIXME: always correct? //			mzd_and_bits(res, j, 64, acols-64, 0);