Correctness of instruction selection for integer division
Require Import String.
Require Import Coqlib Maps.
Require Import AST Errors Integers Floats.
Require Import Values Memory Globalenvs Events Cminor Op CminorSel.
Require Import SelectOp SelectOpproof SplitLong.
Require Import Blockset Footprint Op_fp CUAST helpers Cminor_local CminorSel_local SplitLongproof
selectop_proof.
Local Open Scope cminorsel_scope.
Local Open Scope string_scope.
Characterizing the helper functions
Definition helper_declared {
F V:
Type} (
cu:
comp_unit_generic (
AST.fundef F)
V) (
id:
ident) (
name:
string) (
sg:
signature) :
Prop :=
(
comp_unit_defmap cu)!
id =
Some (
Gfun (
External (
EF_runtime name sg))).
Definition helper_functions_declared {
F V:
Type} (
p:
comp_unit_generic (
AST.fundef F)
V) (
hf:
helper_functions) :
Prop :=
helper_declared p i64_dtos "
__i64_dtos"
sig_f_l
/\
helper_declared p i64_dtou "
__i64_dtou"
sig_f_l
/\
helper_declared p i64_stod "
__i64_stod"
sig_l_f
/\
helper_declared p i64_utod "
__i64_utod"
sig_l_f
/\
helper_declared p i64_stof "
__i64_stof"
sig_l_s
/\
helper_declared p i64_utof "
__i64_utof"
sig_l_s
/\
helper_declared p i64_sdiv "
__i64_sdiv"
sig_ll_l
/\
helper_declared p i64_udiv "
__i64_udiv"
sig_ll_l
/\
helper_declared p i64_smod "
__i64_smod"
sig_ll_l
/\
helper_declared p i64_umod "
__i64_umod"
sig_ll_l
/\
helper_declared p i64_shl "
__i64_shl"
sig_li_l
/\
helper_declared p i64_shr "
__i64_shr"
sig_li_l
/\
helper_declared p i64_sar "
__i64_sar"
sig_li_l
/\
helper_declared p i64_umulh "
__i64_umulh"
sig_ll_l
/\
helper_declared p i64_smulh "
__i64_smulh"
sig_ll_l.
Correctness of the instruction selection functions for 64-bit operators
Ltac exacteval H:=
eapply eval_expr_preserved;
try eexact H;
try gegen;
eauto with gegen.
Ltac evalge H:=
eapply eval_expr_preserved in H;
try (
try gegen;
eauto with gegen;
fail).
Ltac swapeq fp0 fp5:=
match goal with
| |-
context[(
FP.union (
FP.union ?
fp4 fp0) (
FP.union fp5 ?
fp1))] =>
rewrite <- (
FP.fp_union_assoc fp4 fp0), (
FP.fp_union_assoc fp0 fp5), (
FP.union_comm_eq fp0 fp5);
rewrite <- (
FP.fp_union_assoc fp5 fp0), (
FP.fp_union_assoc fp4 fp5)
end.
Ltac rffp :=
repeat rewrite FP.fp_union_assoc.
Ltac trivcons :=
repeat econstructor;
eauto with evalexpr evalexprfp;
simpl;
eauto.
Section CMCONSTR.
Variable prog:
cminorsel_comp_unit.
Variable hf:
helper_functions.
Hypothesis HELPERS:
helper_functions_declared prog hf.
Variable ge :
genv.
Hypothesis GE_INIT:
globalenv_generic prog ge.
Variable sp:
val.
Variable e:
env.
Variable m:
mem.
Ltac UseHelper :=
decompose [
Logic.and]
i64_helpers_correct;
eauto.
Ltac DeclHelper :=
red in HELPERS;
decompose [
Logic.and]
HELPERS;
eauto.
Lemma eval_helper_fp:
forall le id name sg args vargs fp vres (
Hi64ext:
i64ext (
EF_runtime name sg)),
eval_exprlist ge sp e m le args vargs ->
eval_exprlist_fp ge sp e m le args fp ->
helper_declared prog id name sg ->
external_implements name sg vargs vres ->
eval_expr_fp ge sp e m le (
Eexternal id sg args)
fp.
Proof.
Corollary eval_helper_fp_1:
forall le id name sg arg1 varg1 fp vres (
Hi64ext:
i64ext (
EF_runtime name sg)),
eval_expr ge sp e m le arg1 varg1 ->
eval_expr_fp ge sp e m le arg1 fp ->
helper_declared prog id name sg ->
external_implements name sg (
varg1::
nil)
vres ->
eval_expr_fp ge sp e m le (
Eexternal id sg (
arg1 :::
Enil))
fp.
Proof.
intros.
eapply eval_helper_fp;
eauto.
constructor;
auto.
constructor.
econstructor;
eauto.
econstructor.
econstructor.
rewrite FP.fp_union_emp;
auto.
Qed.
Corollary eval_helper_fp_2:
forall le id name sg arg1 arg2 varg1 fp1 varg2 fp2 vres (
Hi64ext:
i64ext (
EF_runtime name sg)),
eval_expr ge sp e m le arg1 varg1 ->
eval_expr_fp ge sp e m le arg1 fp1 ->
eval_expr ge sp e m le arg2 varg2 ->
eval_expr_fp ge sp e m le arg2 fp2 ->
helper_declared prog id name sg ->
external_implements name sg (
varg1::
varg2::
nil)
vres ->
eval_expr_fp ge sp e m le (
Eexternal id sg (
arg1 :::
arg2 :::
Enil)) (
FP.union fp1 fp2).
Proof.
intros.
eapply eval_helper_fp;
eauto.
constructor;
auto.
constructor;
auto.
constructor.
econstructor;
eauto.
econstructor;
eauto.
econstructor.
econstructor;
eauto.
econstructor.
econstructor.
rewrite FP.fp_union_emp;
auto.
Qed.
Remark eval_builtin_fp_1:
forall le id sg arg1 varg1 fp1 vres (
Hi64ext:
i64ext (
EF_builtin id sg)),
eval_expr ge sp e m le arg1 varg1 ->
eval_expr_fp ge sp e m le arg1 fp1 ->
builtin_implements id sg (
varg1::
nil)
vres ->
eval_expr_fp ge sp e m le (
Ebuiltin (
EF_builtin id sg) (
arg1 :::
Enil))
fp1.
Proof.
intros.
econstructor;
eauto.
econstructor.
eauto.
constructor.
econstructor;
eauto.
constructor.
constructor.
rewrite FP.fp_union_emp;
auto.
Qed.
Remark eval_builtin_2:
forall le id sg arg1 arg2 varg1 fp1 varg2 fp2 vres (
Hi64ext:
i64ext (
EF_builtin id sg)),
eval_expr ge sp e m le arg1 varg1 ->
eval_expr_fp ge sp e m le arg1 fp1 ->
eval_expr ge sp e m le arg2 varg2 ->
eval_expr_fp ge sp e m le arg2 fp2 ->
builtin_implements id sg (
varg1::
varg2::
nil)
vres ->
eval_expr_fp ge sp e m le (
Ebuiltin (
EF_builtin id sg) (
arg1 :::
arg2 :::
Enil)) (
FP.union fp1 fp2).
Proof.
intros.
econstructor;
eauto.
constructor;
eauto.
constructor;
eauto.
constructor.
econstructor;
eauto.
econstructor;
eauto.
constructor.
econstructor;
eauto.
constructor.
constructor.
rewrite FP.fp_union_emp;
auto.
Qed.
cstr won't introduce additional footprint
Definition unary_constructor_fp_sound (
cstr:
expr ->
expr) :
Prop :=
forall le a x fp z,
eval_expr ge sp e m le a x ->
eval_expr_fp ge sp e m le a fp ->
eval_expr ge sp e m le (
cstr a)
z ->
exists fp',
eval_expr_fp ge sp e m le (
cstr a)
fp' /\
FP.subset fp'
fp.
Definition binary_constructor_fp_sound (
cstr:
expr ->
expr ->
expr) :
Prop :=
forall le a x fp1 b y fp2 z,
eval_expr ge sp e m le a x ->
eval_expr_fp ge sp e m le a fp1 ->
eval_expr ge sp e m le b y ->
eval_expr_fp ge sp e m le b fp2 ->
eval_expr ge sp e m le (
cstr a b)
z ->
exists fp,
eval_expr_fp ge sp e m le (
cstr a b)
fp /\
FP.subset fp (
FP.union fp1 fp2).
Theorems about cstr
Theorem eval_intoflong_fp:
unary_constructor_fp_sound intoflong.
Proof.
Theorem eval_longofintu_fp:
unary_constructor_fp_sound longofintu.
Proof.
Theorem eval_longofint_fp:
unary_constructor_fp_sound longofint.
Proof.
Lemma eval_longconst_fp:
forall le n,
eval_expr_fp ge sp e m le (
longconst n)
FP.emp.
Proof.
intros. EvalOpFP. repeat econstructor; eauto. Qed.
Theorem eval_negl_fp:
unary_constructor_fp_sound negl.
Proof.
intros le a x fp.
intros.
unfold negl.
case (
is_longconst a)
eqn:? ;
InvEvalFP;
Triv.
UseHelper.
eapply H8.
Qed.
Lemma eval_splitlong_fp:
forall le a f v fp v',
(
forall le a b x y fpx fpy z,
eval_expr ge sp e m le a x ->
eval_expr_fp ge sp e m le a fpx ->
eval_expr ge sp e m le b y ->
eval_expr_fp ge sp e m le b fpy ->
eval_expr ge sp e m le (
f a b)
z ->
exists fp',
eval_expr_fp ge sp e m le (
f a b)
fp' /\
FP.subset fp' (
FP.union fpx fpy)) ->
eval_expr ge sp e m le a v ->
eval_expr_fp ge sp e m le a fp ->
eval_expr ge sp e m le (
splitlong a f)
v' ->
exists fp',
eval_expr_fp ge sp e m le (
splitlong a f)
fp' /\
FP.subset fp'
fp.
Proof.
intros until v';
intros EXEC.
unfold splitlong.
case (
splitlong_match a)
eqn:
SM;
intros EVAL EVALFP EVAL'.
-
InvEval;
InvEvalFP;
InvEmpFP;
InvEval;
eqexpr.
exploit EXEC.
exact H3.
exact H8.
exact H2.
exact H10.
eauto.
intros [
fp' [
A B]].
Triv.
-
inv EVAL';
eqexpr.
exploit (
EXEC (
v1 ::
le) (
Eop Ohighlong (
Eletvar 0 :::
Enil)) (
Eop Olowlong (
Eletvar 0 :::
Enil)));
eauto.
EvalOp.
repeat econstructor;
eauto.
simpl.
eauto.
repeat econstructor;
eauto.
EvalOp.
repeat econstructor;
eauto.
simpl.
eauto.
repeat econstructor;
eauto.
TrivFP.
intros [
fp' [
A B]].
Triv.
rewrite FP.union_comm_eq.
rewrite <- (
FP.emp_union_fp fp)
at 2.
apply FP.union2_subset;
auto.
Qed.
Lemma eval_splitlong2_fp:
forall le a b f va vb fpa fpb v,
(
forall le a1 a2 b1 b2 x1 x2 fpx1 fpx2 y1 y2 fpy1 fpy2 v,
eval_expr ge sp e m le a1 x1 ->
eval_expr ge sp e m le a2 x2 ->
eval_expr_fp ge sp e m le a1 fpx1 ->
eval_expr_fp ge sp e m le a2 fpx2 ->
eval_expr ge sp e m le b1 y1 ->
eval_expr ge sp e m le b2 y2 ->
eval_expr_fp ge sp e m le b1 fpy1 ->
eval_expr_fp ge sp e m le b2 fpy2 ->
eval_expr ge sp e m le (
f a1 a2 b1 b2)
v ->
exists fp,
eval_expr_fp ge sp e m le (
f a1 a2 b1 b2)
fp /\
FP.subset fp (
FP.union (
FP.union fpx1 fpx2) (
FP.union fpy1 fpy2))) ->
eval_expr ge sp e m le a va ->
eval_expr_fp ge sp e m le a fpa ->
eval_expr ge sp e m le b vb ->
eval_expr_fp ge sp e m le b fpb ->
eval_expr ge sp e m le (
splitlong2 a b f)
v ->
exists fp,
eval_expr_fp ge sp e m le (
splitlong2 a b f)
fp /\
FP.subset fp (
FP.union fpa fpb).
Proof.
Theorem eval_notl_fp:
unary_constructor_fp_sound notl.
Proof.
Theorem eval_longoffloat_fp:
forall le a x fpx y,
eval_expr ge sp e m le a x ->
eval_expr_fp ge sp e m le a fpx ->
Val.longoffloat x =
Some y ->
exists fp,
eval_expr_fp ge sp e m le (
longoffloat a)
fp /\
FP.subset fp fpx.
Proof.
intros;
unfold longoffloat.
econstructor;
split.
eapply eval_helper_fp_1;
eauto. 2:
DeclHelper.
constructor.
UseHelper;
auto.
TrivFP.
Qed.
Theorem eval_longuoffloat_fp:
forall le a x fpx y,
eval_expr ge sp e m le a x ->
eval_expr_fp ge sp e m le a fpx ->
Val.longuoffloat x =
Some y ->
exists fp,
eval_expr_fp ge sp e m le (
longuoffloat a)
fp /\
FP.subset fp fpx.
Proof.
Theorem eval_floatoflong_fp:
forall le a x fpx y,
eval_expr ge sp e m le a x ->
eval_expr_fp ge sp e m le a fpx ->
Val.floatoflong x =
Some y ->
exists fp,
eval_expr_fp ge sp e m le (
floatoflong a)
fp /\
FP.subset fp fpx.
Proof.
Theorem eval_floatoflongu_fp:
forall le a x fpx y,
eval_expr ge sp e m le a x ->
eval_expr_fp ge sp e m le a fpx ->
Val.floatoflongu x =
Some y ->
exists fp,
eval_expr_fp ge sp e m le (
floatoflongu a)
fp /\
FP.subset fp fpx.
Proof.
Theorem eval_longofsingle_fp:
forall le a x fpx y,
eval_expr ge sp e m le a x ->
eval_expr_fp ge sp e m le a fpx ->
Val.longofsingle x =
Some y ->
exists fp,
eval_expr_fp ge sp e m le (
longofsingle a)
fp /\
FP.subset fp fpx.
Proof.
Theorem eval_longuofsingle_fp:
forall le a x fpx y,
eval_expr ge sp e m le a x ->
eval_expr_fp ge sp e m le a fpx ->
Val.longuofsingle x =
Some y ->
exists fp,
eval_expr_fp ge sp e m le (
longuofsingle a)
fp /\
FP.subset fp fpx.
Proof.
Theorem eval_singleoflong_fp:
forall le a x fpx y,
eval_expr ge sp e m le a x ->
eval_expr_fp ge sp e m le a fpx ->
Val.singleoflong x =
Some y ->
exists fp,
eval_expr_fp ge sp e m le (
singleoflong a)
fp /\
FP.subset fp fpx.
Proof.
Theorem eval_singleoflongu_fp:
forall le a x fpx y,
eval_expr ge sp e m le a x ->
eval_expr_fp ge sp e m le a fpx ->
Val.singleoflongu x =
Some y ->
exists fp,
eval_expr_fp ge sp e m le (
singleoflongu a)
fp /\
FP.subset fp fpx.
Proof.
Theorem eval_andl_fp:
binary_constructor_fp_sound andl.
Proof.
Theorem eval_orl_fp:
binary_constructor_fp_sound orl.
Proof.
Theorem eval_xorl_fp:
binary_constructor_fp_sound xorl.
Proof.
Lemma eval_lowlong_fp:
unary_constructor_fp_sound lowlong.
Proof.
unfold lowlong;
red.
intros until x.
destruct (
lowlong_match a);
intros.
InvEvalFP;
InvEval;
eqexpr;
simpl in *;
FuncInv;
subst.
Triv.
Triv.
Qed.
Lemma eval_highlong_fp:
unary_constructor_fp_sound highlong.
Proof.
unfold highlong;
red.
intros until x.
destruct (
highlong_match a);
intros.
InvEvalFP;
InvEval;
eqexpr;
simpl in *;
FuncInv;
subst.
Triv.
Triv.
Qed.
Lemma eval_shllimm_fp:
forall n,
unary_constructor_fp_sound (
fun e =>
shllimm e n).
Proof.
Lemma eval_shrlimm_fp:
forall n,
unary_constructor_fp_sound (
fun e =>
shrlimm e n).
Proof.
Lemma eval_shrluimm_fp:
forall n,
unary_constructor_fp_sound (
fun e =>
shrluimm e n).
Proof.
Theorem eval_shll_fp:
binary_constructor_fp_sound shll.
Proof.
unfold shll;
red;
intros.
repeat match goal with | |-
context[
match ?
x with _ =>
_ end] =>
destruct x eqn:?
end.
-
exploit eval_shllimm_fp.
exact H.
exact H0.
exact H3.
intros [
fp [
A B]].
Triv.
-
econstructor;
split.
eapply eval_helper_fp_2;
eauto. 2:
DeclHelper.
constructor.
UseHelper.
TrivFP.
Qed.
Theorem eval_shrlu_fp:
binary_constructor_fp_sound shrlu.
Proof.
unfold shrlu;
red;
intros.
repeat match goal with | |-
context[
match ?
x with _ =>
_ end] =>
destruct x eqn:?
end.
-
exploit eval_shrluimm_fp.
exact H.
exact H0.
exact H3.
intros [
fp [
A B]].
Triv.
-
econstructor;
split.
eapply eval_helper_fp_2;
eauto. 2:
DeclHelper.
constructor.
UseHelper.
TrivFP.
Qed.
Theorem eval_shrl_fp:
binary_constructor_fp_sound shrl.
Proof.
unfold shrl;
red;
intros.
repeat match goal with | |-
context[
match ?
x with _ =>
_ end] =>
destruct x eqn:?
end.
-
exploit eval_shrlimm_fp.
exact H.
exact H0.
exact H3.
intros [
fp [
A B]].
Triv.
-
econstructor;
split.
eapply eval_helper_fp_2;
eauto. 2:
DeclHelper.
constructor.
UseHelper.
TrivFP.
Qed.
Theorem eval_addl_fp:
Archi.ptr64 =
false ->
binary_constructor_fp_sound addl.
Proof.
unfold addl;
red;
intros.
repeat match goal with | |-
context[
match ?
x with _ =>
_ end] =>
destruct x eqn:?
end;
Triv;
inv H4;
InvEval;
eqexpr;
eauto.
Qed.
Theorem eval_subl_fp:
Archi.ptr64 =
false ->
binary_constructor_fp_sound subl.
Proof.
unfold subl;
red;
intros.
repeat match goal with | |-
context[
match ?
x with _ =>
_ end] =>
destruct x eqn:?
end;
try (
Triv;
inv H4;
InvEval;
eqexpr;
eauto;
fail).
exploit eval_negl_fp.
exact H2.
exact H3.
exact H4.
intros [
fp' [
A B]].
Triv.
Qed.
Lemma eval_mull_base_fp:
binary_constructor_fp_sound mull_base.
Proof.
Lemma eval_mullimm_fp:
forall n,
unary_constructor_fp_sound (
mullimm n).
Proof.
unfold mullimm;
red;
intros.
repeat match goal with | |-
context[
match ?
x with _ =>
_ end] =>
destruct x eqn:?
end;
try (
Triv;
inv H4;
InvEval;
eqexpr;
eauto;
fail).
exploit eval_shllimm_fp.
exact H.
exact H0.
exact H1.
intros [
fp' [
A B]].
Triv.
exploit eval_mull_base_fp.
exact H.
exact H0.
instantiate (2:=
longconst n).
repeat econstructor.
repeat econstructor.
exact H1.
TrivFP.
Qed.
Theorem eval_mull_fp:
binary_constructor_fp_sound mull.
Proof.
unfold mull;
red;
intros.
repeat match goal with | |-
context[
match ?
x with _ =>
_ end] =>
destruct x eqn:?
end.
Triv.
exploit eval_mullimm_fp.
exact H1.
exact H2.
exact H3.
intros [
fp' [
A B]].
Triv.
exploit eval_mullimm_fp.
exact H.
exact H0.
exact H3.
intros [
fp' [
A B]].
Triv.
exploit eval_mull_base_fp.
exact H.
exact H0.
exact H1.
exact H2.
exact H3.
intros [
fp' [
A B]].
Triv.
Qed.
Theorem eval_mullhu_fp:
forall n,
unary_constructor_fp_sound (
fun a =>
mullhu a n).
Proof.
unfold mullhu;
intros;
red;
intros.
eexists.
split.
eapply eval_helper_fp_2;
eauto. 4:
DeclHelper;
eauto.
constructor.
repeat econstructor.
repeat econstructor.
UseHelper.
TrivFP.
Qed.
Theorem eval_mullhs_fp:
forall n,
unary_constructor_fp_sound (
fun a =>
mullhs a n).
Proof.
unfold mullhs;
intros;
red;
intros.
econstructor;
split.
eapply eval_helper_fp_2;
eauto. 4:
DeclHelper;
eauto.
constructor.
repeat econstructor.
repeat econstructor.
UseHelper.
TrivFP.
Qed.
Theorem eval_shrxlimm_fp:
forall le a n x fpx z,
Archi.ptr64 =
false ->
eval_expr ge sp e m le a x ->
eval_expr_fp ge sp e m le a fpx ->
Val.shrxl x (
Vint n) =
Some z ->
exists fp,
eval_expr_fp ge sp e m le (
shrxlimm a n)
fp /\
FP.subset fp fpx.
Proof.
Theorem eval_divlu_base_fp:
forall le a b x y fpx fpy z,
eval_expr ge sp e m le a x ->
eval_expr_fp ge sp e m le a fpx ->
eval_expr ge sp e m le b y ->
eval_expr_fp ge sp e m le b fpy ->
Val.divlu x y =
Some z ->
exists fp,
eval_expr_fp ge sp e m le (
divlu_base a b)
fp /\
FP.subset fp (
FP.union fpx fpy).
Proof.
intros;
unfold divlu_base.
econstructor;
split.
eapply eval_helper_fp_2;
eauto.
2:
DeclHelper.
constructor.
UseHelper.
TrivFP. Qed.
Theorem eval_modlu_base_fp:
forall le a b x y fpx fpy z,
eval_expr ge sp e m le a x ->
eval_expr_fp ge sp e m le a fpx ->
eval_expr ge sp e m le b y ->
eval_expr_fp ge sp e m le b fpy ->
Val.modlu x y =
Some z ->
exists fp,
eval_expr_fp ge sp e m le (
modlu_base a b)
fp /\
FP.subset fp (
FP.union fpx fpy).
Proof.
intros;
unfold modlu_base.
econstructor;
split.
eapply eval_helper_fp_2;
eauto. 2:
DeclHelper.
constructor.
UseHelper.
TrivFP. Qed.
Theorem eval_divls_base_fp:
forall le a b x y fpx fpy z,
eval_expr ge sp e m le a x ->
eval_expr_fp ge sp e m le a fpx ->
eval_expr ge sp e m le b y ->
eval_expr_fp ge sp e m le b fpy ->
Val.divls x y =
Some z ->
exists fp,
eval_expr_fp ge sp e m le (
divls_base a b)
fp /\
FP.subset fp (
FP.union fpx fpy).
Proof.
intros;
unfold divls_base.
econstructor;
split.
eapply eval_helper_fp_2;
eauto.
2:
DeclHelper.
constructor.
UseHelper.
TrivFP.
Qed.
Theorem eval_modls_base_fp:
forall le a b x y fpx fpy z,
eval_expr ge sp e m le a x ->
eval_expr_fp ge sp e m le a fpx ->
eval_expr ge sp e m le b y ->
eval_expr_fp ge sp e m le b fpy ->
Val.modls x y =
Some z ->
exists fp,
eval_expr_fp ge sp e m le (
modls_base a b)
fp /\
FP.subset fp (
FP.union fpx fpy).
Proof.
intros;
unfold modls_base.
econstructor;
split.
eapply eval_helper_fp_2;
eauto.
2:
DeclHelper.
constructor.
UseHelper.
TrivFP.
Qed.
Lemma eval_cmpl_eq_zero_fp:
forall le a x fpx,
eval_expr ge sp e m le a (
Vlong x) ->
eval_expr_fp ge sp e m le a fpx ->
exists fp,
eval_expr_fp ge sp e m le (
cmpl_eq_zero a)
fp /\
FP.subset fp fpx.
Proof.
Lemma eval_cmpl_ne_zero_fp:
forall le a x fpx,
eval_expr ge sp e m le a (
Vlong x) ->
eval_expr_fp ge sp e m le a fpx ->
exists fp,
eval_expr_fp ge sp e m le (
cmpl_ne_zero a)
fp /\
FP.subset fp fpx.
Proof.
Lemma eval_cmpl_gen_fp:
forall ch cl a b le x fpx y fpy,
eval_expr ge sp e m le a (
Vlong x) ->
eval_expr_fp ge sp e m le a fpx ->
eval_expr ge sp e m le b (
Vlong y) ->
eval_expr_fp ge sp e m le b fpy ->
exists fp,
eval_expr_fp ge sp e m le (
cmpl_gen ch cl a b)
fp /\
FP.subset fp (
FP.union fpx fpy).
Proof.
intros.
unfold cmpl_gen.
exploit eval_cmpl_gen.
exacteval H.
exacteval H1.
instantiate (1:=
ch).
instantiate (1:=
cl).
intro A.
evalge A.
unfold cmpl_gen in *.
unfold splitlong2 in *.
case (
splitlong2_match a b)
eqn:
SL;
clear SL;
inv A;
InvEvalFP;
InvEval;
eqexpr;
simpl in *;
FuncInv;
subst.
++
destruct v11,
v12;
inv H;
destruct v13,
v14;
inv H0.
inv H8;
InvEval;
eqexpr;
simpl in *;
FuncInv;
subst.
destruct Int.eq eqn:
IEQ;
eexists; (
split; [
trivcons;
try rewrite IEQ;
simpl;
eauto;
trivcons|]).
TrivFP.
swapeq fp0 fp5.
TrivFP.
TrivFP.
apply subset2_union;
swapeq fp0 fp5;
TrivFP.
++
destruct v6,
v7;
inv H.
inv H8.
inv H9.
InvEval;
simpl in *;
eqexpr.
pose proof (
eval_lift ge sp e m le h1 _ (
Vlong y)
H4).
eqexpr.
inv H5.
inv H3.
simpl in H8.
inv H8.
destruct Int.eq eqn:
IEQ;
eexists; (
split; [
trivcons;
try rewrite IEQ;
simpl;
eauto;
trivcons|
TrivFP]).
rewrite (
FP.union_comm_eq fpy).
apply FP.union2_subset.
apply subset2_union;
TrivFP.
++
destruct v6,
v7;
inv H1.
inv H8.
inv H9.
InvEval;
simpl in *;
eqexpr.
pose proof (
eval_lift ge sp e m le h2 _ (
Vlong x)
H4).
eqexpr.
inv H6.
inv H3.
simpl in H8.
inv H8.
destruct Int.eq eqn:
IEQ;
eexists; (
split; [
trivcons;
try rewrite IEQ;
simpl;
eauto;
trivcons|
TrivFP]).
repeat apply subset2_union;
TrivFP;
rewrite FP.union_comm_eq, <-
FP.fp_union_assoc;
TrivFP.
++
inv H8.
pose proof (
eval_lift _ _ _ _ _ _ _ (
Vlong x)
H1).
eqexpr.
inv H9.
inv H10.
InvEval;
eqexpr.
inv H8.
inv H7.
inv H5.
inv H8.
simpl in H9.
inv H9.
destruct Int.eq eqn:
IEQ;
eexists; (
split; [
trivcons;
try rewrite IEQ;
simpl;
eauto;
trivcons|
TrivFP]).
Qed.
Theorem eval_cmpl_fp:
forall c le a x fpx b y fpy v,
eval_expr ge sp e m le a x ->
eval_expr_fp ge sp e m le a fpx ->
eval_expr ge sp e m le b y ->
eval_expr_fp ge sp e m le b fpy ->
Val.cmpl c x y =
Some v ->
exists fp,
eval_expr_fp ge sp e m le (
cmpl c a b)
fp /\
FP.subset fp (
FP.union fpx fpy).
Proof.
Lemma eval_cmplu_gen_fp:
forall ch cl a b le x fpx y fpy,
eval_expr ge sp e m le a (
Vlong x) ->
eval_expr_fp ge sp e m le a fpx ->
eval_expr ge sp e m le b (
Vlong y) ->
eval_expr_fp ge sp e m le b fpy ->
exists fp,
eval_expr_fp ge sp e m le (
cmplu_gen ch cl a b)
fp /\
FP.subset fp (
FP.union fpx fpy).
Proof.
intros.
unfold cmplu_gen.
exploit eval_cmplu_gen.
exacteval H.
exacteval H1.
instantiate (1:=
ch).
instantiate (1:=
cl).
intro A.
evalge A.
unfold cmplu_gen in *.
unfold splitlong2 in *.
case (
splitlong2_match a b)
eqn:
SL;
clear SL;
inv A;
InvEvalFP;
InvEval;
eqexpr;
simpl in *;
FuncInv;
subst.
++
destruct v11,
v12;
inv H;
destruct v13,
v14;
inv H0.
inv H8;
InvEval;
eqexpr;
simpl in *;
FuncInv;
subst.
destruct Int.eq eqn:
IEQ;
eexists; (
split; [
trivcons;
try rewrite IEQ;
simpl;
eauto;
trivcons|]).
TrivFP.
swapeq fp0 fp5.
TrivFP.
TrivFP.
apply subset2_union;
swapeq fp0 fp5;
TrivFP.
++
destruct v6,
v7;
inv H.
inv H8.
inv H9.
InvEval;
simpl in *;
eqexpr.
pose proof (
eval_lift ge sp e m le h1 _ (
Vlong y)
H4).
eqexpr.
inv H5.
inv H3.
simpl in H8.
inv H8.
destruct Int.eq eqn:
IEQ;
eexists; (
split; [
trivcons;
try rewrite IEQ;
simpl;
eauto;
trivcons|
TrivFP]).
rewrite (
FP.union_comm_eq fpy).
apply FP.union2_subset.
apply subset2_union;
TrivFP.
++
destruct v6,
v7;
inv H1.
inv H8.
inv H9.
InvEval;
simpl in *;
eqexpr.
pose proof (
eval_lift ge sp e m le h2 _ (
Vlong x)
H4).
eqexpr.
inv H6.
inv H3.
simpl in H8.
inv H8.
destruct Int.eq eqn:
IEQ;
eexists; (
split; [
trivcons;
try rewrite IEQ;
simpl;
eauto;
trivcons|
TrivFP]).
repeat apply subset2_union;
TrivFP;
rewrite FP.union_comm_eq, <-
FP.fp_union_assoc;
TrivFP.
++
inv H8.
pose proof (
eval_lift _ _ _ _ _ _ _ (
Vlong x)
H1).
eqexpr.
inv H9.
inv H10.
InvEval;
eqexpr.
inv H8.
inv H7.
inv H5.
inv H8.
simpl in H9.
inv H9.
destruct Int.eq eqn:
IEQ;
eexists; (
split; [
trivcons;
try rewrite IEQ;
simpl;
eauto;
trivcons|
TrivFP]).
Qed.
Theorem eval_cmplu_fp:
forall c le a x fpx b y fpy v,
eval_expr ge sp e m le a x ->
eval_expr_fp ge sp e m le a fpx ->
eval_expr ge sp e m le b y ->
eval_expr_fp ge sp e m le b fpy ->
Val.cmplu (
Mem.valid_pointer m)
c x y =
Some v ->
Archi.ptr64 =
false ->
exists fp,
eval_expr_fp ge sp e m le (
cmplu c a b)
fp /\
FP.subset fp (
FP.union fpx fpy).
Proof.
End CMCONSTR.