diff --git a/src/lib.rs b/src/lib.rs index c40eedf87f..e0e908d671 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,6 +22,7 @@ #![feature(derive_coerce_pointee)] #![feature(arbitrary_self_types)] #![feature(macro_metavar_expr)] +#![feature(uint_carryless_mul)] // Configure clippy and other lints #![allow( clippy::collapsible_else_if, diff --git a/src/shims/x86/mod.rs b/src/shims/x86/mod.rs index dc0d8d48ac..ce6538c8ca 100644 --- a/src/shims/x86/mod.rs +++ b/src/shims/x86/mod.rs @@ -1178,21 +1178,7 @@ fn pclmulqdq<'tcx>( let index = if (imm8 & 0x10) == 0 { lo } else { hi }; let right = ecx.read_scalar(&ecx.project_index(&right, index)?)?.to_u64()?; - // Perform carry-less multiplication. - // - // This operation is like long multiplication, but ignores all carries. - // That idea corresponds to the xor operator, which is used in the implementation. - // - // Wikipedia has an example https://en.wikipedia.org/wiki/Carry-less_product#Example - let mut result: u128 = 0; - - for i in 0..64 { - // if the i-th bit in right is set - if (right & (1 << i)) != 0 { - // xor result with `left` shifted to the left by i positions - result ^= u128::from(left) << i; - } - } + let result = left.widening_carryless_mul(right); let dest = ecx.project_index(&dest, i)?; ecx.write_scalar(Scalar::from_u128(result), &dest)?;