(** The following lemmas show that the translation from Mach to ARM preserves labels, in the sense that the following diagram commutes: << translation Mach code ------------------------ ARM instr sequence |                                          | | Mach.find_label lbl       find_label lbl | |                                          | v                                          v Mach code tail ------------------- ARM instr seq tail translation >> The proof demands many boring lemmas showing that ARM constructor functions do not introduce new labels. *)
Section TRANSL_LABEL.
Remark iterate_op_label:
forall op1 op2 l k,
(forall so, nolabel (op1 so)) ->
(forall so, nolabel (op2 so)) ->
tail_nolabel k (iterate_op op1 op2 l k).
Hint Resolve iterate_op_label: labels.
Remark loadimm_label:
forall r n k, tail_nolabel k (loadimm r n k).
Hint Resolve loadimm_label: labels.
Remark addimm_label:
forall r1 r2 n k, tail_nolabel k (addimm r1 r2 n k).
Hint Resolve addimm_label: labels.
Remark andimm_label:
forall r1 r2 n k, tail_nolabel k (andimm r1 r2 n k).
Hint Resolve andimm_label: labels.
Remark rsubimm_label:
forall r1 r2 n k, tail_nolabel k (rsubimm r1 r2 n k).
Hint Resolve rsubimm_label: labels.
Remark orimm_label:
forall r1 r2 n k, tail_nolabel k (orimm r1 r2 n k).
Hint Resolve orimm_label: labels.
Remark xorimm_label:
forall r1 r2 n k, tail_nolabel k (xorimm r1 r2 n k).
Hint Resolve xorimm_label: labels.
Remark indexed_memory_access_label:
forall mk_instr mk_immed base ofs k,
(forall r n, nolabel (mk_instr r n)) ->
tail_nolabel k (indexed_memory_access mk_instr mk_immed base ofs k).
Hint Resolve indexed_memory_access_label.
Remark loadind_label:
forall base ofs ty dst k c, loadind base ofs ty dst k = OK c -> tail_nolabel k c.
Remark storeind_label:
forall base ofs ty src k c, storeind src base ofs ty k = OK c -> tail_nolabel k c.
Remark save_lr_label:
forall ofs k, tail_nolabel k (save_lr ofs k).
Remark transl_cond_label:
forall cond args k c, transl_cond cond args k = OK c -> tail_nolabel k c.
Remark transl_op_label:
forall op args r k c, transl_op op args r k = OK c -> tail_nolabel k c.
Remark transl_memory_access_label:
forall (mk_instr_imm: ireg -> int -> instruction)
(mk_instr_gen: option (ireg -> shift_op -> instruction))
(mk_immed: int -> int)
(addr: addressing) (args: list mreg) c k,
transl_memory_access mk_instr_imm mk_instr_gen mk_immed addr args k = OK c ->
(forall r n, nolabel (mk_instr_imm r n)) ->
(match mk_instr_gen with
| None => True
| Some f => forall r sa, nolabel (f r sa)
end) ->
tail_nolabel k c.

(* Specifications: *)
Lemma transl_instr_label:
forall f i ep k c,
transl_instr f i ep k = OK c ->
match i with Mlabel lbl => c = Plabel lbl :: k | _ => tail_nolabel k c end.
Lemma transl_instr_label':
forall lbl f i ep k c,
transl_instr f i ep k = OK c ->
find_label lbl c = if Mach.is_label lbl i then Some k else find_label lbl k.
Lemma transl_code_label:
forall lbl f c ep tc,
transl_code f c ep = OK tc ->
match Mach.find_label lbl c with
| None => find_label lbl tc = None
| Some c' => exists tc', find_label lbl tc = Some tc' /\ transl_code f c' false = OK tc'
end.
Lemma transl_find_label:
forall lbl f tf,
transf_function f = OK tf ->
match Mach.find_label lbl f.(Mach.fn_code) with
| None => find_label lbl (fn_code tf) = None
| Some c => exists tc, find_label lbl (fn_code tf) = Some tc /\ transl_code f c false = OK tc
end.