Constraints related to multiplication instructions in 32 bit RiscV M extension #538
vivekvpandya
started this conversation in
Ideas
Replies: 1 comment 2 replies
-
What's the maximum degree of the constraints you propose here? |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Check appendix A for maximum and minimum values in various possible configurations and those fits well with Goldilock Field.
Constraints for MUL and MULHU
Basic constraints:
multiplicand * multiplier = low_32_bits + 2^32 * high_32_bits
range_check(low_32_bits)
range_check(high_32_bits)
A small caveat:
For Goldilock prime,
2^32 * 0XFFFF_FFFF == -1
if
high_32_bits
value is0XFFFF_FFFF
then above constraint will behave likemultiplicand * multiplier = low_limb - 1
However largest possible result for unsigned * unsigned for 32 bits is
u32::MAX * u32::MAX = 0xFFFF_FFFE_0000_0001
so
high_32_bits
forMUL
andMULH
can never be0xFFFF_FFFF
for any valid case. Hence we add additional constraint for checking that too.Constraints for MULH and MULHSU
Basic constraints:
As these both operations can have signed value as result, we have following idea:
Above algorithm can be checked to work for all cases with simple rust test shown in appendix C.
A small caveat:
For case where result is 0 but any one operand has negative value, destination = 0, low_32_bits = 0, high_32_bits = 0 sign of product is negative so it needs 2's complement
high_32_bits_2s_complement = u32::MAX - high_32_bits + 1
( add 1 only if carried from complemented of low_32_bits, see appendix B)high_32_bits_2s_complement = 0x1_0000_0000
In primitive arithmetic we just take bits
0..31
and that turns out to be 0 which is same has destination.However we can't just take
0..31
bits in field arithmetic. So we handled this as special case when product is zero but one of operand has sign bit 1.And hence we get following constraint in code
Appendix
A)
Maximum and minimum possible values:
MAX 4294967295 (0xFFFFFFFF), MAX 4294967295 (0xFFFFFFFF), MULHU RES 18446744065119617025 (0xFFFFFFFE00000001)
MAX 2147483647 (0x7FFFFFFF), MIN -2147483648 (0xFFFFFFFF80000000), MULH RES -4611686016279904256 (0xC000000080000000)
MAX 2147483647 (0x7FFFFFFF), MAX 2147483647 (0x7FFFFFFF), MULH RES 4611686014132420609 (0x3FFFFFFF00000001)
MIN -2147483648 (0xFFFFFFFF80000000), MIN -2147483648 (0xFFFFFFFF80000000), MULH RES 4611686018427387904 (0x4000000000000000)
MIN -2147483648 (0xFFFFFFFF80000000), MAX 4294967295 (0xFFFFFFFF), MULHSU RES -9223372034707292160 (0xFFFFFFFFFFFFFFFF8000000080000000)
MAX 2147483647 (0x7FFFFFFF), MAX 4294967295 (0xFFFFFFFF), MULHSU RES 9223372030412324865 (0x7FFFFFFE80000001)
Goldilock Prime p=18446744069414584321=0xFFFFFFFF00000001 so all above values can be handled by GoldiLock Field.
B)
When we want 2's complement of high_32_bits we can use following equation
0xFFFF_FFFF - high_32_bits (+ 1 if 2's complement of low_32_bit is 0x1_0000_0000)
above case only happens if low_32_limbs is 0 and this u32::MAX - 0 + 1 == 0x1_0000_0000
C)
Beta Was this translation helpful? Give feedback.
All reactions