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
syntax val (+) "(%1) + (%2)"
syntax val (-) "(%1) - (%2)"
syntax val (-_) "-(%1)"
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
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);
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
syntax val (+) "(%1) + (%2)"
syntax val (-) "(%1) - (%2)"
syntax val (-_) "-(%1)"
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
syntax val (+) "(%1) + (%2)"
syntax val (-) "(%1) - (%2)"
syntax val (-_) "-(%1)"
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)
#include \"longlong.h\"
#undef invert_limb
struct __add64_with_carry_result
{ uint64_t __field_0;
uint64_t __field_1;
};
struct __add64_with_carry_result
add64_with_carry(uint64_t x, uint64_t y, uint64_t c);
static struct __add64_with_carry_result
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
{ uint64_t __field_0;
uint64_t __field_1;
};
struct __add64_double_result
add64_double(uint64_t a1, uint64_t a0, uint64_t b1, uint64_t b0);
static struct __add64_double_result
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
{ uint64_t __field_0;
uint64_t __field_1;
};
struct __sub64_with_borrow_result
sub64_with_borrow(uint64_t x, uint64_t y, uint64_t b);
static struct __sub64_with_borrow_result
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
{ uint64_t __field_0;
uint64_t __field_1;
};
struct __sub64_double_result
sub64_double(uint64_t a1, uint64_t a0, uint64_t b1, uint64_t b0);
static struct __sub64_double_result
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
{ uint64_t __field_0;
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
{ uint64_t __field_0;
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
{ uint64_t __field_0;
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 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:
./mulrelative &
./addrelative &
./addplot &
./minidivrelative &
./minimulrelative &
./miniaddrelative &
./gmpdivplot &
./gmpmulplot &
./gmpaddplot &
# ./minidivrelative &
# ./minimulrelative &
# ./miniaddrelative &
# ./gmpdivplot &
# ./gmpmulplot &
# ./gmpaddplot &
./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) {
printf("\n");
}
void init_valid (mp_ptr ap, mp_ptr bp, mp_size_t an, mp_size_t bn) {
for (int i = 0; i <= an; i++)
ap[i] = genrand64_int64();
......@@ -215,7 +213,7 @@ int main () {
printf ("#an bn t(s)\n");
#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);
an = (bn * 3) / 2;
......
......@@ -19,7 +19,7 @@ module Toom
use mul.Mul
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)
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
requires { valid x sx }
requires { valid y sy }
requires { valid r (sx + sy) }
requires { toom22_threshold < sx }
requires { toom22_threshold < sy }
requires { 0 < k }
requires { sx <= toom22_threshold * power 2 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)
requires { valid x sx }
requires { valid y sy }
requires { valid r (sx + sy) }
requires { 0 < sy <= sx }
requires { 0 < sy <= sx <= sy + sy }
requires { 8 * sx < max_int32 }
requires { 0 <= 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)
else
if Int32.(<) (Int32.( *) 4 sx) (Int32.( *) 5 sy) (* ? *)
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
requires { valid x sz }
......
......@@ -1032,7 +1032,7 @@ module MLToC = struct
[], C.(Sexpr(Ebinop(Bassign, t, C.Evar v.pv_vs.vs_name)))
| Eassign _ -> raise (Unsupported "assign")
| Ehole | Eany _ -> assert false
| Eexn _ -> raise (Unsupported "exception")
| Eexn (_,_,e) -> expr info env e
| Eignore e ->
[], C.Sseq(C.Sblock(expr info {env with computes_return_value = false} e),
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