aboutsummaryrefslogtreecommitdiffstats
path: root/riscV/ConstpropOpproof.v
diff options
context:
space:
mode:
authorDavid Monniaux <david.monniaux@univ-grenoble-alpes.fr>2020-09-21 09:17:05 +0200
committerDavid Monniaux <david.monniaux@univ-grenoble-alpes.fr>2020-09-21 19:39:46 +0200
commitcae21e8816db863bf99f87469c9680e150d28960 (patch)
tree19fdf188238300245e0e5e7a9b78a94bbb53df93 /riscV/ConstpropOpproof.v
parent52b4f973646c3b79804fcdddeed5325ab1f3ce7d (diff)
downloadcompcert-kvx-cae21e8816db863bf99f87469c9680e150d28960.tar.gz
compcert-kvx-cae21e8816db863bf99f87469c9680e150d28960.zip
maketotal mod & div
Diffstat (limited to 'riscV/ConstpropOpproof.v')
-rw-r--r--riscV/ConstpropOpproof.v152
1 files changed, 112 insertions, 40 deletions
diff --git a/riscV/ConstpropOpproof.v b/riscV/ConstpropOpproof.v
index 765aa035..26a50317 100644
--- a/riscV/ConstpropOpproof.v
+++ b/riscV/ConstpropOpproof.v
@@ -265,52 +265,84 @@ Qed.
Lemma make_divimm_correct:
forall n r1 r2 v,
- Val.divs e#r1 e#r2 = Some v ->
+ Val.maketotal (Val.divs e#r1 e#r2) = 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.
Proof.
intros; unfold make_divimm.
- predSpec Int.eq Int.eq_spec n Int.one; intros. subst. rewrite H0 in H.
- destruct (e#r1) eqn:?;
- try (rewrite Val.divs_one in H; exists (Vint i); split; simpl; try rewrite Heqv0; auto);
- inv H; auto.
- destruct (Int.is_power2 n) eqn:?.
- destruct (Int.ltu i (Int.repr 31)) eqn:?.
- exists v; split; auto. simpl. eapply Val.divs_pow2; eauto. congruence.
- exists v; auto.
- exists v; auto.
+ predSpec Int.eq Int.eq_spec n Int.one; intros; subst; rewrite H0.
+ { destruct (e # r1) eqn:Er1.
+ all: try (cbn; exists (e # r1); split; auto; fail).
+ rewrite Val.divs_one.
+ cbn.
+ rewrite Er1.
+ exists (Vint i); split; auto.
+ }
+ destruct (Int.is_power2 n) eqn:Power2.
+ {
+ destruct (Int.ltu i (Int.repr 31)) eqn:iLT31.
+ {
+ cbn.
+ exists (Val.maketotal (Val.shrx e # r1 (Vint i))); split; auto.
+ destruct (Val.divs e # r1 (Vint n)) eqn:DIVS; cbn; auto.
+ rewrite Val.divs_pow2 with (y:=v) (n:=n).
+ cbn.
+ all: auto.
+ }
+ exists (Val.maketotal (Val.divs e # r1 (Vint n))); split; cbn; auto; congruence.
+ }
+ exists (Val.maketotal (Val.divs e # r1 (Vint n))); split; cbn; auto; congruence.
Qed.
Lemma make_divuimm_correct:
forall n r1 r2 v,
- Val.divu e#r1 e#r2 = Some v ->
+ Val.maketotal (Val.divu e#r1 e#r2) = 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.
Proof.
intros; unfold make_divuimm.
- predSpec Int.eq Int.eq_spec n Int.one; intros. subst. rewrite H0 in H.
- destruct (e#r1) eqn:?;
- try (rewrite Val.divu_one in H; exists (Vint i); split; simpl; try rewrite Heqv0; auto);
- inv H; auto.
- destruct (Int.is_power2 n) eqn:?.
- econstructor; split. simpl; eauto.
- rewrite H0 in H. erewrite Val.divu_pow2 by eauto. auto.
- exists v; auto.
+ predSpec Int.eq Int.eq_spec n Int.one; intros; subst; rewrite H0.
+ { destruct (e # r1) eqn:Er1.
+ all: try (cbn; exists (e # r1); split; auto; fail).
+ rewrite Val.divu_one.
+ cbn.
+ rewrite Er1.
+ exists (Vint i); split; auto.
+ }
+ destruct (Int.is_power2 n) eqn:Power2.
+ {
+ cbn.
+ exists (Val.shru e # r1 (Vint i)); split; auto.
+ destruct (Val.divu e # r1 (Vint n)) eqn:DIVU; cbn; auto.
+ rewrite Val.divu_pow2 with (y:=v) (n:=n).
+ all: auto.
+ }
+ exists (Val.maketotal (Val.divu e # r1 (Vint n))); split; cbn; auto; congruence.
Qed.
Lemma make_moduimm_correct:
forall n r1 r2 v,
- Val.modu e#r1 e#r2 = Some v ->
+ Val.maketotal (Val.modu e#r1 e#r2) = 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.
Proof.
intros; unfold make_moduimm.
destruct (Int.is_power2 n) eqn:?.
- exists v; split; auto. simpl. decEq. eapply Val.modu_pow2; eauto. congruence.
- exists v; auto.
+ { destruct (Val.modu e # r1 e # r2) eqn:MODU; cbn in H.
+ { subst v0.
+ exists v; split; auto.
+ cbn. decEq. eapply Val.modu_pow2; eauto. congruence.
+ }
+ subst v.
+ eexists; split; auto.
+ cbn. reflexivity.
+ }
+ exists v; split; auto.
+ cbn.
+ congruence.
Qed.
Lemma make_andimm_correct:
@@ -444,48 +476,82 @@ Qed.
Lemma make_divlimm_correct:
forall n r1 r2 v,
- Val.divls e#r1 e#r2 = Some v ->
+ Val.maketotal (Val.divls e#r1 e#r2) = 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.
Proof.
intros; unfold make_divlimm.
- destruct (Int64.is_power2' n) eqn:?. destruct (Int.ltu i (Int.repr 63)) eqn:?.
- rewrite H0 in H. econstructor; split. simpl; eauto. eapply Val.divls_pow2; eauto. auto.
- exists v; auto.
- exists v; auto.
+ destruct (Int64.is_power2' n) eqn:Power2.
+ {
+ destruct (Int.ltu i (Int.repr 63)) eqn:iLT63.
+ {
+ cbn.
+ exists (Val.maketotal (Val.shrxl e # r1 (Vint i))); split; auto.
+ rewrite H0 in H.
+ destruct (Val.divls e # r1 (Vlong n)) eqn:DIVS; cbn in H; auto.
+ {
+ subst v0.
+ rewrite Val.divls_pow2 with (y:=v) (n:=n).
+ cbn.
+ all: auto.
+ }
+ subst. auto.
+ }
+ cbn. subst. rewrite H0.
+ exists (Val.maketotal (Val.divls e # r1 (Vlong n))); split; auto.
+ }
+ cbn. subst. rewrite H0.
+ exists (Val.maketotal (Val.divls e # r1 (Vlong n))); split; auto.
Qed.
Lemma make_divluimm_correct:
forall n r1 r2 v,
- Val.divlu e#r1 e#r2 = Some v ->
+ Val.maketotal (Val.divlu e#r1 e#r2) = 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.
Proof.
intros; unfold make_divluimm.
destruct (Int64.is_power2' n) eqn:?.
+ {
econstructor; split. simpl; eauto.
- rewrite H0 in H. destruct (e#r1); inv H. destruct (Int64.eq n Int64.zero); inv H2.
- simpl.
- erewrite Int64.is_power2'_range by eauto.
- erewrite Int64.divu_pow2' by eauto. auto.
- exists v; auto.
+ rewrite H0 in H. destruct (e#r1); inv H.
+ all: cbn; auto.
+ {
+ destruct (Int64.eq n Int64.zero); cbn; auto.
+ erewrite Int64.is_power2'_range by eauto.
+ erewrite Int64.divu_pow2' by eauto. auto.
+ }
+ }
+ exists v; split; auto.
+ cbn.
+ rewrite H.
+ reflexivity.
Qed.
Lemma make_modluimm_correct:
forall n r1 r2 v,
- Val.modlu e#r1 e#r2 = Some v ->
+ Val.maketotal (Val.modlu e#r1 e#r2) = 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.
Proof.
intros; unfold make_modluimm.
destruct (Int64.is_power2 n) eqn:?.
- exists v; split; auto. simpl. decEq.
- rewrite H0 in H. destruct (e#r1); inv H. destruct (Int64.eq n Int64.zero); inv H2.
- simpl. erewrite Int64.modu_and by eauto. auto.
- exists v; auto.
+ {
+ econstructor; split. simpl; eauto.
+ rewrite H0 in H. destruct (e#r1); inv H.
+ all: cbn; auto.
+ {
+ destruct (Int64.eq n Int64.zero); cbn; auto.
+ erewrite Int64.modu_and by eauto. auto.
+ }
+ }
+ exists v; split; auto.
+ cbn.
+ rewrite H.
+ reflexivity.
Qed.
Lemma make_andlimm_correct:
@@ -633,14 +699,17 @@ Proof.
- (* mul 2*)
InvApproxRegs; SimplVM; inv H0. apply make_mulimm_correct; auto.
- (* divs *)
- assert (e#r2 = Vint n2). clear H0. InvApproxRegs; SimplVM; auto.
- apply make_divimm_correct; auto.
+ assert (e#r2 = Vint n2). { clear H0. InvApproxRegs; SimplVM; auto. }
+ apply make_divimm_correct; auto.
+ congruence.
- (* divu *)
assert (e#r2 = Vint n2). clear H0. InvApproxRegs; SimplVM; auto.
apply make_divuimm_correct; auto.
+ congruence.
- (* modu *)
assert (e#r2 = Vint n2). clear H0. InvApproxRegs; SimplVM; auto.
apply make_moduimm_correct; auto.
+ congruence.
- (* and 1 *)
rewrite Val.and_commut in H0. InvApproxRegs; SimplVM; inv H0. apply make_andimm_correct; auto.
- (* and 2 *)
@@ -680,12 +749,15 @@ Proof.
- (* divl *)
assert (e#r2 = Vlong n2). clear H0. InvApproxRegs; SimplVM; auto.
apply make_divlimm_correct; auto.
+ congruence.
- (* divlu *)
assert (e#r2 = Vlong n2). clear H0. InvApproxRegs; SimplVM; auto.
apply make_divluimm_correct; auto.
+ congruence.
- (* modlu *)
assert (e#r2 = Vlong n2). clear H0. InvApproxRegs; SimplVM; auto.
apply make_modluimm_correct; auto.
+ congruence.
- (* andl 1 *)
rewrite Val.andl_commut in H0. InvApproxRegs; SimplVM; inv H0. apply make_andlimm_correct; auto.
- (* andl 2 *)