Section RELSEM.
Variable ge: genv.
Definition find_function
(ros: reg + ident) (rs: regset) : option fundef :=
match ros with
| inl r => Genv.find_funct ge rs#r
| inr symb =>
match Genv.find_symbol ge symb with
| None => None
| Some b => Genv.find_funct_ptr ge b
end
end.
(** The transitions are presented as an inductive predicate [step ge st1 t st2], where [ge] is the global environment, [st1] the initial state, [st2] the final state, and [t] the trace of system calls performed during this transition. *)
Inductive step: state -> trace -> state -> Prop :=
| exec_Inop:
forall s f sp pc rs m pc',
(fn_code f)!pc = Some(Inop pc') ->
step (State s f sp pc rs m)
E0 (State s f sp pc' rs m)
| exec_Iop:
forall s f sp pc rs m op args res pc' v,
(fn_code f)!pc = Some(Iop op args res pc') ->
eval_operation ge sp op rs##args m = Some v ->
step (State s f sp pc rs m)
E0 (State s f sp pc' (rs#res <- v) m)
| exec_Iload:
forall s f sp pc rs m chunk addr args dst pc' a v,
(fn_code f)!pc = Some(Iload chunk addr args dst pc') ->
eval_addressing ge sp addr rs##args = Some a ->
Mem.loadv chunk m a = Some v ->
step (State s f sp pc rs m)
E0 (State s f sp pc' (rs#dst <- v) m)
| exec_Istore:
forall s f sp pc rs m chunk addr args src pc' a m',
(fn_code f)!pc = Some(Istore chunk addr args src pc') ->
eval_addressing ge sp addr rs##args = Some a ->
Mem.storev chunk m a rs#src = Some m' ->
step (State s f sp pc rs m)
E0 (State s f sp pc' rs m')
| exec_Icall:
forall s f sp pc rs m sig ros args res pc' fd,
(fn_code f)!pc = Some(Icall sig ros args res pc') ->
find_function ros rs = Some fd ->
funsig fd = sig ->
step (State s f sp pc rs m)
E0 (Callstate (Stackframe res f sp pc' rs :: s) fd rs##args m)
| exec_Itailcall:
forall s f stk pc rs m sig ros args fd m',
(fn_code f)!pc = Some(Itailcall sig ros args) ->
find_function ros rs = Some fd ->
funsig fd = sig ->
Mem.free m stk 0 f.(fn_stacksize) = Some m' ->
step (State s f (Vptr stk Ptrofs.zero) pc rs m)
E0 (Callstate s fd rs##args m')
| exec_Ibuiltin:
forall s f sp pc rs m ef args res pc' vargs t vres m',
(fn_code f)!pc = Some(Ibuiltin ef args res pc') ->
eval_builtin_args ge (fun r => rs#r) sp m args vargs ->
external_call ef ge vargs m t vres m' ->
step (State s f sp pc rs m)
t (State s f sp pc' (regmap_setres res vres rs) m')
| exec_Icond:
forall s f sp pc rs m cond args ifso ifnot b pc',
(fn_code f)!pc = Some(Icond cond args ifso ifnot) ->
eval_condition cond rs##args m = Some b ->
pc' = (if b then ifso else ifnot) ->
step (State s f sp pc rs m)
E0 (State s f sp pc' rs m)
| exec_Ijumptable:
forall s f sp pc rs m arg tbl n pc',
(fn_code f)!pc = Some(Ijumptable arg tbl) ->
rs#arg = Vint n ->
list_nth_z tbl (Int.unsigned n) = Some pc' ->
step (State s f sp pc rs m)
E0 (State s f sp pc' rs m)
| exec_Ireturn:
forall s f stk pc rs m or m',
(fn_code f)!pc = Some(Ireturn or) ->
Mem.free m stk 0 f.(fn_stacksize) = Some m' ->
step (State s f (Vptr stk Ptrofs.zero) pc rs m)
E0 (Returnstate s (regmap_optget or Vundef rs) m')
| exec_function_internal:
forall s f args m m' stk,
Mem.alloc m 0 f.(fn_stacksize) = (m', stk) ->
step (Callstate s (Internal f) args m)
E0 (State s
f
(Vptr stk Ptrofs.zero)
f.(fn_entrypoint)
(init_regs args f.(fn_params))
m')
| exec_function_external:
forall s ef args res t m m',
external_call ef ge args m t res m' ->
step (Callstate s (External ef) args m)
t (Returnstate s res m')
| exec_return:
forall res f sp pc rs s vres m,
step (Returnstate (Stackframe res f sp pc rs :: s) vres m)
E0 (State s f sp pc (rs#res <- vres) m).

Lemma exec_Iload':
forall s f sp pc rs m chunk addr args dst pc' rs' a v,
(fn_code f)!pc = Some(Iload chunk addr args dst pc') ->
eval_addressing ge sp addr rs##args = Some a ->
Mem.loadv chunk m a = Some v ->
rs' = (rs#dst <- v) ->
step (State s f sp pc rs m)
E0 (State s f sp pc' rs' m).