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.

(* Specifications: *)
Lemma const_for_result_correct:
forall a op v,
const_for_result a = Some op ->
vmatch bc v a ->
exists v', eval_operation ge (Vptr sp Ptrofs.zero) op nil m = Some v' /\ Val.lessdef v v'.
Lemma cond_strength_reduction_correct:
forall cond args vl,
vl = map (fun r => AE.get r ae) args ->
let (cond', args') := cond_strength_reduction cond args vl in
eval_condition cond' rs##args' m = eval_condition cond rs##args m.
Lemma make_cmp_base_correct:
forall c args vl,
vl = map (fun r => AE.get r ae) args ->
let (op', args') := make_cmp_base c args vl in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op' rs##args' m = Some v
/\ Val.lessdef (Val.of_optbool (eval_condition c rs##args m)) v.
Lemma make_cmp_correct:
forall c args vl,
vl = map (fun r => AE.get r ae) args ->
let (op', args') := make_cmp c args vl in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op' rs##args' m = Some v
/\ Val.lessdef (Val.of_optbool (eval_condition c rs##args m)) v.
Lemma make_addimm_correct:
forall n r,
let (op, args) := make_addimm n r in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.add rs#r (Vint n)) v.
Lemma make_shlimm_correct:
forall n r1 r2,
rs#r2 = Vint n ->
let (op, args) := make_shlimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.shl rs#r1 (Vint n)) v.
Lemma make_shrimm_correct:
forall n r1 r2,
rs#r2 = Vint n ->
let (op, args) := make_shrimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.shr rs#r1 (Vint n)) v.
Lemma make_shruimm_aux_correct:
forall n r1,
Int.ltu n Int.iwordsize = true ->
let (op, args) := make_shruimm_aux n r1 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.shru rs#r1 (Vint n)) v.
Lemma make_shruimm_correct:
forall n r1 r2,
rs#r2 = Vint n ->
let (op, args) := make_shruimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.shru rs#r1 (Vint n)) v.
Lemma make_mulimm_correct:
forall n r1 r2,
rs#r2 = Vint n ->
let (op, args) := make_mulimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.mul rs#r1 (Vint n)) v.
Lemma make_divimm_correct:
forall n r1 r2 v,
Val.divs rs#r1 rs#r2 = Some v ->
rs#r2 = Vint n ->
let (op, args) := make_divimm n r1 r2 in
exists w, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some w /\ Val.lessdef v w.
Lemma make_divuimm_correct:
forall n r1 r2 v,
Val.divu rs#r1 rs#r2 = Some v ->
rs#r2 = Vint n ->
let (op, args) := make_divuimm n r1 r2 in
exists w, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some w /\ Val.lessdef v w.
Lemma make_andimm_correct:
forall n r x,
vmatch bc rs#r x ->
let (op, args) := make_andimm n r x in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.and rs#r (Vint n)) v.
Lemma make_orimm_correct:
forall n r,
let (op, args) := make_orimm n r in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.or rs#r (Vint n)) v.
Lemma make_xorimm_correct:
forall n r,
let (op, args) := make_xorimm n r in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.xor rs#r (Vint n)) v.
Lemma make_addlimm_correct:
forall n r,
let (op, args) := make_addlimm n r in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.addl rs#r (Vlong n)) v.
Lemma make_mullimm_correct:
forall n r1 r2,
rs#r2 = Vlong n ->
let (op, args) := make_mullimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.mull rs#r1 (Vlong n)) v.
Lemma make_shllimm_correct:
forall n r1 r2,
rs#r2 = Vint n ->
let (op, args) := make_shllimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.shll rs#r1 (Vint n)) v.
Lemma make_shrlimm_correct:
forall n r1 r2,
rs#r2 = Vint n ->
let (op, args) := make_shrlimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.shrl rs#r1 (Vint n)) v.
Lemma make_shrluimm_aux_correct:
forall n r1,
Int.ltu n Int64.iwordsize' = true ->
let (op, args) := make_shrluimm_aux n r1 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.shrlu rs#r1 (Vint n)) v.
Lemma make_shrluimm_correct:
forall n r1 r2,
rs#r2 = Vint n ->
let (op, args) := make_shrluimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.shrlu rs#r1 (Vint n)) v.
Lemma make_andlimm_correct:
forall n r x,
let (op, args) := make_andlimm n r x in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.andl rs#r (Vlong n)) v.
Lemma make_orlimm_correct:
forall n r,
let (op, args) := make_orlimm n r in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.orl rs#r (Vlong n)) v.
Lemma make_xorlimm_correct:
forall n r,
let (op, args) := make_xorlimm n r in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.xorl rs#r (Vlong n)) v.
Lemma make_divluimm_correct:
forall n r1 r2 v,
Val.divlu rs#r1 rs#r2 = Some v ->
rs#r2 = Vlong n ->
let (op, args) := make_divluimm n r1 r2 in
exists w, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some w /\ Val.lessdef v w.
Lemma make_mulfimm_correct:
forall n r1 r2,
rs#r2 = Vfloat n ->
let (op, args) := make_mulfimm n r1 r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.mulf rs#r1 rs#r2) v.
Lemma make_divlimm_correct:
forall n r1 r2 v,
Val.divls rs#r1 rs#r2 = Some v ->
rs#r2 = Vlong n ->
let (op, args) := make_divlimm n r1 r2 in
exists w, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some w /\ Val.lessdef v w.
Lemma make_mulfimm_correct_2:
forall n r1 r2,
rs#r1 = Vfloat n ->
let (op, args) := make_mulfimm n r2 r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.mulf rs#r1 rs#r2) v.
Lemma make_mulfsimm_correct:
forall n r1 r2,
rs#r2 = Vsingle n ->
let (op, args) := make_mulfsimm n r1 r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.mulfs rs#r1 rs#r2) v.
Lemma make_mulfsimm_correct_2:
forall n r1 r2,
rs#r1 = Vsingle n ->
let (op, args) := make_mulfsimm n r2 r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.mulfs rs#r1 rs#r2) v.
Lemma make_cast8signed_correct:
forall r x,
vmatch bc rs#r x ->
let (op, args) := make_cast8signed r x in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.sign_ext 8 rs#r) v.
Lemma make_cast16signed_correct:
forall r x,
vmatch bc rs#r x ->
let (op, args) := make_cast16signed r x in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v /\ Val.lessdef (Val.sign_ext 16 rs#r) v.
Lemma op_strength_reduction_correct:
forall op args vl v,
vl = map (fun r => AE.get r ae) args ->
eval_operation ge (Vptr sp Ptrofs.zero) op rs##args m = Some v ->
let (op', args') := op_strength_reduction op args vl in
exists w, eval_operation ge (Vptr sp Ptrofs.zero) op' rs##args' m = Some w /\ Val.lessdef v w.
Lemma eval_Olea_ptr:
forall a el,
eval_operation ge (Vptr sp Ptrofs.zero) (Olea_ptr a) el m = eval_addressing ge (Vptr sp Ptrofs.zero) a el.
Lemma const_for_result_correct:
forall a op v,
const_for_result a = Some op ->
vmatch bc v a ->
exists v', eval_operation ge (Vptr sp Ptrofs.zero) op nil m = Some v' /\ Val.lessdef v v'.
Lemma cond_strength_reduction_correct:
forall cond args vl,
vl = map (fun r => AE.get r ae) args ->
let (cond', args') := cond_strength_reduction cond args vl in
eval_condition cond' e##args' m = eval_condition cond e##args m.
Lemma addr_strength_reduction_32_generic_correct:
forall addr args vl res,
vl = map (fun r => AE.get r ae) args ->
eval_addressing32 ge (Vptr sp Ptrofs.zero) addr e##args = Some res ->
let (addr', args') := addr_strength_reduction_32_generic addr args vl in
exists res', eval_addressing32 ge (Vptr sp Ptrofs.zero) addr' e##args' = Some res' /\ Val.lessdef res res'.
Lemma addr_strength_reduction_32_correct:
forall addr args vl res,
vl = map (fun r => AE.get r ae) args ->
eval_addressing32 ge (Vptr sp Ptrofs.zero) addr e##args = Some res ->
let (addr', args') := addr_strength_reduction_32 addr args vl in
exists res', eval_addressing32 ge (Vptr sp Ptrofs.zero) addr' e##args' = Some res' /\ Val.lessdef res res'.
Lemma addr_strength_reduction_64_generic_correct:
forall addr args vl res,
vl = map (fun r => AE.get r ae) args ->
eval_addressing64 ge (Vptr sp Ptrofs.zero) addr e##args = Some res ->
let (addr', args') := addr_strength_reduction_64_generic addr args vl in
exists res', eval_addressing64 ge (Vptr sp Ptrofs.zero) addr' e##args' = Some res' /\ Val.lessdef res res'.
Lemma addr_strength_reduction_64_correct:
forall addr args vl res,
vl = map (fun r => AE.get r ae) args ->
eval_addressing64 ge (Vptr sp Ptrofs.zero) addr e##args = Some res ->
let (addr', args') := addr_strength_reduction_64 addr args vl in
exists res', eval_addressing64 ge (Vptr sp Ptrofs.zero) addr' e##args' = Some res' /\ Val.lessdef res res'.
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 e##args = Some res ->
let (addr', args') := addr_strength_reduction addr args vl in
exists res', eval_addressing ge (Vptr sp Ptrofs.zero) addr' e##args' = Some res' /\ Val.lessdef res res'.
Lemma make_cmp_base_correct:
forall c args vl,
vl = map (fun r => AE.get r ae) args ->
let (op', args') := make_cmp_base c args vl in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op' e##args' m = Some v
/\ Val.lessdef (Val.of_optbool (eval_condition c e##args m)) v.
Lemma make_cmp_correct:
forall c args vl,
vl = map (fun r => AE.get r ae) args ->
let (op', args') := make_cmp c args vl in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op' e##args' m = Some v
/\ Val.lessdef (Val.of_optbool (eval_condition c e##args m)) v.
Lemma make_addimm_correct:
forall n r,
let (op, args) := make_addimm n r in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.add e#r (Vint n)) v.
Lemma make_shlimm_correct:
forall n r1 r2,
e#r2 = Vint n ->
let (op, args) := make_shlimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.shl e#r1 (Vint n)) v.
Lemma make_shrimm_correct:
forall n r1 r2,
e#r2 = Vint n ->
let (op, args) := make_shrimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.shr e#r1 (Vint n)) v.
Lemma make_shruimm_correct:
forall n r1 r2,
e#r2 = Vint n ->
let (op, args) := make_shruimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.shru e#r1 (Vint n)) v.
Lemma make_mulimm_correct:
forall n r1,
let (op, args) := make_mulimm n r1 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.mul e#r1 (Vint n)) v.
Lemma make_divimm_correct:
forall n r1 r2 v,
Val.divs e#r1 e#r2 = Some v ->
e#r2 = Vint n ->
let (op, args) := make_divimm n r1 r2 in
exists w, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some w /\ Val.lessdef v w.
Lemma make_divuimm_correct:
forall n r1 r2 v,
Val.divu e#r1 e#r2 = Some v ->
e#r2 = Vint n ->
let (op, args) := make_divuimm n r1 r2 in
exists w, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some w /\ Val.lessdef v w.
Lemma make_moduimm_correct:
forall n r1 r2 v,
Val.modu e#r1 e#r2 = Some v ->
e#r2 = Vint n ->
let (op, args) := make_moduimm n r1 r2 in
exists w, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some w /\ Val.lessdef v w.
Lemma make_andimm_correct:
forall n r x,
vmatch bc e#r x ->
let (op, args) := make_andimm n r x in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.and e#r (Vint n)) v.
Lemma make_orimm_correct:
forall n r,
let (op, args) := make_orimm n r in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.or e#r (Vint n)) v.
Lemma make_xorimm_correct:
forall n r,
let (op, args) := make_xorimm n r in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.xor e#r (Vint n)) v.
Lemma make_addlimm_correct:
forall n r,
let (op, args) := make_addlimm n r in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.addl e#r (Vlong n)) v.
Lemma make_shllimm_correct:
forall n r1 r2,
e#r2 = Vint n ->
let (op, args) := make_shllimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.shll e#r1 (Vint n)) v.
Lemma make_shrlimm_correct:
forall n r1 r2,
e#r2 = Vint n ->
let (op, args) := make_shrlimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.shrl e#r1 (Vint n)) v.
Lemma make_shrluimm_correct:
forall n r1 r2,
e#r2 = Vint n ->
let (op, args) := make_shrluimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.shrlu e#r1 (Vint n)) v.
Lemma make_mullimm_correct:
forall n r1,
let (op, args) := make_mullimm n r1 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.mull e#r1 (Vlong n)) v.
Lemma make_divlimm_correct:
forall n r1 r2 v,
Val.divls e#r1 e#r2 = Some v ->
e#r2 = Vlong n ->
let (op, args) := make_divlimm n r1 r2 in
exists w, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some w /\ Val.lessdef v w.
Lemma make_divluimm_correct:
forall n r1 r2 v,
Val.divlu e#r1 e#r2 = Some v ->
e#r2 = Vlong n ->
let (op, args) := make_divluimm n r1 r2 in
exists w, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some w /\ Val.lessdef v w.
Lemma make_modluimm_correct:
forall n r1 r2 v,
Val.modlu e#r1 e#r2 = Some v ->
e#r2 = Vlong n ->
let (op, args) := make_modluimm n r1 r2 in
exists w, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some w /\ Val.lessdef v w.
Lemma make_andlimm_correct:
forall n r x,
let (op, args) := make_andlimm n r x in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.andl e#r (Vlong n)) v.
Lemma make_orlimm_correct:
forall n r,
let (op, args) := make_orlimm n r in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.orl e#r (Vlong n)) v.
Lemma make_xorlimm_correct:
forall n r,
let (op, args) := make_xorlimm n r in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.xorl e#r (Vlong n)) v.
Lemma make_mulfimm_correct:
forall n r1 r2,
e#r2 = Vfloat n ->
let (op, args) := make_mulfimm n r1 r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.mulf e#r1 e#r2) v.
Lemma make_mulfimm_correct_2:
forall n r1 r2,
e#r1 = Vfloat n ->
let (op, args) := make_mulfimm n r2 r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.mulf e#r1 e#r2) v.
Lemma make_mulfsimm_correct:
forall n r1 r2,
e#r2 = Vsingle n ->
let (op, args) := make_mulfsimm n r1 r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.mulfs e#r1 e#r2) v.
Lemma make_mulfsimm_correct_2:
forall n r1 r2,
e#r1 = Vsingle n ->
let (op, args) := make_mulfsimm n r2 r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.mulfs e#r1 e#r2) v.
Lemma make_cast8signed_correct:
forall r x,
vmatch bc e#r x ->
let (op, args) := make_cast8signed r x in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.sign_ext 8 e#r) v.
Lemma make_cast8unsigned_correct:
forall r x,
vmatch bc e#r x ->
let (op, args) := make_cast8unsigned r x in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.zero_ext 8 e#r) v.
Lemma make_cast16signed_correct:
forall r x,
vmatch bc e#r x ->
let (op, args) := make_cast16signed r x in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.sign_ext 16 e#r) v.
Lemma make_cast16unsigned_correct:
forall r x,
vmatch bc e#r x ->
let (op, args) := make_cast16unsigned r x in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.zero_ext 16 e#r) v.
Lemma op_strength_reduction_correct:
forall op args vl v,
vl = map (fun r => AE.get r ae) args ->
eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v ->
let (op', args') := op_strength_reduction op args vl in
exists w, eval_operation ge (Vptr sp Ptrofs.zero) op' e##args' m = Some w /\ Val.lessdef v w.
Lemma const_for_result_correct:
forall a op v,
const_for_result a = Some op ->
vmatch bc v a ->
exists v', eval_operation ge (Vptr sp Ptrofs.zero) op nil m = Some v' /\ Val.lessdef v v'.
Lemma cond_strength_reduction_correct:
forall cond args vl,
vl = map (fun r => AE.get r ae) args ->
let (cond', args') := cond_strength_reduction cond args vl in
eval_condition cond' e##args' m = eval_condition cond e##args m.
Lemma make_cmp_base_correct:
forall c args vl,
vl = map (fun r => AE.get r ae) args ->
let (op', args') := make_cmp_base c args vl in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op' e##args' m = Some v
/\ Val.lessdef (Val.of_optbool (eval_condition c e##args m)) v.
Lemma make_cmp_correct:
forall c args vl,
vl = map (fun r => AE.get r ae) args ->
let (op', args') := make_cmp c args vl in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op' e##args' m = Some v
/\ Val.lessdef (Val.of_optbool (eval_condition c e##args m)) v.
Lemma make_addimm_correct:
forall n r,
let (op, args) := make_addimm n r in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.add e#r (Vint n)) v.
Lemma make_shlimm_correct:
forall n r1 r2,
e#r2 = Vint n ->
let (op, args) := make_shlimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.shl e#r1 (Vint n)) v.
Lemma make_shrimm_correct:
forall n r1 r2,
e#r2 = Vint n ->
let (op, args) := make_shrimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.shr e#r1 (Vint n)) v.
Lemma make_shruimm_correct:
forall n r1 r2,
e#r2 = Vint n ->
let (op, args) := make_shruimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.shru e#r1 (Vint n)) v.
Lemma make_mulimm_correct:
forall n r1 r2,
e#r2 = Vint n ->
let (op, args) := make_mulimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.mul e#r1 (Vint n)) v.
Lemma make_divimm_correct:
forall n r1 r2 v,
Val.divs e#r1 e#r2 = Some v ->
e#r2 = Vint n ->
let (op, args) := make_divimm n r1 r2 in
exists w, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some w /\ Val.lessdef v w.
Lemma make_divuimm_correct:
forall n r1 r2 v,
Val.divu e#r1 e#r2 = Some v ->
e#r2 = Vint n ->
let (op, args) := make_divuimm n r1 r2 in
exists w, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some w /\ Val.lessdef v w.
Lemma make_moduimm_correct:
forall n r1 r2 v,
Val.modu e#r1 e#r2 = Some v ->
e#r2 = Vint n ->
let (op, args) := make_moduimm n r1 r2 in
exists w, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some w /\ Val.lessdef v w.
Lemma make_andimm_correct:
forall n r x,
vmatch bc e#r x ->
let (op, args) := make_andimm n r x in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.and e#r (Vint n)) v.
Lemma make_orimm_correct:
forall n r,
let (op, args) := make_orimm n r in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.or e#r (Vint n)) v.
Lemma make_xorimm_correct:
forall n r,
let (op, args) := make_xorimm n r in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.xor e#r (Vint n)) v.
Lemma make_addlimm_correct:
forall n r,
let (op, args) := make_addlimm n r in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.addl e#r (Vlong n)) v.
Lemma make_shllimm_correct:
forall n r1 r2,
e#r2 = Vint n ->
let (op, args) := make_shllimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.shll e#r1 (Vint n)) v.
Lemma make_shrlimm_correct:
forall n r1 r2,
e#r2 = Vint n ->
let (op, args) := make_shrlimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.shrl e#r1 (Vint n)) v.
Lemma make_shrluimm_correct:
forall n r1 r2,
e#r2 = Vint n ->
let (op, args) := make_shrluimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.shrlu e#r1 (Vint n)) v.
Lemma make_mullimm_correct:
forall n r1 r2,
e#r2 = Vlong n ->
let (op, args) := make_mullimm n r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.mull e#r1 (Vlong n)) v.
Lemma make_divlimm_correct:
forall n r1 r2 v,
Val.divls e#r1 e#r2 = Some v ->
e#r2 = Vlong n ->
let (op, args) := make_divlimm n r1 r2 in
exists w, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some w /\ Val.lessdef v w.
Lemma make_divluimm_correct:
forall n r1 r2 v,
Val.divlu e#r1 e#r2 = Some v ->
e#r2 = Vlong n ->
let (op, args) := make_divluimm n r1 r2 in
exists w, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some w /\ Val.lessdef v w.
Lemma make_modluimm_correct:
forall n r1 r2 v,
Val.modlu e#r1 e#r2 = Some v ->
e#r2 = Vlong n ->
let (op, args) := make_modluimm n r1 r2 in
exists w, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some w /\ Val.lessdef v w.
Lemma make_andlimm_correct:
forall n r x,
let (op, args) := make_andlimm n r x in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.andl e#r (Vlong n)) v.
Lemma make_orlimm_correct:
forall n r,
let (op, args) := make_orlimm n r in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.orl e#r (Vlong n)) v.
Lemma make_xorlimm_correct:
forall n r,
let (op, args) := make_xorlimm n r in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.xorl e#r (Vlong n)) v.
Lemma make_mulfimm_correct:
forall n r1 r2,
e#r2 = Vfloat n ->
let (op, args) := make_mulfimm n r1 r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.mulf e#r1 e#r2) v.
Lemma make_mulfimm_correct_2:
forall n r1 r2,
e#r1 = Vfloat n ->
let (op, args) := make_mulfimm n r2 r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.mulf e#r1 e#r2) v.
Lemma make_mulfsimm_correct:
forall n r1 r2,
e#r2 = Vsingle n ->
let (op, args) := make_mulfsimm n r1 r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.mulfs e#r1 e#r2) v.
Lemma make_mulfsimm_correct_2:
forall n r1 r2,
e#r1 = Vsingle n ->
let (op, args) := make_mulfsimm n r2 r1 r2 in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.mulfs e#r1 e#r2) v.
Lemma make_cast8signed_correct:
forall r x,
vmatch bc e#r x ->
let (op, args) := make_cast8signed r x in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.sign_ext 8 e#r) v.
Lemma make_cast16signed_correct:
forall r x,
vmatch bc e#r x ->
let (op, args) := make_cast16signed r x in
exists v, eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v /\ Val.lessdef (Val.sign_ext 16 e#r) v.
Lemma op_strength_reduction_correct:
forall op args vl v,
vl = map (fun r => AE.get r ae) args ->
eval_operation ge (Vptr sp Ptrofs.zero) op e##args m = Some v ->
let (op', args') := op_strength_reduction op args vl in
exists w, eval_operation ge (Vptr sp Ptrofs.zero) op' e##args' m = Some w /\ Val.lessdef v w.
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 e##args = Some res ->
let (addr', args') := addr_strength_reduction addr args vl in
exists res', eval_addressing ge (Vptr sp Ptrofs.zero) addr' e##args' = Some res' /\ Val.lessdef res res'.