aboutsummaryrefslogtreecommitdiffstats
path: root/riscV/Asmgenproof1.v
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@inria.fr>2017-11-12 19:23:49 +0100
committerXavier Leroy <xavier.leroy@inria.fr>2019-03-26 16:08:10 +0100
commit8252140c54d9be6f8c62a068f96795eac1e6c078 (patch)
tree33a8ab2fd1a18c094f16888ab88acc6d940bf294 /riscV/Asmgenproof1.v
parent1df887f5a275e4c31096018ff1a8fdfc39bca591 (diff)
downloadcompcert-8252140c54d9be6f8c62a068f96795eac1e6c078.tar.gz
compcert-8252140c54d9be6f8c62a068f96795eac1e6c078.zip
Introduce and use the type fp_comparison for floating-point comparisons
With FP arithmetic, the negation of "x < y" is not "x >= y". For this reason, the back-end intermediate languages of CompCert used to have both "Ccompf c" and "Cnotcompf c" comparison operators, where "c" is of type Integers.comparison and "Cnotcompf c" denotes the negation of FP comparison c. There are some problems with this approach: - Beyond Cnotcompf we also need Cnotcompfs (for single precision FP) and, in case of ARM, special forms for not-comparison against 0.0. This duplication of comparison constructors inevitably causes some code and proof duplication. - Cnotcompf Ceq is really Ccompf Cne, and likewise Cnotcompf Cne is really Ccompf Ceq, hence the representation of FP comparisons is not canonical, adding to the code and proof duplication mentioned above. - Cnotcompf is introduced in CminorSel, but in Cminor we don't have it, making it impossible to express some transformations over comparisons at the machine-independent Cminor level. This commit develops an alternate approach, whereas FP comparisons have their own type, defined as Floats.fp_comparison, and which includes constructors for "not <", "not <=", "not >" and "not >=". Hence this type is closed under boolean negation, so to speak, and there is no longer a need for "Cnotcompf", given that "Ccompf" takes a fp_comparison and can therefore express all FP comparisons of interest.
Diffstat (limited to 'riscV/Asmgenproof1.v')
-rw-r--r--riscV/Asmgenproof1.v63
1 files changed, 13 insertions, 50 deletions
diff --git a/riscV/Asmgenproof1.v b/riscV/Asmgenproof1.v
index 7f070c12..4b413393 100644
--- a/riscV/Asmgenproof1.v
+++ b/riscV/Asmgenproof1.v
@@ -360,6 +360,12 @@ Proof.
rewrite <- Float.cmp_swap. auto.
- simpl. f_equal. f_equal. f_equal. destruct (rs r2), (rs r1); auto. unfold Val.cmpf, Val.cmpf_bool.
rewrite <- Float.cmp_swap. auto.
+- rewrite <- Val.negate_cmpf. auto.
+- rewrite <- Val.negate_cmpf. auto.
+- rewrite <- Val.negate_cmpf. simpl. f_equal. f_equal. f_equal. destruct (rs r2), (rs r1); auto. unfold Val.cmpf, Val.cmpf_bool.
+ rewrite <- Float.cmp_swap. auto.
+- rewrite <- Val.negate_cmpf. simpl. f_equal. f_equal. f_equal. destruct (rs r2), (rs r1); auto. unfold Val.cmpf, Val.cmpf_bool.
+ rewrite <- Float.cmp_swap. auto.
Qed.
Lemma transl_cond_single_correct:
@@ -369,12 +375,17 @@ Lemma transl_cond_single_correct:
exec_instr ge fn insn rs m = Next (nextinstr (rs#rd <- v)) m.
Proof.
intros. destruct cmp; simpl in H; inv H; auto.
-- simpl. f_equal. f_equal. f_equal. destruct (rs r2), (rs r1); auto. unfold Val.cmpfs, Val.cmpfs_bool.
- rewrite Float32.cmp_ne_eq. destruct (Float32.cmp Ceq f0 f); auto.
+- rewrite <- Val.negate_cmpfs. auto.
- simpl. f_equal. f_equal. f_equal. destruct (rs r2), (rs r1); auto. unfold Val.cmpfs, Val.cmpfs_bool.
rewrite <- Float32.cmp_swap. auto.
- simpl. f_equal. f_equal. f_equal. destruct (rs r2), (rs r1); auto. unfold Val.cmpfs, Val.cmpfs_bool.
rewrite <- Float32.cmp_swap. auto.
+- rewrite <- Val.negate_cmpfs. auto.
+- rewrite <- Val.negate_cmpfs. auto.
+- rewrite <- Val.negate_cmpfs. simpl. f_equal. f_equal. f_equal. destruct (rs r2), (rs r1); auto. unfold Val.cmpfs, Val.cmpfs_bool.
+ rewrite <- Float32.cmp_swap. auto.
+- rewrite <- Val.negate_cmpfs. simpl. f_equal. f_equal. f_equal. destruct (rs r2), (rs r1); auto. unfold Val.cmpfs, Val.cmpfs_bool.
+ rewrite <- Float32.cmp_swap. auto.
Qed.
Remark branch_on_X31:
@@ -481,16 +492,6 @@ Proof.
split. constructor. apply exec_straight_one. eapply transl_cond_float_correct with (v := v); eauto. auto.
split. rewrite V; destruct normal, b; reflexivity.
intros; Simpl.
-- destruct (transl_cond_float c0 X31 x x0) as [insn normal] eqn:TC; inv EQ2.
- assert (EVAL'': Val.cmpf_bool c0 (rs x) (rs x0) = Some (negb b)).
- { destruct (Val.cmpf_bool c0 (rs x) (rs x0)) as [[]|]; inv EVAL'; auto. }
- set (v := if normal then Val.cmpf c0 rs#x rs#x0 else Val.notbool (Val.cmpf c0 rs#x rs#x0)).
- assert (V: v = Val.of_bool (xorb normal b)).
- { unfold v, Val.cmpf. rewrite EVAL''. destruct normal, b; reflexivity. }
- econstructor; econstructor.
- split. constructor. apply exec_straight_one. eapply transl_cond_float_correct with (v := v); eauto. auto.
- split. rewrite V; destruct normal, b; reflexivity.
- intros; Simpl.
- destruct (transl_cond_single c0 X31 x x0) as [insn normal] eqn:TC; inv EQ2.
set (v := if normal then Val.cmpfs c0 rs#x rs#x0 else Val.notbool (Val.cmpfs c0 rs#x rs#x0)).
assert (V: v = Val.of_bool (eqb normal b)).
@@ -499,16 +500,6 @@ Proof.
split. constructor. apply exec_straight_one. eapply transl_cond_single_correct with (v := v); eauto. auto.
split. rewrite V; destruct normal, b; reflexivity.
intros; Simpl.
-- destruct (transl_cond_single c0 X31 x x0) as [insn normal] eqn:TC; inv EQ2.
- assert (EVAL'': Val.cmpfs_bool c0 (rs x) (rs x0) = Some (negb b)).
- { destruct (Val.cmpfs_bool c0 (rs x) (rs x0)) as [[]|]; inv EVAL'; auto. }
- set (v := if normal then Val.cmpfs c0 rs#x rs#x0 else Val.notbool (Val.cmpfs c0 rs#x rs#x0)).
- assert (V: v = Val.of_bool (xorb normal b)).
- { unfold v, Val.cmpfs. rewrite EVAL''. destruct normal, b; reflexivity. }
- econstructor; econstructor.
- split. constructor. apply exec_straight_one. eapply transl_cond_single_correct with (v := v); eauto. auto.
- split. rewrite V; destruct normal, b; reflexivity.
- intros; Simpl.
Qed.
Lemma transl_cbranch_correct_true:
@@ -897,20 +888,6 @@ Proof.
simpl; reflexivity.
auto. auto.
split; intros; Simpl. unfold v, Val.cmpf. destruct (Val.cmpf_bool c0 (rs x) (rs x0)) as [[]|]; auto.
-+ (* notcmpf *)
- destruct (transl_cond_float c0 rd x x0) as [insn normal] eqn:TR.
- rewrite Val.notbool_negb_3. fold (Val.cmpf c0 (rs x) (rs x0)).
- set (v := Val.cmpf c0 (rs x) (rs x0)).
- destruct normal; inv EQ2.
-* econstructor; split.
- eapply exec_straight_two.
- eapply transl_cond_float_correct with (v := v); eauto.
- simpl; reflexivity.
- auto. auto.
- split; intros; Simpl. unfold v, Val.cmpf. destruct (Val.cmpf_bool c0 (rs x) (rs x0)) as [[]|]; auto.
-* econstructor; split.
- apply exec_straight_one. eapply transl_cond_float_correct with (v := Val.notbool v); eauto. auto.
- split; intros; Simpl.
+ (* cmpfs *)
destruct (transl_cond_single c0 rd x x0) as [insn normal] eqn:TR.
fold (Val.cmpfs c0 (rs x) (rs x0)).
@@ -925,20 +902,6 @@ Proof.
simpl; reflexivity.
auto. auto.
split; intros; Simpl. unfold v, Val.cmpfs. destruct (Val.cmpfs_bool c0 (rs x) (rs x0)) as [[]|]; auto.
-+ (* notcmpfs *)
- destruct (transl_cond_single c0 rd x x0) as [insn normal] eqn:TR.
- rewrite Val.notbool_negb_3. fold (Val.cmpfs c0 (rs x) (rs x0)).
- set (v := Val.cmpfs c0 (rs x) (rs x0)).
- destruct normal; inv EQ2.
-* econstructor; split.
- eapply exec_straight_two.
- eapply transl_cond_single_correct with (v := v); eauto.
- simpl; reflexivity.
- auto. auto.
- split; intros; Simpl. unfold v, Val.cmpfs. destruct (Val.cmpfs_bool c0 (rs x) (rs x0)) as [[]|]; auto.
-* econstructor; split.
- apply exec_straight_one. eapply transl_cond_single_correct with (v := Val.notbool v); eauto. auto.
- split; intros; Simpl.
Qed.
(** Some arithmetic properties. *)