Require Import
Coqlib Values Maps Registers
Traces Errors Globalenvs
Simulations TSOsimulation
.
Require Import
Utf8 Classical
Utils Common
RTLinject RTLinjectlow RTL
RTLofRTLinject
RTLofRTLinjectspec.
Section CORRECT.
Variable bi :
backend_info.
Hypothesis OK_BI:
ok_bi bi.
Inductive match_fundef :
RTLinject.fundef →
RTL.fundef →
Prop :=
|
MFI sg param ssz c c'
ep
(
SIG: ∀
t,
In t sg.(
Ast.sig_args) →
t =
Ast.Tint)
(
CODE:
match_code bi c c')
:
match_fundef
(
Ast.Internal (
RTLinject.mkfunction sg param ssz c ep))
(
Ast.Internal (
RTL.mkfunction sg (
map xO param)
ssz c'
ep))
|
MFE f
:
match_fundef (
Ast.External f) (
Ast.External f)
.
Remark transl_fundef_correct {
f f'} :
transl_fundef bi f =
OK f' →
match_fundef f f'.
Proof.
Definition genv_rel :
RTLinject.genv →
RTL.genv →
Prop :=
fun x y =>
Genv.genv_match (
fun a b =>
transl_fundef bi a =
Errors.OK b)
y x.
Definition match_prg p p' :=
transf_program bi p =
OK p'.
Section SIM.
Variables (
ge:
RTLinject.genv) (
tge:
RTL.genv).
Hypothesis TRANSF:
genv_rel ge tge.
Let lts :=
mklts thread_labels (
rtl_step'
ge).
Let tlts :=
mklts thread_labels (
rtl_step tge).
Definition match_regset :
INJECT.regset →
RTL.regset →
Prop :=
fun x y =>
∀
r,
Val.lessdef (
x r) (
y # (
xO r)).
Definition match_inject_regset :
INJECT.regset →
RTL.regset →
Prop :=
fun x y =>
∀
r,
Val.lessdef (
x r) (
y # (
xI r)).
Lemma match_regset_upd rs rs' :
match_regset rs rs' →
∀
v v',
Val.lessdef v v' →
∀
r,
match_regset (
upd rs r v) (
rs' # (
xO r) <-
v').
Proof.
intros H v v' V r r'.
unfold upd.
eq_case. intros ->. now rewrite Regmap.gss.
intros NE. rewrite Regmap.gso. apply H.
congruence.
Qed.
Lemma match_regset_iupd rs rs' :
match_regset rs rs' →
∀
v v',
Val.lessdef v v' →
∀
r,
match_regset rs (
rs' # (
xI r) <-
v').
Proof.
intros H v v' V r r'.
rewrite Regmap.gso. apply H.
congruence.
Qed.
Lemma match_iregset_upd rs rs' :
match_inject_regset rs rs' →
∀
v v',
Val.lessdef v v' →
∀
r,
match_inject_regset (
INJECT.upd_regset rs r v) (
rs' # (
xI r) <-
v').
Proof.
intros H v v' V r r'.
unfold INJECT.upd_regset.
case (peq r' r). intros ->. now rewrite Regmap.gss.
intros NE. rewrite Regmap.gso. apply H.
congruence.
Qed.
Hint Resolve match_regset_upd match_regset_iupd match_iregset_upd.
Lemma match_args_lessdef {
rs rs'} :
match_regset rs rs' →
∀
args,
Val.lessdef_list (
map rs args) (
rs' ## (
map xO args)).
Proof.
intros REGS.
induction args; simpl; vauto.
Qed.
Lemma match_iargs_lessdef {
rs rs'} :
match_inject_regset rs rs' →
∀
args,
Val.lessdef_list (
map rs args) (
rs' ## (
map xI args)).
Proof.
intros REGS.
induction args; simpl; vauto.
Qed.
Lemma match_init_regs :
∀
param,
forall args'
args,
Val.lessdef_list args args' →
match_regset (
reg_upd (
fun _ :
reg =>
Vundef)
param args)
(
init_regs args' (
map xO param)).
Proof.
induction param as [|
p param IH].
unfold reg_upd,
init_regs.
simpl.
intros ? ?
_ r.
vauto.
simpl.
intros [|
x args];
intros ?
K;
inv K;
unfold reg_upd;
simpl.
intros r;
vauto.
fold reg_upd.
intros r.
unfold upd.
eq_case.
now intros ->;
rewrite Regmap.gss.
intros K.
rewrite Regmap.gso.
apply IH;
auto.
intros Q;
apply K.
now inv Q.
Qed.
Lemma match_find_function {
rs rs'} :
match_regset rs rs' →
∀
ros fd,
RTLinject.find_function ge ros rs =
Some fd →
∃
fd',
RTL.find_function tge (
match ros with inl f =>
inl Ast.ident (
xO f) |
inr f =>
inr _ f end)
rs' =
Some fd'
∧
match_fundef fd fd'.
Proof.
destruct TRANSF as (
T1 &
T3).
intros REGS [
r|
s]
fd;
simpl.
pose proof (
REGS r)
as Hr.
destruct (
rs r);
clarify.
simpl.
specialize T3 with p.
intros H.
rewrite H in T3.
case_eq (
Genv.find_funct_ptr tge p).
intros fd'
H'.
rewrite H'
in T3.
exists fd'.
inv Hr.
split;
auto using @
transl_fundef_correct.
intros K;
rewrite K in T3.
easy.
intros H.
specialize T1 with s.
destruct (
Genv.find_symbol ge s);
simpl in *.
specialize T3 with p.
rewrite H in T3.
case_eq (
Genv.find_funct_ptr tge p).
intros fd'
H'.
rewrite H'
in T3.
exists fd'.
rewrite <-
T1.
split;
auto using @
transl_fundef_correct.
intros K;
rewrite K in T3.
easy.
now clarify.
Qed.
Lemma match_eval_addressing {
ad sp v a a'} :
Val.lessdef_list a a' →
Op.eval_addressing ge sp ad a =
Some v →
Op.eval_addressing tge sp ad a' =
Some v.
Proof.
destruct TRANSF as (
T1 &
T3).
induction 1
as [|
a a'
args args'
U V IH].
destruct ad;
simpl;
eauto.
case_eq (
Genv.find_symbol ge i).
now intros p Hp;
rewrite <-
T1,
Hp.
case_eq (
Genv.find_symbol tge i);
clarify.
destruct args as [|
b args];
inv V.
destruct ad;
simpl;
destruct a;
inv U;
vauto.
case_eq (
Genv.find_symbol ge i).
intros p Hp;
now rewrite <-
T1,
Hp.
case_eq (
Genv.find_symbol tge i);
clarify.
case_eq (
Genv.find_symbol ge i0).
now intros p Hp;
rewrite <-
T1,
Hp.
now case_eq (
Genv.find_symbol tge i0);
clarify.
destruct args as [|
c args];
inv H3.
destruct ad;
simpl;
destruct a;
inv U;
destruct b;
inv H1;
clarify;
destruct p;
congruence.
destruct ad;
simpl;
destruct a;
inv U;
destruct b;
inv H1;
clarify;
destruct p;
congruence.
Qed.
Lemma match_eval_op {
op args args'
sp v} :
INJECT.ok_op op →
Val.lessdef_list args args' →
Op.eval_operation ge sp op args =
Some v →
∃
v',
Op.eval_operation tge sp op args' =
Some v'
∧
Val.lessdef v v'.
Proof.
destruct op;
clarify;
intros _;
unfold Op.eval_operation.
destruct args as [|
a [|]];
clarify.
intros K;
inv K.
intros K;
inv K.
inv H3.
eexists;
intuition.
destruct args as [|];
clarify.
inversion 1.
inversion 1.
eexists;
intuition.
destruct args as [|
a [|]];
clarify;
destruct a;
clarify.
inversion 1;
inversion 1.
inv H4.
inv H2.
eexists;
intuition.
destruct args as [|
a [|]];
clarify;
destruct a;
clarify.
inversion 1;
inversion 1.
inv H4.
inv H2.
eexists;
intuition.
destruct args as [|
a [|]];
clarify;
destruct a;
clarify.
inversion 1;
inversion 1.
inv H4.
inv H2.
eexists;
intuition.
destruct args as [|
a [|]];
clarify;
destruct a;
clarify.
inversion 1.
intros K.
bif2.
inv H4.
inv H2.
eexists;
intuition.
eauto using @
match_eval_addressing.
case_eq (
Op.eval_condition c args).
intros []
H K L;
clarify;
rewrite (
Op.eval_condition_lessdef _ K H);
eauto.
clarify.
Qed.
Definition only_int :
RTL.regset →
Prop :=
fun rs => ∀
r,
Val.has_type (
rs #
r)
Ast.Tint.
Lemma only_int_update rs v r :
only_int rs →
Val.has_type v Ast.Tint →
only_int (
rs #
r <-
v).
Proof.
intros I V r'.
case (peq r r'). intros ->. now rewrite Regmap.gss.
intros K. rewrite Regmap.gso. apply I. congruence.
Qed.
Hint Resolve only_int_update.
Lemma eval_op_int {
rs'
sp op args v} :
only_int rs' →
INJECT.ok_op op →
Op.eval_operation tge sp op (
rs' ##
args) =
Some v →
Val.has_type v Ast.Tint.
Proof.
intros INTS.
destruct op;
clarify;
intros _;
try now destruct args as [|
x [|]];
clarify;
simpl;
inversion 1.
destruct args as [|
x [|]];
clarify;
simpl.
now destruct (
rs' #
x);
inversion 1.
now destruct (
rs' #
x);
inversion 1.
now destruct args as [|
x [|]];
clarify;
simpl;
destruct (
rs' #
x);
inversion 1.
now destruct args as [|
x [|]];
clarify;
simpl;
destruct (
rs' #
x);
inversion 1.
destruct args as [|
x [|]];
clarify;
simpl;
destruct (
rs' #
x);
clarify;
intros;
bif2.
destruct a;
simpl;
destruct args as [|? [|? ()]];
simpl;
clarify;
try (
now destruct (
rs' #
p)
as [| | |()];
inversion 1);
try (
destruct (
rs' #
p)
as [| | |()];
clarify;
destruct (
rs' #
p0)
as [| | |()];
clarify;
inversion 1;
auto).
destruct (
Genv.find_symbol tge i);
inversion 1;
auto.
destruct (
rs' #
p);
clarify.
destruct (
Genv.find_symbol tge i);
inversion 1;
auto.
destruct (
rs' #
p);
clarify.
destruct (
Genv.find_symbol tge i0);
inversion 1;
auto.
destruct sp;
inversion 1;
auto.
destruct c;
simpl;
destruct args as [|
x [|
y ()]];
simpl;
clarify;
destruct (
rs' #
x);
simpl;
clarify;
try (
destruct (
rs' #
y);
simpl;
clarify);
try (
now destruct (
Op.eval_compare_null c i)
as [()|];
inversion 1;
auto);
try (
intros;
bif2).
now destruct (
Val.option_bool_of_bool3 (
Pointers.Ptr.cmp c p p0))
as [()|];
inversion 1.
now destruct (
Val.option_bool_of_bool3 (
Pointers.Ptr.cmpu c p p0))
as [()|];
inversion 1.
Qed.
Inductive match_stack_frame :
stack_frame →
stackframe →
Prop :=
|
MSF res rs rs'
c c'
sp pc
(
INTS:
only_int rs')
(
REGS:
match_regset rs rs')
(
CODE:
match_code bi c c')
:
match_stack_frame (
mksf res c sp pc rs) (
Stackframe (
xO res)
c'
sp pc rs').
Definition match_stack :
stack →
list stackframe →
Prop :=
list_forall2 match_stack_frame.
Inductive tr_cont (
c:
RTL.code) (
exit:
node) (
dst:
list reg) :
INJECT.continuation →
node →
node →
Prop :=
|
TKstmt s k ns nk nd
(
TKS:
tr_stmt bi c s ns dst exit nk)
(
TKK:
tr_cont c exit dst k nk nd)
:
tr_cont c exit dst (
INJECT.Kstmt s k)
ns nd
|
TKend nd
:
tr_cont c exit dst INJECT.Kend nd nd
.
Inductive match_state :
RTLinject.intra_state →
RTL.state →
Prop :=
|
MSCS stk stk'
f f'
args args'
(
STK:
match_stack stk stk')
(
FD:
match_fundef f f')
(
ARGS:
Val.lessdef_list args args')
(
INTS: ∀
a,
In a args' →
Val.has_type a Ast.Tint)
:
match_state (
RICallState stk f args) (
Callstate stk'
f'
args')
|
MSBS stk stk'
sg
(
STK:
match_stack stk stk')
:
match_state (
RIBlockedState stk sg) (
Blockedstate stk'
sg)
|
MSRS stk stk'
res res'
(
STK:
match_stack stk stk')
(
RES:
Val.lessdef res res')
(
INT:
Val.has_type res'
Ast.Tint)
:
match_state (
RIRetState stk res) (
Returnstate stk'
res')
|
MSS stk stk'
c c'
sp pc rs rs'
(
STK:
match_stack stk stk')
(
CODE:
match_code bi c c')
(
REGS:
match_regset rs rs')
(
INTS:
only_int rs')
:
match_state (
RIState stk c sp pc rs) (
State stk'
c'
sp pc rs')
|
MSI stk stk'
c c'
sp pc pc'
rs rs'
dst irs is ik nk
(
STK:
match_stack stk stk')
(
CODE:
match_code bi c c')
(
REGS:
match_regset rs rs')
(
IREGS:
match_inject_regset irs rs')
(
INTS:
only_int rs')
(
TS:
tr_stmt bi c'
is pc' (
map xO dst)
pc nk)
(
TK:
tr_cont c'
pc (
map xO dst)
ik nk pc)
:
match_state (
RIInjectState stk c sp pc rs dst (
INJECT.NormalState irs is ik))
(
State stk'
c'
sp pc'
rs')
.
Section M.
Import INJECT.
Open Scope nat_scope.
Fixpoint measure_stmt (
stmt:
statement) :
nat :=
match stmt with
|
Sskip
|
Sreturn _ => 1
|
Sfreeperm
|
Leak _ _ _
|
Sop _ _ _
|
Sload _ _ _ _
|
Sstore _ _ _ _ _
|
Satomicmem _ _ _ _
|
Sfence false
|
Srequestperm _ _ _
|
Sabort _ false _
|
Sassume _ _
|
Srelease
=> 2
|
Sabort _ true _
|
Sfence true
=> 3
|
Sseq s s'
|
Sbranch s s'
|
Sifthenelse _ _ s s' => 1 +
measure_stmt s +
measure_stmt s'
|
Satomic _ s
|
Sloop s
|
Swhile _ _ s => 1 +
measure_stmt s
|
Srepeat s _ _ => 3 +
measure_stmt s +
measure_stmt s
end.
Fixpoint measure_cont (
k:
continuation) :
nat :=
match k with
|
Kstmt s k' =>
measure_stmt s +
measure_cont k'
|
Kendatomic _ k' =>
measure_cont k'
|
Kend =>
O
end.
Definition measure_state (
s:
state) :
nat :=
match s with
|
NormalState _ s k =>
measure_stmt s +
measure_cont k
|
ReturnState =>
O
end.
End M.
Definition measure_intra_state (
s:
RTLinject.intra_state) :
nat :=
match s with
|
RIInjectState _ _ _ _ _ _ is =>
measure_state is
|
_ =>
O
end.
Definition inject_order :
RTLinject.intra_state →
RTLinject.intra_state →
Prop :=
ltof _ measure_intra_state.
Lemma inject_order_wf :
well_founded inject_order.
Proof.
Lemma begin_inject_inv stk'
c'
sp :
forall {
nd args param ns},
tr_init c'
ns args param nd →
∀
rs',
taustar tlts (
State stk'
c'
sp ns rs')
(
State stk'
c'
sp nd (
fold_left2 (
fun q p a =>
q # (
xI p) <- (
q # (
xO a)))
rs'
param args)).
Proof.
induction 1. simpl. intros; left.
intros rs'. simpl.
eright. simpl. eapply exec_Iop; eauto. simpl. reflexivity.
now apply IHtr_init.
Qed.
Lemma begin_inject_match_reg rs :
∀
args param rs',
match_regset rs rs' →
match_regset rs (
fold_left2 (
fun q p a =>
q # (
xI p) <- (
q # (
xO a)))
rs'
param args).
Proof.
induction args. destruct param; easy.
intros [|p param]. easy.
intros rs' H. eapply IHargs.
intros r. now rewrite Regmap.gso.
Qed.
Lemma begin_inject_match_ireg rs :
∀
args param rs',
∀
acc acc',
match_regset rs rs' →
match_regset rs acc' →
match_inject_regset acc acc' →
match_inject_regset (
fold_left2 upd acc param (
map rs args))
(
fold_left2 (
fun q p a =>
q # (
xI p) <- (
q # (
xO a)))
acc'
param args).
Proof.
induction args.
now intros [|] rs' acc acc' ? ? ?; simpl.
intros [|p param] rs' acc acc' REGS RS ACC. easy.
simpl. eapply IHargs. eassumption.
intros r'. now rewrite Regmap.gso.
intros r'.
unfold upd. eq_case. intros ->. rewrite Regmap.gss. auto.
intros K. rewrite Regmap.gso. auto. congruence.
Qed.
Lemma begin_inject_only_int :
∀
args param rs',
only_int rs' →
only_int (
fold_left2 (
fun q p a =>
q # (
xI p) <- (
q # (
xO a)))
rs'
param args).
Proof.
induction args.
intros [];
easy.
intros [|
p param]
rs'
H.
easy.
simpl.
apply IHargs.
intros r.
case (
peq r (
xI p)).
intros ->.
rewrite Regmap.gss.
apply H.
intros K.
rewrite Regmap.gso.
eapply H.
exact K.
Qed.
Lemma end_inject_inv stk'
c'
sp :
forall {
ns res dst ne nd},
res ≠
nil →
tr_stmt bi c' (
INJECT.Sreturn res)
ns dst ne nd →
∀
rs',
∃
t,
stepr tlts (
State stk'
c'
sp ns rs')
Events.TEtau t
∧
taustar tlts t
(
State stk'
c'
sp ne (
fold_right2 (
fun q p a =>
q #
p <- (
q # (
xI a)))
rs'
dst res)).
Proof.
induction res.
clarify.
intros [|
d dst]
ne nd _ H rs';
inv H.
destruct res as [|
r res];
inv RET.
simpl.
eexists.
split;[|
left].
eapply exec_Iop;
eauto.
simpl.
reflexivity.
simpl.
assert (
r::
res ≠
nil)
as Q by discriminate.
assert (
tr_stmt bi c' (
INJECT.Sreturn (
r::
res))
ns (
t::
tgtl)
ns0 nd)
as K by vauto.
destruct (
IHres _ _ _ Q K rs')
as (
s &
Hs &
Hss).
exists s.
intuition.
eapply taustar_trans.
eassumption.
eright.
simpl.
eapply exec_Iop;
eauto.
simpl.
reflexivity.
left.
Qed.
Lemma end_inject_match_reg rs irs rs':
match_regset rs rs' →
match_inject_regset irs rs' →
∀
res dst,
match_regset (
reg_upd rs dst (
map irs res))
(
fold_right2 (
fun q p a =>
q #
p <- (
q # (
xI a)))
rs' (
map xO dst)
res).
Proof.
intros REGS IREGS.
induction res; intros [|d dst]; simpl; try easy.
intros r'. unfold reg_upd. simpl. unfold upd at 1.
eq_case. intros ->. rewrite Regmap.gss.
clear -IREGS. generalize dependent dst.
induction res; intros [|d dst]; try easy.
simpl. rewrite Regmap.gso. intuition. congruence.
intros K. rewrite Regmap.gso. apply IHres. congruence.
Qed.
Lemma end_inject_only_int rs':
only_int rs' →
∀
res dst,
only_int (
fold_right2 (
fun q p a =>
q #
p <- (
q # (
xI a)))
rs' (
map xO dst)
res).
Proof.
intros INTS.
induction res;
intros [|
d dst];
simpl;
try assumption.
intros r'.
case (
peq r' (
xO d)).
intros ->.
rewrite Regmap.gss.
apply IHres.
intros K.
rewrite Regmap.gso.
apply IHres.
exact K.
Qed.
Lemma fw_sim :
forward_sim_with_undefs2 lts tlts match_state inject_order.
Proof.
intros s t l s'
SSTEP MS.
inv SSTEP;
inv STEP;
inv MS;
simpl in TE;
clarify;
try pose proof (
CODE _ _ PC)
as PC'.
right;
right.
eexists.
split;
vauto.
eexists;
eexists;
split.
left.
split;[|
left].
inv PC';
vauto.
pose proof (
Op.eval_condition_lessdef _ (
match_args_lessdef REGS _)
COND)
as COND'.
right;
right.
eexists.
split;
vauto.
eexists;
eexists;
split.
left.
split;[|
left].
inv PC';
vauto.
pose proof (
Op.eval_condition_lessdef _ (
match_args_lessdef REGS _)
COND)
as COND'.
right;
right.
eexists.
split;
vauto.
eexists;
eexists;
split.
left.
split;[|
left].
inv PC';
vauto.
inv PC'.
pose proof (
match_eval_op OKOP (
match_args_lessdef REGS args)
OP)
as (
v' &
K1 &
K2).
right;
right.
eexists.
split;
vauto.
eexists;
eexists;
split.
left.
split;[|
left].
vauto.
econstructor;
eauto.
intros r.
case (
peq r (
xO res)).
intros ->.
rewrite Regmap.gss.
apply (
eval_op_int INTS OKOP K1).
intros K.
now rewrite Regmap.gso.
assert (
rs' # (
xO fp) =
Vptr pfp).
pose proof (
REGS fp)
as K;
rewrite FP in K.
now inv K.
right.
eexists.
exists (
rs' # (
xO arg)::
nil).
split.
vauto.
split.
eexists.
eexists.
split.
left.
split;[|
left].
inv PC';
vauto.
vauto.
destruct (
match_find_function REGS _ _ FUNC)
as (
fd' &
Hfd' &
K).
inv K.
right;
right.
eexists.
split;
vauto.
eexists;
eexists;
split.
left.
split;[|
left].
now inv PC';
vauto.
econstructor;
vauto.
now eapply match_args_lessdef.
clear -
INTS.
induction args;
simpl.
intuition.
intros v [<-|
H].
apply INTS.
intuition.
right;
right.
eexists.
split;
vauto.
eexists;
eexists;
split.
left.
split;[|
left].
now inv PC';
vauto.
econstructor;
vauto.
now eapply match_args_lessdef.
clear -
INTS.
induction args;
simpl.
intuition.
intros v [<-|
H].
apply INTS.
intuition.
inv FD.
right.
eexists.
split;
vauto.
eexists;
eexists;
split.
left.
split;[|
left].
vauto.
econstructor;
eauto.
now apply match_init_regs.
simpl.
clear -
INTS.
generalize dependent args'.
induction param.
intros args'
H r.
simpl.
rewrite Regmap.gi.
easy.
intros [|
x args].
simpl.
intros _ r;
simpl;
rewrite Regmap.gi;
easy.
simpl.
intros H r.
case (
peq r (
xO a)).
intros ->.
now rewrite Regmap.gss;
intuition.
intros K.
rewrite Regmap.gso.
apply IHparam.
intros y A.
apply H.
intuition.
intuition.
inv FD.
right;
right.
eexists.
split;
vauto.
eexists;
eexists;
split.
left.
split;[|
left].
vauto.
econstructor;
eauto.
now apply match_init_regs.
simpl.
clear -
INTS.
generalize dependent args'.
induction param;
simpl.
intros ?
_ r.
now rewrite Regmap.gi.
intros [|
x args']
INTS.
intros r;
now rewrite Regmap.gi.
intros r.
case (
peq r (
xO a)).
intros ->.
rewrite Regmap.gss.
intuition.
intros K.
rewrite Regmap.gso;
intuition.
apply IHparam.
intros v H.
apply INTS.
intuition.
inv FD.
right.
eexists.
split;
vauto.
eexists;
eexists;
split.
left.
split;[|
left].
econstructor;
eauto.
clear -
ARGS.
generalize dependent args'.
induction eargs.
simpl in *.
now inversion 1.
intros args'
ARGS.
inv ARGS.
simpl.
f_equal.
now inv H1.
now intuition.
right.
eexists.
split;
vauto.
eexists;
eexists;
split.
left.
split;[|
left].
econstructor;
eauto.
destruct sg.(
Ast.sig_res);
congruence.
inv STK.
inv H1.
right;
right.
eexists.
split;
vauto.
eexists;
eexists;
split.
left.
split;[|
left].
vauto.
simpl.
econstructor;
eauto.
inv STK.
right.
eexists.
split;
vauto.
eexists;
eexists;
split.
left.
split;[|
left].
vauto.
right.
eexists.
split;
vauto.
eexists;
eexists;
split.
left.
split;[|
left].
change (
rs' # (
xO res))
with (
regmap_optget (
Some (
xO res))
Vundef rs').
inv PC'.
vauto.
right;
right.
eexists.
split;
vauto.
eexists;
eexists;
split.
left.
split;[|
left].
change (
rs' # (
xO res))
with (
regmap_optget (
Some (
xO res))
Vundef rs').
inv PC'.
vauto.
right;
right.
inv PC'.
pose proof (
begin_inject_inv stk'
c'
sp INIT rs')
as INIT'.
eexists.
split.
eexists;
eexists.
split.
left.
split. 2:
apply INIT'.
vauto.
econstructor;
eauto.
now apply begin_inject_match_reg.
eapply begin_inject_match_ireg;
eauto.
vauto.
now apply begin_inject_only_int.
vauto.
destruct is0.
inv TS.
inv INJECT. 2:
inv TK. 2:
eelim EV;
reflexivity.
simpl in TE;
inv TE.
clear EV.
right;
left.
split.
unfold inject_order,
ltof.
simpl.
auto with arith.
inv TK.
vauto.
inv INJECT.
simpl in TE;
inv TE;
clear EV.
inv TS.
right;
left.
split.
unfold inject_order,
ltof.
simpl.
auto with arith.
vauto.
now elim OK_BI.
Hint Constructors tr_stmt.
inv TS.
inv INJECT.
simpl in TE;
inv TE.
clear EV.
destruct (
match_eval_op OP (
match_iargs_lessdef IREGS args)
H6)
as (
v' &
Hv' &
Hvv').
right;
right.
eexists.
split.
eexists;
eexists.
split.
left.
split;[|
left].
vauto.
econstructor;
eauto.
intros r.
case (
peq r (
xI dst0)).
intros ->.
rewrite Regmap.gss.
apply (
eval_op_int INTS OP Hv').
intros K.
now rewrite Regmap.gso.
inv TS.
inv INJECT.
simpl in TE;
inv TE.
clear EV.
pose proof (
match_eval_addressing (
match_iargs_lessdef IREGS args)
H8).
right.
eexists.
split.
eexists;
eexists.
split.
left.
split;[|
left].
vauto.
intros v'
Hvv'.
eexists.
split.
simpl.
econstructor.
eapply RTLI_inject_step with (
ev :=
INJECT.TEtso (
INJECT.TSOmem (
INJECT.MEread ap inbuf a v'))).
econstructor;
vauto.
destruct v';
trivial;
inv Hvv'.
solve by inversion.
congruence.
easy.
reflexivity.
econstructor;
eauto.
inv TS.
inv INJECT.
simpl in TE;
inv TE.
clear EV.
pose proof (
match_eval_addressing (
match_iargs_lessdef IREGS args)
H8).
right.
eexists.
exists (
Events.cast_value_to_chunk Ast.Mint32 (
rs' # (
xI dst0))).
split.
generalize (
IREGS dst0).
destruct (
irs dst0);
inversion 1;
clarify.
split.
eexists;
eexists.
split.
left.
split;[|
left].
red.
red.
eapply exec_Istore;
eauto.
simpl.
generalize (
INTS (
xI dst0)).
now destruct (
rs' # (
xI dst0)).
vauto.
inv TS.
inv INJECT.
inv ASME;
simpl in TE;
inv TE;
clear EV.
destruct args as [|
q [|
r [|
s [|]]]];
clarify.
simpl in *;
clarify.
right.
eexists.
split.
eexists;
eexists.
split.
left.
split;[|
left].
simpl.
eapply exec_Iatomic.
eassumption.
simpl.
generalize (
IREGS q).
destruct (
irs q);
clarify;
inversion 1.
generalize (
IREGS r).
destruct (
irs r);
clarify;
inversion 1;
generalize (
IREGS s);
destruct (
irs s);
clarify;
inversion 1;
vauto.
reflexivity.
assumption.
intros v'
Hv'.
eexists.
split.
econstructor;
eauto.
econstructor;
eauto.
econstructor.
simpl.
rewrite <-
H2.
eapply INJECT.atomic_statement_mem_event_cas with (
v:=
v');
eauto.
reflexivity.
destruct v';
clarify.
inv Hv'.
inv HTv.
discriminate.
reflexivity.
econstructor;
eauto.
inv TS.
inv INJECT.
simpl in TE;
inv TE.
clear EV.
right.
eexists.
split.
eexists;
eexists.
split.
left.
split;[|
left].
vauto.
vauto.
destruct l;
try destruct ev;
clarify.
right.
eexists.
split.
eexists;
eexists.
split.
left.
split;[|
left].
vauto.
vauto.
inv TS.
inv INJECT;
simpl in TE;
inv TE;
clear EV;
pose proof (
Op.eval_condition_lessdef _ (
match_iargs_lessdef IREGS _)
H7)
as COND'.
right;
right.
eexists.
split.
eexists;
eexists.
split.
left.
split;[|
left].
vauto.
vauto.
right;
right.
eexists.
split.
eexists;
eexists.
split.
left.
split;[|
left].
vauto.
vauto.
inv TS.
inv INJECT;
simpl in TE;
inv TE;
clear EV;
pose proof (
Op.eval_condition_lessdef _ (
match_iargs_lessdef IREGS _)
H6)
as COND'.
right;
right.
eexists.
split.
eexists;
eexists.
split.
left.
split;[|
left].
vauto.
econstructor;
eauto.
vauto.
right;
right.
eexists.
split.
eexists;
eexists.
split.
left.
split;[|
left].
vauto.
econstructor;
eauto.
vauto.
inv INJECT;
simpl in TE;
inv TE;
clear EV.
right;
left.
split.
unfold inject_order,
ltof.
simpl.
zify.
omega.
inv TS.
econstructor;
eauto.
inv TS.
inv INJECT;
simpl in TE;
inv TE;
clear EV.
right;
left.
split.
unfold inject_order,
ltof.
simpl.
zify.
omega.
vauto.
inv INJECT.
eelim EV;
reflexivity.
simpl in LOW.
now apply False_ind.
inv INJECT.
eelim EV;
reflexivity.
simpl in TE;
clarify.
simpl in LOW.
now apply False_ind.
inv INJECT;
simpl in TE;
inv TE.
right;
left.
split.
unfold inject_order,
ltof.
simpl.
auto with arith.
inv TS.
vauto.
simpl in LOW.
now apply False_ind.
simpl in LOW.
now apply False_ind.
inv INJECT;
simpl in TE;
inv TE.
right;
left.
split.
unfold inject_order,
ltof.
simpl.
auto with arith.
inv TS.
vauto.
inv INJECT;
simpl in TE;
inv TE.
right;
left.
split.
unfold inject_order,
ltof.
simpl.
auto with arith.
inv TS.
vauto.
inv INJECT;
simpl in TE;
inv TE.
right;
left.
split.
unfold inject_order,
ltof.
simpl.
auto with arith.
inv TS.
vauto.
inv INJECT.
destruct res0 as [|
r res].
right;
left.
inv TS.
split.
unfold inject_order,
ltof.
simpl.
intuition.
econstructor;
eauto.
destruct dst;
clarify.
right;
right.
assert (
r::
res ≠
nil)
as Q by discriminate.
pose proof (
end_inject_inv stk'
c'
sp Q TS rs')
as (
t &
Ht).
eexists.
split.
eexists;
eexists.
split.
left.
apply Ht.
econstructor;
eauto.
apply end_inject_match_reg;
eauto.
apply end_inject_only_int;
eauto.
left.
eapply ev_stuck_or_error_error;
vauto.
left.
eapply ev_stuck_or_error_error;
vauto.
Qed.
Definition bsim_rel := @
bsr _ lts tlts match_state.
Definition bsim_order := @
bsc _ tlts.
Lemma init_sim_succ:
forall {
p vals vals'
tinit},
rtl_init tge p vals =
Some tinit ->
Val.lessdef_list vals'
vals →
exists sinit,
rtl_inject_init ge p vals' =
Some sinit /\
bsim_rel tinit sinit.
Proof.
unfold rtl_inject_init,
rtl_init.
intros p vals vals'
tinit INIT LD.
destruct TRANSF as (
MG &
MF).
specialize MF with p.
repeat (
destruct Genv.find_funct_ptr;
clarify).
destruct f0.
2:
now inv MF.
pose proof (
transl_fundef_correct MF)
as K;
inv K;
clear MF.
simpl in *.
rewrite (
lessdef_list_length LD).
bif2.
eexists.
split.
reflexivity.
econstructor;
eauto.
split.
econstructor;
vauto.
3:
left;
left.
generalize (
Ast.sig_args sg).
clear -
LD.
induction LD.
induction l;
simpl;
vauto.
induction l;
simpl;
vauto.
econstructor;
eauto.
now apply Val.conv_lessdef.
clear -
SIG.
generalize dependent SIG.
generalize (
Ast.sig_args sg).
clear sg.
induction vals.
induction l;
simpl;
intuition.
subst;
vauto.
destruct l;
simpl.
intuition.
intros SIG v [
K|
K].
assert (
t =
Ast.Tint)
as ->.
now apply SIG;
left.
destruct a;
simpl in K;
subst;
vauto.
apply (
IHvals l).
intuition.
exact K.
Qed.
Lemma init_sim_fail:
forall p vals vals',
rtl_init tge p vals =
None ->
Val.lessdef_list vals'
vals →
rtl_inject_init ge p vals' =
None.
Proof.
unfold rtl_inject_init,
rtl_init.
intros p vals vals'
INIT LD.
destruct TRANSF as (
MG &
MF).
specialize MF with p.
repeat (
destruct Genv.find_funct_ptr;
clarify).
destruct f0.
pose proof (
transl_fundef_correct MF)
as K;
inv K;
clear MF.
simpl in *.
rewrite (
lessdef_list_length LD).
bif2.
reflexivity.
Qed.
End SIM.
Ltac bind_inv :=
match goal with
| [
H:
bind ?
f ?
g =
OK ?
y |-
_] =>
destruct (
bind_inversion f g H)
as
(? & ?
Hbind & ?
Hbind' );
clear H
end.
Theorem rtlgen_sim :
Sim.sim RtlInjectSem rtl_sem match_prg.
Proof.
eapply (
TSOsim_with_undefs.sim RtlInjectSem rtl_sem genv_rel
bsim_rel (
fun _ =>
bsim_order));
unfold match_prg;
simpl;
intros.
destruct GENVR as [
GR FR].
rewrite GR.
now rewrite (
Ast.transform_partial_program_main _ _ MP).
eapply Genv.exists_matching_genv_and_mem_rev
with (
match_var :=
fun a b =>
a =
b),
INIT.
eby eapply Ast.transform_partial_program_match.
apply (
init_sim_succ _ _ GENVR INIT LD).
apply (
init_sim_fail _ _ GENVR _ _ _ INITF LD).
apply forward_to_backward_sim_with_undefs with (
fsc:=
inject_order).
apply rtli_receptive.
apply rtl_sem.(
TSOmachine.SEM_determinate).
simpl.
intros s.
destruct (
classic (∃
l, ∃
s',
rtl_step'
sge s l s'))
as [
K|
K].
now right.
left.
intros s'
l K'.
apply K.
exists l;
exists s'.
assumption.
apply Events.ldo_samekind_eq.
apply Events.ldo_not_tau.
apply Events.ldi_refl.
split.
exact inject_order_wf.
apply mk_forward_sim_with_undefs.
exact inject_order_wf.
now apply fw_sim.
Qed.
End CORRECT.