Inductive match_cont: composite_env -> type -> nat -> nat -> Clight.cont -> Csharpminor.cont -> Prop :=
| match_Kstop: forall ce tyret nbrk ncnt,
match_cont tyret ce nbrk ncnt Clight.Kstop Kstop
| match_Kseq: forall ce tyret nbrk ncnt s k ts tk,
transl_statement ce tyret nbrk ncnt s = OK ts ->
match_cont ce tyret nbrk ncnt k tk ->
match_cont ce tyret nbrk ncnt
(Clight.Kseq s k)
(Kseq ts tk)
| match_Kloop1: forall ce tyret s1 s2 k ts1 ts2 nbrk ncnt tk,
transl_statement ce tyret 1%nat 0%nat s1 = OK ts1 ->
transl_statement ce tyret 0%nat (S ncnt) s2 = OK ts2 ->
match_cont ce tyret nbrk ncnt k tk ->
match_cont ce tyret 1%nat 0%nat
(Clight.Kloop1 s1 s2 k)
(Kblock (Kseq ts2 (Kseq (Sloop (Sseq (Sblock ts1) ts2)) (Kblock tk))))
| match_Kloop2: forall ce tyret s1 s2 k ts1 ts2 nbrk ncnt tk,
transl_statement ce tyret 1%nat 0%nat s1 = OK ts1 ->
transl_statement ce tyret 0%nat (S ncnt) s2 = OK ts2 ->
match_cont ce tyret nbrk ncnt k tk ->
match_cont ce tyret 0%nat (S ncnt)
(Clight.Kloop2 s1 s2 k)
(Kseq (Sloop (Sseq (Sblock ts1) ts2)) (Kblock tk))
| match_Kswitch: forall ce tyret nbrk ncnt k tk,
match_cont ce tyret nbrk ncnt k tk ->
match_cont ce tyret 0%nat (S ncnt)
(Clight.Kswitch k)
(Kblock tk)
| match_Kcall: forall ce tyret nbrk ncnt nbrk' ncnt' f e k id tf te le tk cu,
linkorder cu prog ->
transl_function cu.(prog_comp_env) f = OK tf ->
match_env e te ->
match_cont cu.(prog_comp_env) (Clight.fn_return f) nbrk' ncnt' k tk ->
match_cont ce tyret nbrk ncnt
(Clight.Kcall id f e le k)
(Kcall id tf te le tk).
Inductive match_states: Clight.state -> Csharpminor.state -> Prop :=
| match_state:
forall f nbrk ncnt s k e le m tf ts tk te ts' tk' cu
(LINK: linkorder cu prog)
(TRF: transl_function cu.(prog_comp_env) f = OK tf)
(TR: transl_statement cu.(prog_comp_env) (Clight.fn_return f) nbrk ncnt s = OK ts)
(MTR: match_transl ts tk ts' tk')
(MENV: match_env e te)
(MK: match_cont cu.(prog_comp_env) (Clight.fn_return f) nbrk ncnt k tk),
match_states (Clight.State f s k e le m)
(State tf ts' tk' te le m)
| match_callstate:
forall fd args k m tfd tk targs tres cconv cu ce
(LINK: linkorder cu prog)
(TR: match_fundef cu fd tfd)
(MK: match_cont ce Tvoid 0%nat 0%nat k tk)
(ISCC: Clight.is_call_cont k)
(TY: type_of_fundef fd = Tfunction targs tres cconv),
match_states (Clight.Callstate fd args k m)
(Callstate tfd args tk m)
| match_returnstate:
forall res k m tk ce
(MK: match_cont ce Tvoid 0%nat 0%nat k tk),
match_states (Clight.Returnstate res k m)
(Returnstate res tk m).
Remark match_states_skip:
forall f e le te nbrk ncnt k tf tk m cu,
linkorder cu prog ->
transl_function cu.(prog_comp_env) f = OK tf ->
match_env e te ->
match_cont cu.(prog_comp_env) (Clight.fn_return f) nbrk ncnt k tk ->
match_states (Clight.State f Clight.Sskip k e le m) (State tf Sskip tk te le m).
(** Commutation between label resolution and compilation *)
Section FIND_LABEL.
Variable ce: composite_env.
Variable lbl: label.
Variable tyret: type.

(* Specifications: *)
Lemma transl_find_label:
forall s nbrk ncnt k ts tk
(TR: transl_statement ce tyret nbrk ncnt s = OK ts)
(MC: match_cont ce tyret nbrk ncnt k tk),
match Clight.find_label lbl s k with
| None => find_label lbl ts tk = None
| Some (s', k') =>
exists ts', exists tk', exists nbrk', exists ncnt',
find_label lbl ts tk = Some (ts', tk')
/\ transl_statement ce tyret nbrk' ncnt' s' = OK ts'
/\ match_cont ce tyret nbrk' ncnt' k' tk'
end
with transl_find_label_ls:
forall ls nbrk ncnt k tls tk
(TR: transl_lbl_stmt ce tyret nbrk ncnt ls = OK tls)
(MC: match_cont ce tyret nbrk ncnt k tk),
match Clight.find_label_ls lbl ls k with
| None => find_label_ls lbl tls tk = None
| Some (s', k') =>
exists ts', exists tk', exists nbrk', exists ncnt',
find_label_ls lbl tls tk = Some (ts', tk')
/\ transl_statement ce tyret nbrk' ncnt' s' = OK ts'
/\ match_cont ce tyret nbrk' ncnt' k' tk'
end.