(** Offset an addressing mode [addr] by a quantity [delta], so that it designates the pointer [delta] bytes past the pointer designated by [addr].  This may be undefined if an offset overflows, in which case [None] is returned.  *)
Definition offset_addressing_total (addr: addressing) (delta: Z) : addressing :=
match addr with
| Aindexed n => Aindexed (n + delta)
| Aindexed2 n => Aindexed2 (n + delta)
| Ascaled sc n => Ascaled sc (n + delta)
| Aindexed2scaled sc n => Aindexed2scaled sc (n + delta)
| Aglobal s n => Aglobal s (Ptrofs.add n (Ptrofs.repr delta))
| Abased s n => Abased s (Ptrofs.add n (Ptrofs.repr delta))
| Abasedscaled sc s n => Abasedscaled sc s (Ptrofs.add n (Ptrofs.repr delta))
| Ainstack n => Ainstack (Ptrofs.add n (Ptrofs.repr delta))
end.
Definition offset_addressing (addr: addressing) (delta: Z) : option addressing :=
let addr' := offset_addressing_total addr delta in
if addressing_valid addr' then Some addr' else None.

(* Specifications: *)
Lemma eval_offset_addressing_total_32:
forall (F V: Type) (ge: Genv.t F V) sp addr args delta v,
eval_addressing32 ge sp addr args = Some v ->
eval_addressing32 ge sp (offset_addressing_total addr delta) args = Some(Val.add v (Vint (Int.repr delta))).
Lemma eval_offset_addressing_total_64:
forall (F V: Type) (ge: Genv.t F V) sp addr args delta v,
eval_addressing64 ge sp addr args = Some v ->
eval_addressing64 ge sp (offset_addressing_total addr delta) args = Some(Val.addl v (Vlong (Int64.repr delta))).