Section STRENGTH_REDUCTION.
Variable bc: block_classification.
Variable ge: genv.
Hypothesis GENV: genv_match bc ge.
Variable sp: block.
Hypothesis STACK: bc sp = BCstack.
Variable ae: AE.t.
Variable rs: regset.
Variable m: mem.
Hypothesis MATCH: ematch bc rs ae.
Ltac InvApproxRegs :=
match goal with
| [ H: _ :: _ = _ :: _ |- _ ] =>
injection H; clear H; intros; InvApproxRegs
| [ H: ?v = AE.get ?r ae |- _ ] =>
generalize (MATCH r); rewrite <- H; clear H; intro; InvApproxRegs
| _ => idtac
end.
Ltac SimplVM :=
match goal with
| [ H: vmatch _ ?v (I ?n) |- _ ] =>
let E := fresh in
assert (E: v = Vint n) by (inversion H; auto);
rewrite E in *; clear H; SimplVM
| [ H: vmatch _ ?v (L ?n) |- _ ] =>
let E := fresh in
assert (E: v = Vlong n) by (inversion H; auto);
rewrite E in *; clear H; SimplVM
| [ H: vmatch _ ?v (F ?n) |- _ ] =>
let E := fresh in
assert (E: v = Vfloat n) by (inversion H; auto);
rewrite E in *; clear H; SimplVM
| [ H: vmatch _ ?v (FS ?n) |- _ ] =>
let E := fresh in
assert (E: v = Vsingle n) by (inversion H; auto);
rewrite E in *; clear H; SimplVM
| [ H: vmatch _ ?v (Ptr(Gl ?id ?ofs)) |- _ ] =>
let E := fresh in
assert (E: Val.lessdef v (Genv.symbol_address ge id ofs)) by (eapply vmatch_ptr_gl; eauto);
clear H; SimplVM
| [ H: vmatch _ ?v (Ptr(Stk ?ofs)) |- _ ] =>
let E := fresh in
assert (E: Val.lessdef v (Vptr sp ofs)) by (eapply vmatch_ptr_stk; eauto);
clear H; SimplVM
| _ => idtac
end.
Remark shift_symbol_address:
forall id ofs delta,
Genv.symbol_address ge id (Ptrofs.add ofs (Ptrofs.of_int delta)) = Val.add (Genv.symbol_address ge id ofs) (Vint delta).

Lemma addr_strength_reduction_correct:
forall addr args vl res,
vl = map (fun r => AE.get r ae) args ->
eval_addressing ge (Vptr sp Ptrofs.zero) addr rs##args = Some res ->
let (addr', args') := addr_strength_reduction addr args vl in
exists res', eval_addressing ge (Vptr sp Ptrofs.zero) addr' rs##args' = Some res' /\ Val.lessdef res res'.