(** Shifting stack-relative references.  This is used in [Stacking]. *)
Definition shift_stack_addressing (delta: Z) (addr: addressing) :=
match addr with
| Ainstack ofs => Ainstack (Ptrofs.add ofs (Ptrofs.repr delta))
| _ => addr
end.
Definition shift_stack_operation (delta: Z) (op: operation) :=
match op with
| Olea  addr => Olea  (shift_stack_addressing delta addr)
| Oleal addr => Oleal (shift_stack_addressing delta addr)
| _ => op
end.

(* Specifications: *)
Lemma type_shift_stack_addressing:
forall delta addr, type_of_addressing (shift_stack_addressing delta addr) = type_of_addressing addr.
Lemma type_shift_stack_operation:
forall delta op, type_of_operation (shift_stack_operation delta op) = type_of_operation op.
Lemma eval_shift_stack_addressing32:
forall F V (ge: Genv.t F V) sp addr vl delta,
eval_addressing32 ge (Vptr sp Ptrofs.zero) (shift_stack_addressing delta addr) vl =
eval_addressing32 ge (Vptr sp (Ptrofs.repr delta)) addr vl.
Lemma eval_shift_stack_addressing64:
forall F V (ge: Genv.t F V) sp addr vl delta,
eval_addressing64 ge (Vptr sp Ptrofs.zero) (shift_stack_addressing delta addr) vl =
eval_addressing64 ge (Vptr sp (Ptrofs.repr delta)) addr vl.
Lemma eval_shift_stack_addressing:
forall F V (ge: Genv.t F V) sp addr vl delta,
eval_addressing ge (Vptr sp Ptrofs.zero) (shift_stack_addressing delta addr) vl =
eval_addressing ge (Vptr sp (Ptrofs.repr delta)) addr vl.
Lemma eval_shift_stack_operation:
forall F V (ge: Genv.t F V) sp op vl m delta,
eval_operation ge (Vptr sp Ptrofs.zero) (shift_stack_operation delta op) vl m =
eval_operation ge (Vptr sp (Ptrofs.repr delta)) op vl m.