Fix comments
Paul-Henry Kajfasz kajfaszph@gmail.com
Thu, 22 Aug 2024 15:21:59 +0100
1 files changed,
21 insertions(+),
20 deletions(-)
M
src/hash/rescue/arch/x86_64_avx2.rs
→
src/hash/rescue/arch/x86_64_avx2.rs
@@ -5,36 +5,37 @@ // https://github.com/0xPolygonZero/plonky2/blob/main/plonky2/src/hash/arch/x86_64/poseidon_goldilocks_avx2_bmi2.rs
// Preliminary notes: // 1. AVX does not support addition with carry but 128-bit (2-word) addition can be easily emulated. -// The method recognizes that for a + b overflowed iff (a + b) < a: -// - i. res_lo = a_lo + b_lo -// - ii. carry_mask = res_lo < a_lo -// - iii. res_hi = a_hi + b_hi - carry_mask Notice that carry_mask is subtracted, not added. +// The method recognizes that for a + b overflowed iff (a + b) < a: i. res_lo = a_lo + b_lo ii. +// carry_mask = res_lo < a_lo iii. res_hi = a_hi + b_hi - carry_mask +// +// Notice that carry_mask is subtracted, not added. +// // This is because AVX comparison instructions return -1 (all bits 1) for true and 0 for false. // // 2. AVX does not have unsigned 64-bit comparisons. Those can be emulated with signed comparisons // by recognizing that a <u b iff a + (1 << 63) <s b + (1 << 63), where the addition wraps around // and the comparisons are unsigned and signed respectively. The shift function adds/subtracts 1 -// << 63 to enable this trick. Addition with carry example: -// - i. a_lo_s = shift(a_lo) -// - ii. res_lo_s = a_lo_s + b_lo -// - iii. carry_mask = res_lo_s <s a_lo_s -// - iv. res_lo = shift(res_lo_s) -// - v. res_hi = a_hi + b_hi - carry_mask The suffix _s denotes a value that has been -// shifted by 1 << 63. +// << 63 to enable this trick. Addition with carry example: i. a_lo_s = shift(a_lo) ii. res_lo_s +// = a_lo_s + b_lo iii. carry_mask = res_lo_s <s a_lo_s iv. res_lo = shift(res_lo_s) v. res_hi = +// a_hi + b_hi - carry_mask // -// The result of addition is shifted if exactly one of the operands is shifted, as is the case on +// The suffix _s denotes a value that has been shifted by 1 << 63. The result of addition +// is shifted if exactly one of the operands is shifted, as is the case on // line ii. Line iii. performs a signed comparison res_lo_s <s a_lo_s on shifted values to // emulate unsigned comparison res_lo <u a_lo on unshifted values. Finally, line iv. reverses the -// shift so the result can be returned. When performing a chain of calculations, we can often +// shift so the result can be returned. +// +// When performing a chain of calculations, we can often // save instructions by letting the shift propagate through and only undoing it when necessary. // For example, to compute the addition of three two-word (128-bit) numbers we can do: -// - i. a_lo_s = shift(a_lo) -// - ii. tmp_lo_s = a_lo_s + b_lo -// - iii. tmp_carry_mask = tmp_lo_s <s a_lo_s -// - iv. tmp_hi = a_hi + b_hi - tmp_carry_mask -// - v. res_lo_s = tmp_lo_s + c_lo vi. res_carry_mask = res_lo_s <s tmp_lo_s -// - vii. res_lo = shift(res_lo_s) -// - viii. res_hi = tmp_hi + c_hi - res_carry_mask +// i. a_lo_s = shift(a_lo) +// ii. tmp_lo_s = a_lo_s + b_lo +// iii. tmp_carry_mask = tmp_lo_s <s a_lo_s +// iv. tmp_hi = a_hi + b_hi - tmp_carry_mask +// v. res_lo_s = tmp_lo_s + c_lo vi. res_carry_mask = res_lo_s <s tmp_lo_s +// vii. res_lo = shift(res_lo_s) +// viii. res_hi = tmp_hi + c_hi - res_carry_mask +// // Notice that the above 3-value addition still only requires two calls to shift, just like our // 2-value addition.