(* *********************************************************************)
(*                                                                     *)
(*              The Compcert verified compiler                         *)
(*                                                                     *)
(*          Xavier Leroy, INRIA Paris-Rocquencourt                     *)
(*                                                                     *)
(*  Copyright Institut National de Recherche en Informatique et en     *)
(*  Automatique.  All rights reserved.  This file is distributed       *)
(*  under the terms of the INRIA Non-Commercial License Agreement.     *)
(*                                                                     *)
(* *********************************************************************)
(** Animating the CompCert C semantics *)
Require Cstrategy.
Local Open Scope string_scope.
Local Open Scope list_scope.
(** Error monad with options or lists *)
Notation "'do' X <- A ; B" := (match A with Some X => B | None => None end)
(at level 200, X ident, A at level 100, B at level 200)
: option_monad_scope.
Notation "'do' X , Y <- A ; B" := (match A with Some (X, Y) => B | None => None end)
(at level 200, X ident, Y ident, A at level 100, B at level 200)
: option_monad_scope.
Notation "'do' X , Y , Z <- A ; B" := (match A with Some (X, Y, Z) => B | None => None end)
(at level 200, X ident, Y ident, Z ident, A at level 100, B at level 200)
: option_monad_scope.
Notation " 'check' A ; B" := (if A then B else None)
(at level 200, A at level 100, B at level 200)
: option_monad_scope.
Notation "'do' X <- A ; B" := (match A with Some X => B | None => nil end)
(at level 200, X ident, A at level 100, B at level 200)
: list_monad_scope.
Notation " 'check' A ; B" := (if A then B else nil)
(at level 200, A at level 100, B at level 200)
: list_monad_scope.
Definition is_val (a: expr) : option (val * type) :=
match a with
| Eval v ty => Some(v, ty)
| _ => None
end.
Definition is_loc (a: expr) : option (block * ptrofs * type) :=
match a with
| Eloc b ofs ty => Some(b, ofs, ty)
| _ => None
end.
Local Open Scope option_monad_scope.
Fixpoint is_val_list (al: exprlist) : option (list (val * type)) :=
match al with
| Enil => Some nil
| Econs a1 al => do vt1 <- is_val a1; do vtl <- is_val_list al; Some(vt1::vtl)
end.
Definition is_skip (s: statement) : {s = Sskip} + {s <> Sskip}.
Proof with try discriminate.
induction vl; destruct tl; simpl; intros; inv H.
constructor.
destruct (eventval_of_val a t) as [ev1|] eqn:?...
destruct (list_eventval_of_val vl tl) as [evl'|] eqn:?...
inv H1. constructor. apply eventval_of_val_sound; auto. eauto.
Qed.
(** Volatile memory accesses. *)
Definition do_volatile_load (w: world) (chunk: memory_chunk) (m: mem) (b: block) (ofs: ptrofs)
: option (world * trace * val) :=
if Genv.block_is_volatile ge b then
do id <- Genv.invert_symbol ge b;
match nextworld_vload w chunk id ofs with
| None => None
| Some(res, w') =>
do vres <- val_of_eventval res (type_of_chunk chunk);
Some(w', Event_vload chunk id ofs res :: nil, Val.load_result chunk vres)
end
else
do v <- Mem.load chunk m b (Ptrofs.unsigned ofs);
Some(w, E0, v).
Definition do_volatile_store (w: world) (chunk: memory_chunk) (m: mem) (b: block) (ofs: ptrofs) (v: val)
: option (world * trace * mem) :=
if Genv.block_is_volatile ge b then
do id <- Genv.invert_symbol ge b;
do ev <- eventval_of_val (Val.load_result chunk v) (type_of_chunk chunk);
do w' <- nextworld_vstore w chunk id ofs ev;
Some(w', Event_vstore chunk id ofs ev :: nil, m)
else
do m' <- Mem.store chunk m b (Ptrofs.unsigned ofs) v;
Some(w, E0, m').

Lemma do_volatile_store_complete:
forall w chunk m b ofs v w' t m',
volatile_store ge chunk m b ofs v t m' -> possible_trace w t w' ->
do_volatile_store w chunk m b ofs v = Some(w', t, m').