(** 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').

(* Specifications: *)
Lemma do_volatile_load_sound: forall w chunk m b ofs w' t v, do_volatile_load w chunk m b ofs = Some(w', t, v) -> volatile_load ge chunk m b ofs t v /\ possible_trace w t w'.
Lemma do_volatile_load_complete: forall w chunk m b ofs w' t v, volatile_load ge chunk m b ofs t v -> possible_trace w t w' -> do_volatile_load w chunk m b ofs = Some(w', t, v).
Lemma do_volatile_store_sound: forall w chunk m b ofs v w' t m', do_volatile_store w chunk m b ofs v = Some(w', t, m') -> volatile_store ge chunk m b ofs v t m' /\ possible_trace w t w'.
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').