Section RETADDR_EXISTS.
Hypothesis transl_instr_tail:
forall f i ep k c, transl_instr f i ep k = OK c -> is_tail k c.
Hypothesis transf_function_inv:
forall f tf, transf_function f = OK tf ->
exists tc, exists ep, transl_code f (Mach.fn_code f) ep = OK tc /\ is_tail tc (fn_code tf).
Hypothesis transf_function_len:
forall f tf, transf_function f = OK tf -> list_length_z (fn_code tf) <= Ptrofs.max_unsigned.
End RETADDR_EXISTS.
Remark code_tail_no_bigger:
forall pos c1 c2, code_tail pos c1 c2 -> (length c2 <= length c1)%nat.
Remark code_tail_unique:
forall fn c pos pos',
code_tail pos fn c -> code_tail pos' fn c -> pos = pos'.
(** The [find_label] function returns the code tail starting at the given label.  A connection with [code_tail] is then established. *)
Fixpoint find_label (lbl: label) (c: code) {struct c} : option code :=
match c with
| nil => None
| instr :: c' =>
if is_label lbl instr then Some c' else find_label lbl c'
end.
(** Helper lemmas to reason about - the "code is tail of" property - correct translation of labels. *)
Definition tail_nolabel (k c: code) : Prop :=
is_tail k c /\ forall lbl, find_label lbl c = find_label lbl k.
Definition nolabel (i: instruction) :=
match i with Plabel _ => False | _ => True end.
Hint Extern 1 (nolabel _) => exact I : labels.

Lemma tail_nolabel_cons:
forall i c k,
nolabel i -> tail_nolabel k c -> tail_nolabel k (i :: c).