Remark int64_shru'_div_two_p:
  forall x y, Int64.shru' x y = Int64.repr (Int64.unsigned x / two_p (Int.unsigned y)).

(* Specifications: *)
Theorem divlu_mul_shift: forall x y m p, divlu_mul_params (Int64.unsigned y) = Some(p, m) -> 0 <= p < 64 /\ Int64.divu x y = Int64.shru' (Int64.mulhu x (Int64.repr m)) (Int.repr p).
Lemma is_intconst_sound: forall v a n le, is_intconst a = Some n -> eval_expr ge sp e m le a v -> v = Vint n.
Lemma eval_divu_mul: forall le x y p M, divu_mul_params (Int.unsigned y) = Some(p, M) -> nth_error le O = Some (Vint x) -> eval_expr ge sp e m le (divu_mul p M) (Vint (Int.divu x y)).
Theorem eval_divuimm: forall le e1 x n2 z, eval_expr ge sp e m le e1 x -> Val.divu x (Vint n2) = Some z -> exists v, eval_expr ge sp e m le (divuimm e1 n2) v /\ Val.lessdef z v.
Theorem eval_divu: forall le a b x y z, eval_expr ge sp e m le a x -> eval_expr ge sp e m le b y -> Val.divu x y = Some z -> exists v, eval_expr ge sp e m le (divu a b) v /\ Val.lessdef z v.
Lemma eval_mod_from_div: forall le a n x y, eval_expr ge sp e m le a (Vint y) -> nth_error le O = Some (Vint x) -> eval_expr ge sp e m le (mod_from_div a n) (Vint (Int.sub x (Int.mul y n))).
Theorem eval_moduimm: forall le e1 x n2 z, eval_expr ge sp e m le e1 x -> Val.modu x (Vint n2) = Some z -> exists v, eval_expr ge sp e m le (moduimm e1 n2) v /\ Val.lessdef z v.
Theorem eval_modu: forall le a b x y z, eval_expr ge sp e m le a x -> eval_expr ge sp e m le b y -> Val.modu x y = Some z -> exists v, eval_expr ge sp e m le (modu a b) v /\ Val.lessdef z v.
Lemma eval_divs_mul: forall le x y p M, divs_mul_params (Int.signed y) = Some(p, M) -> nth_error le O = Some (Vint x) -> eval_expr ge sp e m le (divs_mul p M) (Vint (Int.divs x y)).
Theorem eval_divsimm: forall le e1 x n2 z, eval_expr ge sp e m le e1 x -> Val.divs x (Vint n2) = Some z -> exists v, eval_expr ge sp e m le (divsimm e1 n2) v /\ Val.lessdef z v.
Theorem eval_divs: forall le a b x y z, eval_expr ge sp e m le a x -> eval_expr ge sp e m le b y -> Val.divs x y = Some z -> exists v, eval_expr ge sp e m le (divs a b) v /\ Val.lessdef z v.
Theorem eval_modsimm: forall le e1 x n2 z, eval_expr ge sp e m le e1 x -> Val.mods x (Vint n2) = Some z -> exists v, eval_expr ge sp e m le (modsimm e1 n2) v /\ Val.lessdef z v.
Theorem eval_mods: forall le a b x y z, eval_expr ge sp e m le a x -> eval_expr ge sp e m le b y -> Val.mods x y = Some z -> exists v, eval_expr ge sp e m le (mods a b) v /\ Val.lessdef z v.
Lemma eval_modl_from_divl: forall le a n x y, eval_expr ge sp e m le a (Vlong y) -> nth_error le O = Some (Vlong x) -> eval_expr ge sp e m le (modl_from_divl a n) (Vlong (Int64.sub x (Int64.mul y n))).
Lemma eval_divlu_mull: forall le x y p M, divlu_mul_params (Int64.unsigned y) = Some(p, M) -> nth_error le O = Some (Vlong x) -> eval_expr ge sp e m le (divlu_mull p M) (Vlong (Int64.divu x y)).
Theorem eval_divlu: forall le a b x y z, eval_expr ge sp e m le a x -> eval_expr ge sp e m le b y -> Val.divlu x y = Some z -> exists v, eval_expr ge sp e m le (divlu a b) v /\ Val.lessdef z v.
Theorem eval_modlu: forall le a b x y z, eval_expr ge sp e m le a x -> eval_expr ge sp e m le b y -> Val.modlu x y = Some z -> exists v, eval_expr ge sp e m le (modlu a b) v /\ Val.lessdef z v.
Lemma eval_divls_mull: forall le x y p M, divls_mul_params (Int64.signed y) = Some(p, M) -> nth_error le O = Some (Vlong x) -> eval_expr ge sp e m le (divls_mull p M) (Vlong (Int64.divs x y)).
Theorem eval_divls: forall le a b x y z, eval_expr ge sp e m le a x -> eval_expr ge sp e m le b y -> Val.divls x y = Some z -> exists v, eval_expr ge sp e m le (divls a b) v /\ Val.lessdef z v.
Theorem eval_modls: forall le a b x y z, eval_expr ge sp e m le a x -> eval_expr ge sp e m le b y -> Val.modls x y = Some z -> exists v, eval_expr ge sp e m le (modls a b) v /\ Val.lessdef z v.
Theorem eval_divf: forall le a b x y, eval_expr ge sp e m le a x -> eval_expr ge sp e m le b y -> exists v, eval_expr ge sp e m le (divf a b) v /\ Val.lessdef (Val.divf x y) v.
Theorem eval_divfs: forall le a b x y, eval_expr ge sp e m le a x -> eval_expr ge sp e m le b y -> exists v, eval_expr ge sp e m le (divfs a b) v /\ Val.lessdef (Val.divfs x y) v.