Section STRAIGHTLINE.
Variable ge: genv.
Variable fn: function.
(** Straight-line code is composed of processor instructions that execute in sequence (no branches, no function calls and returns). The following inductive predicate relates the machine states before and after executing a straight-line sequence of instructions. Instructions are taken from the first list instead of being fetched from memory. *)
Inductive exec_straight: code -> regset -> mem ->
code -> regset -> mem -> Prop :=
| exec_straight_one:
forall i1 c rs1 m1 rs2 m2,
exec_instr ge fn i1 rs1 m1 = Next rs2 m2 ->
rs2#PC = Val.offset_ptr rs1#PC Ptrofs.one ->
exec_straight (i1 :: c) rs1 m1 c rs2 m2
| exec_straight_step:
forall i c rs1 m1 rs2 m2 c' rs3 m3,
exec_instr ge fn i rs1 m1 = Next rs2 m2 ->
rs2#PC = Val.offset_ptr rs1#PC Ptrofs.one ->
exec_straight c rs2 m2 c' rs3 m3 ->
exec_straight (i :: c) rs1 m1 c' rs3 m3.
(** The following lemmas show that straight-line executions (predicate [exec_straight]) correspond to correct Asm executions. *)

Lemma exec_straight_steps_2:
forall c rs m c' rs' m',
exec_straight c rs m c' rs' m' ->
list_length_z (fn_code fn) <= Ptrofs.max_unsigned ->
forall b ofs,
rs#PC = Vptr b ofs ->
Genv.find_funct_ptr ge b = Some (Internal fn) ->
code_tail (Ptrofs.unsigned ofs) (fn_code fn) c ->
exists ofs',
rs'#PC = Vptr b ofs'
/\ code_tail (Ptrofs.unsigned ofs') (fn_code fn) c'.