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.
Ltac DeclHelper := red in HELPERS; decompose [Logic.and] HELPERS; eauto.
Remark eval_builtin_1:
forall bf le id sg arg1 varg1 vres,
eval_expr ge sp e m le arg1 varg1 ->
lookup_builtin_function id sg = Some bf ->
builtin_function_sem bf (varg1 :: nil) = Some vres ->
eval_expr ge sp e m le (Ebuiltin (EF_builtin id sg) (arg1 ::: Enil)) vres.
Remark eval_builtin_2:
forall bf le id sg arg1 arg2 varg1 varg2 vres,
eval_expr ge sp e m le arg1 varg1 ->
eval_expr ge sp e m le arg2 varg2 ->
lookup_builtin_function id sg = Some bf ->
builtin_function_sem bf (varg1 :: varg2 :: nil) = Some vres ->
eval_expr ge sp e m le (Ebuiltin (EF_builtin id sg) (arg1 ::: arg2 ::: Enil)) vres.
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.
Ltac EvalOp :=
eauto;
match goal with
| [ |- eval_exprlist _ _ _ _ _ Enil _ ] => constructor
| [ |- eval_exprlist _ _ _ _ _ (_:::_) _ ] => econstructor; EvalOp
| [ |- eval_expr _ _ _ _ _ (Eletvar _) _ ] => constructor; simpl; eauto
| [ |- eval_expr _ _ _ _ _ (Elet _ _) _ ] => econstructor; EvalOp
| [ |- eval_expr _ _ _ _ _ (lift _) _ ] => apply eval_lift; EvalOp
| [ |- eval_expr _ _ _ _ _ _ _ ] => eapply eval_Eop; [EvalOp | simpl; eauto]
| _ => idtac
end.
Proof eval_lowlong.
Remark eval_shift_imm:
forall (P: expr -> Prop) n a0 a1 a2 a3,
(n = Int.zero -> P a0) ->
(0 <= Int.unsigned n < Int.zwordsize ->
Int.ltu n Int.iwordsize = true ->
Int.ltu (Int.sub Int.iwordsize n) Int.iwordsize = true ->
Int.ltu n Int64.iwordsize' = true ->
P a1) ->
(Int.zwordsize <= Int.unsigned n < Int64.zwordsize ->
Int.ltu (Int.sub n Int.iwordsize) Int.iwordsize = true ->
P a2) ->
P a3 ->
P (if Int.eq n Int.zero then a0
else if Int.ltu n Int.iwordsize then a1
else if Int.ltu n Int64.iwordsize' then a2
else a3).

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