Require Import Coqlib List Maps Integers Errors.
Import ListNotations.
Require Import AST Linking Smallstep.
Require Import Globalenvs Values.
Require Import Op Registers Memory RTL.
Require Import CounterMeasures ExpandObserve.
Definition match_prog (
prog tprog:
program) :=
match_program (
fun cunit f tf =>
tf =
transf_fundef f)
eq prog tprog.
Lemma transf_program_match:
forall p,
match_prog p (
transf_program p).
Proof.
Section Expand.
Variable prog:
program.
Variable tprog:
program.
Hypothesis TRANSL:
match_prog prog tprog.
Let ge :=
Genv.globalenv prog.
Let tge :=
Genv.globalenv tprog.
Static properties
Lemma sig_preserved:
forall f,
funsig (
transf_fundef f) =
funsig f.
Proof.
intros []; simpl; auto.
Qed.
Lemma fn_sig_preserved:
forall f,
fn_sig (
transf_function f) =
fn_sig f.
Proof.
intros []; simpl; auto.
Qed.
Lemma params_preserved:
forall f,
fn_params (
transf_function f) =
fn_params f.
Proof.
reflexivity. Qed.
Lemma stacksize_preserved:
forall f,
fn_stacksize (
transf_function f) =
fn_stacksize f.
Proof.
reflexivity. Qed.
Lemma symbols_preserved:
forall id,
Genv.find_symbol tge id =
Genv.find_symbol ge id.
Proof.
Lemma senv_preserved:
Senv.equiv ge tge.
Proof.
Lemma functions_translated:
forall v f,
Genv.find_funct ge v =
Some f ->
Genv.find_funct tge v =
Some (
transf_fundef f).
Proof.
Lemma function_ptr_translated:
forall v f,
Genv.find_funct_ptr ge v =
Some f ->
Genv.find_funct_ptr tge v =
Some (
transf_fundef f).
Proof.
Lemma find_function_translated:
forall ros rs fd,
find_function ge ros rs =
Some fd ->
find_function tge ros rs =
Some (
transf_fundef fd).
Proof.
Opaque CounterMeasures.transf_function.
Lemma transf_function_entry:
forall f,
(
fn_code (
transf_function f))!(
fn_entrypoint (
transf_function f)) =
Some (
Inop (
fn_entrypoint f)).
Proof.
Lemma transf_function_correct:
forall f pc i,
f.(
fn_code)!
pc =
Some i ->
exists abort e seq cont,
transf_instr
transf_nop_default transf_op_default
transf_load_default transf_store_default
transf_call_default transf_tailcall_default
transf_builtin
transf_cond_default
transf_jumptable_default transf_return_default
pc i =
existT _
e (
seq,
cont)
/\
spec_seq abort (
fn_code (
transf_function f))
pc seq cont.
Proof.
Simulation invariant
Definition match_regs (
rs rs' :
regset) :=
forall r,
rs'#
r =
rs#
r.
Inductive match_stacks:
list RTL.stackframe ->
list RTL.stackframe ->
Prop :=
|
match_frames_nil:
match_stacks nil nil
|
match_frames_cons:
forall tail tail' res f sp pc rs rs'
(
REG_OK : (
res <=
max_reg_function f)%
positive)
(
REGS:
forall v,
match_regs (
rs #
res <-
v) (
rs' #
res <-
v))
(
TAIL:
match_stacks tail tail'),
match_stacks
((
Stackframe res f sp pc rs) ::
tail)
((
Stackframe res (
transf_function f)
sp pc rs') ::
tail').
Inductive match_states:
RTL.state ->
RTL.state ->
Prop :=
|
match_regular_states:
forall stk stk' f sp pc rs rs' m
(
STACKS:
match_stacks stk stk')
(
REGS :
match_regs rs rs'),
match_states (
State stk f sp pc rs m)
(
State stk' (
transf_function f)
sp pc rs' m)
|
match_callstates:
forall stk stk' f args m
(
STACKS:
match_stacks stk stk'),
match_states (
Callstate stk f args m)
(
Callstate stk' (
transf_fundef f)
args m)
|
match_returnstates:
forall stk stk' v m
(
STACKS:
match_stacks stk stk'),
match_states (
Returnstate stk v m)
(
Returnstate stk' v m).
Lemma match_regs_assign :
forall rs rs' res v,
match_regs rs rs' ->
match_regs (
rs #
res <-
v) (
rs' #
res <-
v).
Proof.
Initial state
Lemma transf_initial_states:
forall st1,
initial_state prog st1 ->
exists st2,
initial_state tprog st2 /\
match_states st1 st2.
Proof.
Final state
Lemma transf_final_states:
forall st1 st2 r
(
MATCH :
match_states st1 st2)
(
FINAL :
final_state st1 r),
final_state st2 r.
Proof.
intros. inv FINAL. inv MATCH. inv STACKS.
constructor.
Qed.
Step simulation
Lemma eval_builtin_arg_match :
forall rs rs' sp m a v,
(
forall r,
In r (
params_of_builtin_arg a) ->
rs' #
r =
rs #
r) ->
Events.eval_builtin_arg ge (
fun r =>
rs #
r)
sp m a v ->
Events.eval_builtin_arg ge (
fun r =>
rs' #
r)
sp m a v.
Proof.
induction a; intros * INCL EVAL; inv EVAL; try econstructor; eauto.
1:{ replace (rs # x) with (rs' # x); [econstructor|].
apply INCL; simpl; auto. }
all:try eapply IHa1; try eapply IHa2; eauto.
all:intros; apply INCL; simpl; auto with datatypes.
Qed.
Lemma step_opaque_copies abort stk tf sp m :
forall args pc sig pc' cseq rs rs1',
concretized pc (
opaque_copies sig args) (
COneExit pc')
cseq ->
spec_cseq abort (
fun _ =>
True)
NoPred (
fn_code tf)
cseq ->
match_regs rs rs1' ->
exists rs2',
plus step tge (
State stk tf sp pc rs1' m)
Events.E0 (
State stk tf sp pc' rs2' m)
/\
match_regs rs rs2'.
Proof.
induction args as [|?];
intros *
CONC SPEC REGS;
simpl in *.
1,2:
repeat inv_transf_function.
-
do 2
esplit; [
eapply plus_one|
eauto].
+
eapply exec_Inop;
eauto.
-
edestruct IHargs with (
rs:=
rs) (
rs1':=
rs1' #
a <- (
rs1' #
a))
as (
rs'&
PLUS&
MATCHR);
eauto.
+
intros ?.
rewrite Regmap.gsident.
auto.
+
do 2
esplit; [
eapply plus_left';
eauto|
auto].
*
eapply exec_Iop;
eauto.
*
now rewrite <-
Events.Eapp_E0.
Qed.
Lemma step_simulation:
forall s1 t s2 (
STEP :
step ge s1 t s2)
s1' (
MS:
match_states s1 s1'),
exists s2',
plus step tge s1' t s2' /\
match_states s2 s2'.
Proof.
Correctness theorem
Theorem transf_program_correct:
forward_simulation (
semantics prog) (
semantics tprog).
Proof.
End Expand.