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.

Lemma exec_straight_three:
forall i1 i2 i3 c rs1 m1 rs2 m2 rs3 m3 rs4 m4,
exec_instr ge fn i1 rs1 m1 = Next rs2 m2 ->
exec_instr ge fn i2 rs2 m2 = Next rs3 m3 ->
exec_instr ge fn i3 rs3 m3 = Next rs4 m4 ->
rs2#PC = Val.offset_ptr rs1#PC Ptrofs.one ->
rs3#PC = Val.offset_ptr rs2#PC Ptrofs.one ->
rs4#PC = Val.offset_ptr rs3#PC Ptrofs.one ->
exec_straight (i1 :: i2 :: i3 :: c) rs1 m1 c rs4 m4.