(** The following lemmas show that the translation from Mach to Asm preserves labels, in the sense that the following diagram commutes: << translation Mach code ------------------------ Asm instr sequence |                                          | | Mach.find_label lbl       find_label lbl | |                                          | v                                          v Mach code tail ------------------- Asm instr seq tail translation >> The proof demands many boring lemmas showing that Asm constructor functions do not introduce new labels. *)
Section TRANSL_LABEL.
Remark loadimm32_label:
forall r n k, tail_nolabel k (loadimm32 r n k).
Hint Resolve loadimm32_label: labels.
Remark opimm32_label:
forall op opimm r1 r2 n k,
(forall r1 r2 r3, nolabel (op r1 r2 r3)) ->
(forall r1 r2 n, nolabel (opimm r1 r2 n)) ->
tail_nolabel k (opimm32 op opimm r1 r2 n k).
Hint Resolve opimm32_label: labels.
Remark loadimm64_label:
forall r n k, tail_nolabel k (loadimm64 r n k).
Hint Resolve loadimm64_label: labels.
Remark opimm64_label:
forall op opimm r1 r2 n k,
(forall r1 r2 r3, nolabel (op r1 r2 r3)) ->
(forall r1 r2 n, nolabel (opimm r1 r2 n)) ->
tail_nolabel k (opimm64 op opimm r1 r2 n k).
Hint Resolve opimm64_label: labels.
Remark addptrofs_label:
forall r1 r2 n k, tail_nolabel k (addptrofs r1 r2 n k).
Hint Resolve addptrofs_label: labels.
Remark transl_cond_float_nolabel:
forall c r1 r2 r3 insn normal,
transl_cond_float c r1 r2 r3 = (insn, normal) -> nolabel insn.
Remark transl_cond_single_nolabel:
forall c r1 r2 r3 insn normal,
transl_cond_single c r1 r2 r3 = (insn, normal) -> nolabel insn.
Remark transl_cbranch_label:
forall cond args lbl k c,
transl_cbranch cond args lbl k = OK c -> tail_nolabel k c.
Remark transl_cond_op_label:
forall cond args r k c,
transl_cond_op cond r 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 indexed_memory_access_label:
forall (mk_instr: ireg -> offset -> instruction) base ofs k,
(forall r o, nolabel (mk_instr r o)) ->
tail_nolabel k (indexed_memory_access mk_instr base ofs k).
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 src base ofs ty k c,
storeind src base ofs ty k = OK c -> tail_nolabel k c.
Remark loadind_ptr_label:
forall base ofs dst k, tail_nolabel k (loadind_ptr base ofs dst k).
Remark storeind_ptr_label:
forall src base ofs k, tail_nolabel k (storeind_ptr src base ofs k).
Remark transl_memory_access_label:
forall (mk_instr: ireg -> offset -> instruction) addr args k c,
(forall r o, nolabel (mk_instr r o)) ->
transl_memory_access mk_instr addr args k = OK c ->
tail_nolabel k c.
Remark make_epilogue_label:
forall f k, tail_nolabel k (make_epilogue f 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.