Section CMCONSTR.
Variable prog: program.
Variable hf: helper_functions.
Hypothesis HELPERS: helper_functions_declared prog hf.
Let ge := Genv.globalenv prog.
Variable sp: val.
Variable e: env.
Variable m: mem.
Definition unary_constructor_sound (cstr: expr -> expr) (sem: val -> val) : Prop :=
forall le a x,
eval_expr ge sp e m le a x ->
exists v, eval_expr ge sp e m le (cstr a) v /\ Val.lessdef (sem x) v.
Definition binary_constructor_sound (cstr: expr -> expr -> expr) (sem: val -> val -> val) : Prop :=
forall le a x b 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 (cstr a b) v /\ Val.lessdef (sem x y) v.
Definition partial_unary_constructor_sound (cstr: expr -> expr) (sem: val -> option val) : Prop :=
forall le a x y,
eval_expr ge sp e m le a x ->
sem x = Some y ->
exists v, eval_expr ge sp e m le (cstr a) v /\ Val.lessdef y v.
Definition partial_binary_constructor_sound (cstr: expr -> expr -> expr) (sem: val -> val -> option val) : Prop :=
forall le a x b y z,
eval_expr ge sp e m le a x ->
eval_expr ge sp e m le b y ->
sem x y = Some z ->
exists v, eval_expr ge sp e m le (cstr a b) v /\ Val.lessdef z v.
Proof with (try discriminate).
intros. unfold is_longconst in *. destruct Archi.splitlong.
eapply SplitLongproof.is_longconst_sound; eauto.
assert (a = Eop (Olongconst n) Enil).
{ destruct a... destruct o... destruct e0... congruence. }
subst a. InvEval. auto.
Qed.

Theorem eval_mullhs:
forall n, unary_constructor_sound (fun a => mullhs a n) (fun v => Val.mullhs v (Vlong n)).