Commit cdb47d44 authored by Raphael Rieu-Helft's avatar Raphael Rieu-Helft

Rework add/sub to be closer to GMP implementation

In particular, inline and simplify uses of add_with_carry/sub_with_borrow with a zero argument.
parent 404521ff
...@@ -30,7 +30,7 @@ module mach.int.Int32 ...@@ -30,7 +30,7 @@ module mach.int.Int32
syntax val (+) "(%1) + (%2)" syntax val (+) "(%1) + (%2)"
syntax val (-) "(%1) - (%2)" syntax val (-) "(%1) - (%2)"
syntax val (-_) "-(%1)" syntax val (-_) "-(%1)"
syntax val (*) "(%1) * (%2)" syntax val ( * ) "(%1) * (%2)"
syntax val (/) "(%1) / (%2)" syntax val (/) "(%1) / (%2)"
syntax val (%) "(%1) % (%2)" syntax val (%) "(%1) % (%2)"
syntax val (=) "(%1) == (%2)" syntax val (=) "(%1) == (%2)"
...@@ -56,7 +56,7 @@ module mach.int.UInt32 ...@@ -56,7 +56,7 @@ module mach.int.UInt32
syntax val (+) "(%1) + (%2)" syntax val (+) "(%1) + (%2)"
syntax val (-) "(%1) - (%2)" syntax val (-) "(%1) - (%2)"
syntax val (*) "(%1) * (%2)" syntax val ( * ) "(%1) * (%2)"
syntax val (/) "(%1) / (%2)" syntax val (/) "(%1) / (%2)"
syntax val (%) "(%1) % (%2)" syntax val (%) "(%1) % (%2)"
syntax val (=) "(%1) == (%2)" syntax val (=) "(%1) == (%2)"
...@@ -187,7 +187,7 @@ struct __lsld32_result lsld32(uint32_t x, uint32_t cnt); ...@@ -187,7 +187,7 @@ struct __lsld32_result lsld32(uint32_t x, uint32_t cnt);
syntax val (+) "(%1) + (%2)" syntax val (+) "(%1) + (%2)"
syntax val (-) "(%1) - (%2)" syntax val (-) "(%1) - (%2)"
syntax val (*) "(%1) * (%2)" syntax val ( * ) "(%1) * (%2)"
syntax val (/) "(%1) / (%2)" syntax val (/) "(%1) / (%2)"
syntax val (%) "(%1) % (%2)" syntax val (%) "(%1) % (%2)"
syntax val (=) "(%1) == (%2)" syntax val (=) "(%1) == (%2)"
...@@ -230,7 +230,7 @@ module mach.int.Int64 ...@@ -230,7 +230,7 @@ module mach.int.Int64
syntax val (+) "(%1) + (%2)" syntax val (+) "(%1) + (%2)"
syntax val (-) "(%1) - (%2)" syntax val (-) "(%1) - (%2)"
syntax val (-_) "-(%1)" syntax val (-_) "-(%1)"
syntax val (*) "(%1) * (%2)" syntax val ( * ) "(%1) * (%2)"
syntax val (/) "(%1) / (%2)" syntax val (/) "(%1) / (%2)"
syntax val (%) "(%1) % (%2)" syntax val (%) "(%1) % (%2)"
syntax val (=) "(%1) == (%2)" syntax val (=) "(%1) == (%2)"
...@@ -256,7 +256,7 @@ module mach.int.UInt64 ...@@ -256,7 +256,7 @@ module mach.int.UInt64
syntax val (+) "(%1) + (%2)" syntax val (+) "(%1) + (%2)"
syntax val (-) "(%1) - (%2)" syntax val (-) "(%1) - (%2)"
syntax val (-_) "-(%1)" syntax val (-_) "-(%1)"
syntax val (*) "(%1) * (%2)" syntax val ( * ) "(%1) * (%2)"
syntax val (/) "(%1) / (%2)" syntax val (/) "(%1) / (%2)"
syntax val (%) "(%1) % (%2)" syntax val (%) "(%1) % (%2)"
syntax val (=) "(%1) == (%2)" syntax val (=) "(%1) == (%2)"
...@@ -396,67 +396,121 @@ struct __lsld64_result lsld64(uint64_t x, uint64_t cnt) ...@@ -396,67 +396,121 @@ struct __lsld64_result lsld64(uint64_t x, uint64_t cnt)
#include \"longlong.h\" #include \"longlong.h\"
#undef invert_limb #undef invert_limb
struct __add64_with_carry_result struct __add64_with_carry_result
{ uint64_t __field_0; { uint64_t __field_0;
uint64_t __field_1; uint64_t __field_1;
}; };
struct __add64_with_carry_result static struct __add64_with_carry_result
add64_with_carry(uint64_t x, uint64_t y, uint64_t c); add64_with_carry(uint64_t x, uint64_t y, uint64_t c)
{
struct __add64_with_carry_result result;
uint64_t r = x + y + c;
result.__field_0 = r;
if (r == x) result.__field_1 = c;
else result.__field_1 = (r < x);
return result;
}
struct __add64_double_result struct __add64_double_result
{ uint64_t __field_0; { uint64_t __field_0;
uint64_t __field_1; uint64_t __field_1;
}; };
struct __add64_double_result static struct __add64_double_result
add64_double(uint64_t a1, uint64_t a0, uint64_t b1, uint64_t b0); add64_double(uint64_t a1, uint64_t a0, uint64_t b1, uint64_t b0)
{
struct __add64_double_result result;
add_ssaaaa(result.__field_0, result.__field_1, a1, a0, b1, b0);
return result;
}
struct __sub64_with_borrow_result struct __sub64_with_borrow_result
{ uint64_t __field_0; { uint64_t __field_0;
uint64_t __field_1; uint64_t __field_1;
}; };
struct __sub64_with_borrow_result static struct __sub64_with_borrow_result
sub64_with_borrow(uint64_t x, uint64_t y, uint64_t b); sub64_with_borrow(uint64_t x, uint64_t y, uint64_t b)
{
struct __sub64_with_borrow_result result;
uint64_t r = x - y - b;
result.__field_0 = r;
if (r > x) result.__field_1 = 1;
else if (r == x) result.__field_1 = b;
else result.__field_1 = 0;
return result;
}
struct __sub64_double_result struct __sub64_double_result
{ uint64_t __field_0; { uint64_t __field_0;
uint64_t __field_1; uint64_t __field_1;
}; };
struct __sub64_double_result static struct __sub64_double_result
sub64_double(uint64_t a1, uint64_t a0, uint64_t b1, uint64_t b0); sub64_double(uint64_t a1, uint64_t a0, uint64_t b1, uint64_t b0)
{
struct __sub64_double_result result;
sub_ddmmss(result.__field_0, result.__field_1, a1, a0, b1, b0);
return result;
}
struct __mul64_double_result struct __mul64_double_result
{ uint64_t __field_0; { uint64_t __field_0;
uint64_t __field_1; uint64_t __field_1;
}; };
struct __mul64_double_result mul64_double(uint64_t x, uint64_t y); static struct __mul64_double_result mul64_double(uint64_t x, uint64_t y)
{
struct __mul64_double_result result;
umul_ppmm(result.__field_1,result.__field_0,x,y);
return result;
}
uint64_t div64_2by1(uint64_t ul, uint64_t uh, uint64_t d); static uint64_t div64_2by1(uint64_t ul, uint64_t uh, uint64_t d)
{
uint64_t q;
uint64_t _dummy __attribute__((unused));
udiv_qrnnd(q,_dummy,uh,ul,d);
return q;
}
struct __add64_3_result struct __add64_3_result
{ uint64_t __field_0; { uint64_t __field_0;
uint64_t __field_1; uint64_t __field_1;
}; };
struct __add64_3_result add64_3(uint64_t x, uint64_t y, uint64_t z); static struct __add64_3_result add64_3(uint64_t x, uint64_t y, uint64_t z)
{
struct __add64_3_result result;
uint64_t r, c1, c2;
r = x + y;
c1 = r < y;
r += z;
c2 = r < z;
result.__field_1 = c1 + c2;
result.__field_0 = r;
return result;
}
struct __lsld64_result struct __lsld64_result
{ uint64_t __field_0; { uint64_t __field_0;
uint64_t __field_1; uint64_t __field_1;
}; };
struct __lsld64_result lsld64(uint64_t x, uint64_t cnt); static struct __lsld64_result lsld64(uint64_t x, uint64_t cnt)
{
struct __lsld64_result result;
result.__field_1 = x >> (64 - cnt);
result.__field_0 = x << cnt;
return result;
}
" "
syntax converter of_int "%1ULL" syntax converter of_int "%1ULL"
syntax val (+) "(%1) + (%2)" syntax val (+) "(%1) + (%2)"
syntax val (-) "(%1) - (%2)" syntax val (-) "(%1) - (%2)"
syntax val (*) "(%1) * (%2)" syntax val ( * ) "(%1) * (%2)"
syntax val (/) "(%1) / (%2)" syntax val (/) "(%1) / (%2)"
syntax val (%) "(%1) % (%2)" syntax val (%) "(%1) % (%2)"
syntax val (=) "(%1) == (%2)" syntax val (=) "(%1) == (%2)"
......
This diff is collapsed.
This diff is collapsed.
...@@ -4,10 +4,10 @@ all: ...@@ -4,10 +4,10 @@ all:
./mulrelative & ./mulrelative &
./addrelative & ./addrelative &
./addplot & ./addplot &
./minidivrelative & # ./minidivrelative &
./minimulrelative & # ./minimulrelative &
./miniaddrelative & # ./miniaddrelative &
./gmpdivplot & # ./gmpdivplot &
./gmpmulplot & # ./gmpmulplot &
./gmpaddplot & # ./gmpaddplot &
./toomrelative ./toomrelative
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -42,8 +42,6 @@ void mpn_dump(mp_ptr ap, mp_size_t an) { ...@@ -42,8 +42,6 @@ void mpn_dump(mp_ptr ap, mp_size_t an) {
printf("\n"); printf("\n");
} }
void init_valid (mp_ptr ap, mp_ptr bp, mp_size_t an, mp_size_t bn) { void init_valid (mp_ptr ap, mp_ptr bp, mp_size_t an, mp_size_t bn) {
for (int i = 0; i <= an; i++) for (int i = 0; i <= an; i++)
ap[i] = genrand64_int64(); ap[i] = genrand64_int64();
...@@ -215,7 +213,7 @@ int main () { ...@@ -215,7 +213,7 @@ int main () {
printf ("#an bn t(s)\n"); printf ("#an bn t(s)\n");
#endif #endif
for (bn = 35; bn <= max_toom; bn += 5) for (bn = 35; bn <= max_toom; bn += 2)
{ {
mp_ptr ws = TMP_ALLOC_LIMBS(9 * bn / 2 + 32); mp_ptr ws = TMP_ALLOC_LIMBS(9 * bn / 2 + 32);
an = (bn * 3) / 2; an = (bn * 3) / 2;
......
...@@ -19,7 +19,7 @@ module Toom ...@@ -19,7 +19,7 @@ module Toom
use mul.Mul use mul.Mul
use logical.Logical use logical.Logical
let constant toom22_threshold : int32 = 20 let constant toom22_threshold : int32 = 30
let lemma no_borrow (x y r b m:int) let lemma no_borrow (x y r b m:int)
requires { 0 <= y <= x } requires { 0 <= y <= x }
...@@ -41,7 +41,7 @@ let rec toom22_mul (r x y scratch: ptr limb) (sx sy:int32) (ghost k: int) : unit ...@@ -41,7 +41,7 @@ let rec toom22_mul (r x y scratch: ptr limb) (sx sy:int32) (ghost k: int) : unit
requires { valid x sx } requires { valid x sx }
requires { valid y sy } requires { valid y sy }
requires { valid r (sx + sy) } requires { valid r (sx + sy) }
requires { toom22_threshold < sx } requires { toom22_threshold < sy }
requires { 0 < k } requires { 0 < k }
requires { sx <= toom22_threshold * power 2 k } requires { sx <= toom22_threshold * power 2 k }
requires { valid scratch (2 * (sx + k)) } requires { valid scratch (2 * (sx + k)) }
...@@ -782,7 +782,7 @@ with toom22_mul_rec (r x y scratch: ptr limb) (sx sy: int32) (ghost k: int) ...@@ -782,7 +782,7 @@ with toom22_mul_rec (r x y scratch: ptr limb) (sx sy: int32) (ghost k: int)
requires { valid x sx } requires { valid x sx }
requires { valid y sy } requires { valid y sy }
requires { valid r (sx + sy) } requires { valid r (sx + sy) }
requires { 0 < sy <= sx } requires { 0 < sy <= sx <= sy + sy }
requires { 8 * sx < max_int32 } requires { 8 * sx < max_int32 }
requires { 0 <= k } requires { 0 <= k }
requires { sx <= toom22_threshold * power 2 k } requires { sx <= toom22_threshold * power 2 k }
...@@ -805,7 +805,7 @@ with toom22_mul_rec (r x y scratch: ptr limb) (sx sy: int32) (ghost k: int) ...@@ -805,7 +805,7 @@ with toom22_mul_rec (r x y scratch: ptr limb) (sx sy: int32) (ghost k: int)
else else
if Int32.(<) (Int32.( *) 4 sx) (Int32.( *) 5 sy) (* ? *) if Int32.(<) (Int32.( *) 4 sx) (Int32.( *) 5 sy) (* ? *)
then toom22_mul r x y scratch sx sy k then toom22_mul r x y scratch sx sy k
else wmpn_mul r x y sx sy (* TODO toom33_mul *) else toom32_mul r x y scratch sx sy k
with toom22_mul_n_rec (r x y scratch: ptr limb) (sz:int32) (ghost k: int) : unit with toom22_mul_n_rec (r x y scratch: ptr limb) (sz:int32) (ghost k: int) : unit
requires { valid x sz } requires { valid x sz }
......
...@@ -1032,7 +1032,7 @@ module MLToC = struct ...@@ -1032,7 +1032,7 @@ module MLToC = struct
[], C.(Sexpr(Ebinop(Bassign, t, C.Evar v.pv_vs.vs_name))) [], C.(Sexpr(Ebinop(Bassign, t, C.Evar v.pv_vs.vs_name)))
| Eassign _ -> raise (Unsupported "assign") | Eassign _ -> raise (Unsupported "assign")
| Ehole | Eany _ -> assert false | Ehole | Eany _ -> assert false
| Eexn _ -> raise (Unsupported "exception") | Eexn (_,_,e) -> expr info env e
| Eignore e -> | Eignore e ->
[], C.Sseq(C.Sblock(expr info {env with computes_return_value = false} e), [], C.Sseq(C.Sblock(expr info {env with computes_return_value = false} e),
if env.computes_return_value if env.computes_return_value
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment