(** Correctness of [make_store]. *)

Inductive val_lessdef_upto (m: int): val -> val -> Prop :=
  | val_lessdef_upto_base:
      forall v1 v2, Val.lessdef v1 v2 -> val_lessdef_upto m v1 v2
  | val_lessdef_upto_int:
      forall n1 n2, Int.and n1 m = Int.and n2 m -> val_lessdef_upto m (Vint n1) (Vint n2).(** Correctness of [make_store]. *)

Inductive val_lessdef_upto (m: int): val -> val -> Prop :=
  | val_lessdef_upto_base:
      forall v1 v2, Val.lessdef v1 v2 -> val_lessdef_upto m v1 v2
  | val_lessdef_upto_int:
      forall n1 n2, Int.and n1 m = Int.and n2 m -> val_lessdef_upto m (Vint n1) (Vint n2).(** Correctness of [make_store]. *)

Inductive val_lessdef_upto (m: int): val -> val -> Prop :=
  | val_lessdef_upto_base:
      forall v1 v2, Val.lessdef v1 v2 -> val_lessdef_upto m v1 v2
  | val_lessdef_upto_int:
      forall n1 n2, Int.and n1 m = Int.and n2 m -> val_lessdef_upto m (Vint n1) (Vint n2).Remark val_lessdef_upto_and:
  forall m v1 v2 p,
  val_lessdef_upto m v1 v2 -> Int.and p m = m ->
  val_lessdef_upto m (Val.and v1 (Vint p)) v2.Remark val_lessdef_upto_zero_ext:
  forall m v1 v2 p,
  val_lessdef_upto m v1 v2 -> Int.and (Int.repr (two_p p - 1)) m = m -> 0 < p < 32 ->
  val_lessdef_upto m (Val.zero_ext p v1) v2.Remark val_lessdef_upto_sign_ext:
  forall m v1 v2 p,
  val_lessdef_upto m v1 v2 -> Int.and (Int.repr (two_p p - 1)) m = m -> 0 < p < 32 ->
  val_lessdef_upto m (Val.sign_ext p v1) v2.Remark val_lessdef_upto_shru:
  forall m v1 v2 p,
  val_lessdef_upto (Int.shl m p) v1 v2 -> Int.shru (Int.shl m p) p = m ->
  val_lessdef_upto m (Val.shru v1 (Vint p)) (Val.shru v2 (Vint p)).Remark val_lessdef_upto_shr:
  forall m v1 v2 p,
  val_lessdef_upto (Int.shl m p) v1 v2 -> Int.shru (Int.shl m p) p = m ->
  val_lessdef_upto m (Val.shr v1 (Vint p)) (Val.shr v2 (Vint p)).

Lemma eval_uncast_int: forall m sp te tm a x, eval_expr tge sp te tm a x -> exists v, eval_expr tge sp te tm (uncast_int m a) v /\ val_lessdef_upto m x v.