(** Indexed memory stores. *)

(* Specifications: *)
Lemma accessind_store_correct:
forall (A: Type) (inj: A -> preg)
(instr1: A -> constant -> ireg -> instruction)
(instr2: A -> ireg -> ireg -> instruction)
(base: ireg) ofs rx chunk (rs: regset) m m' k,
(forall rs m r1 cst r2,
exec_instr ge fn (instr1 r1 cst r2) rs m = store1 ge chunk (inj r1) cst r2 rs m) ->
(forall rs m r1 r2 r3,
exec_instr ge fn (instr2 r1 r2 r3) rs m = store2 chunk (inj r1) r2 r3 rs m) ->
Mem.storev chunk m (Val.offset_ptr rs#base ofs) (rs (inj rx)) = Some m' ->
base <> GPR0 -> inj rx <> PC -> inj rx <> GPR0 ->
exists rs',
exec_straight ge fn (accessind instr1 instr2 base ofs rx k) rs m k rs' m'
/\ forall r, r <> PC -> r <> GPR0 -> rs'#r = rs#r.
Lemma storeind_correct:
forall (base: ireg) ofs ty src k (rs: regset) m m' c,
storeind src base ofs ty k = OK c ->
Mem.storev (chunk_of_type ty) m (Val.offset_ptr rs#base ofs) (rs#(preg_of src)) = Some m' ->
base <> GPR0 ->
exists rs',
exec_straight ge fn c rs m k rs' m'
/\ forall r, r <> PC -> r <> GPR0 -> rs'#r = rs#r.
Lemma storeind_correct:
forall (base: ireg) ofs ty src k c (rs: regset) m m',
storeind src base ofs ty k = OK c ->
Mem.storev (chunk_of_type ty) m (Val.offset_ptr rs#base ofs) (rs#(preg_of src)) = Some m' ->
exists rs',
exec_straight ge fn c rs m k rs' m'
/\ forall r, if_preg r = true -> r <> IR14 -> rs'#r = rs#r.