summaryrefslogtreecommitdiff
path: root/cfrontend
diff options
context:
space:
mode:
authorGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2013-07-03 15:07:17 +0000
committerGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2013-07-03 15:07:17 +0000
commita0aaa3552d53b20a99566ac7116063fbb31b9964 (patch)
tree72b86341e136accdba1c339230cee0f1ba5013d9 /cfrontend
parent18bbf6d3cfb15219c87ebc79a5dd58bf75f2b4c4 (diff)
Treat casts int64 -> float32 as primitive operations instead of two
casts int64 -> float64 -> float32. The latter causes double rounding errors. git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@2290 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
Diffstat (limited to 'cfrontend')
-rw-r--r--cfrontend/Cminorgenproof.v2
-rw-r--r--cfrontend/Cop.v12
-rw-r--r--cfrontend/Cshmgen.v12
-rw-r--r--cfrontend/Cshmgenproof.v6
-rw-r--r--cfrontend/SimplLocalsproof.v3
5 files changed, 21 insertions, 14 deletions
diff --git a/cfrontend/Cminorgenproof.v b/cfrontend/Cminorgenproof.v
index d6b99ed..672f804 100644
--- a/cfrontend/Cminorgenproof.v
+++ b/cfrontend/Cminorgenproof.v
@@ -1532,6 +1532,8 @@ Proof.
inv H0; simpl in H; inv H. simpl. destruct (Float.longuoffloat f0); simpl in *; inv H1. TrivialExists.
inv H0; simpl in H; inv H. simpl. TrivialExists.
inv H0; simpl in H; inv H. simpl. TrivialExists.
+ inv H0; simpl in H; inv H. simpl. TrivialExists.
+ inv H0; simpl in H; inv H. simpl. TrivialExists.
Qed.
(** Compatibility of [eval_binop] with respect to [val_inject]. *)
diff --git a/cfrontend/Cop.v b/cfrontend/Cop.v
index 4932bad..1148d09 100644
--- a/cfrontend/Cop.v
+++ b/cfrontend/Cop.v
@@ -151,10 +151,12 @@ Definition cast_int_long (si: signedness) (i: int) : int64 :=
| Unsigned => Int64.repr (Int.unsigned i)
end.
-Definition cast_long_float (si : signedness) (i: int64) : float :=
- match si with
- | Signed => Float.floatoflong i
- | Unsigned => Float.floatoflongu i
+Definition cast_long_float (si: signedness) (sz: floatsize) (i: int64) : float :=
+ match si, sz with
+ | Signed, F64 => Float.floatoflong i
+ | Unsigned, F64 => Float.floatoflongu i
+ | Signed, F32 => Float.singleoflong i
+ | Unsigned, F32 => Float.singleoflongu i
end.
Definition cast_float_long (si : signedness) (f: float) : option int64 :=
@@ -229,7 +231,7 @@ Definition sem_cast (v: val) (t1 t2: type) : option val :=
end
| cast_case_l2f si1 sz2 =>
match v with
- | Vlong i => Some (Vfloat (cast_float_float sz2 (cast_long_float si1 i)))
+ | Vlong i => Some (Vfloat (cast_long_float si1 sz2 i))
| _ => None
end
| cast_case_f2l si2 =>
diff --git a/cfrontend/Cshmgen.v b/cfrontend/Cshmgen.v
index ad89a2d..c8a030c 100644
--- a/cfrontend/Cshmgen.v
+++ b/cfrontend/Cshmgen.v
@@ -72,10 +72,12 @@ Definition make_longofint (e: expr) (sg: signedness) :=
| Unsigned => Eunop Olongofintu e
end.
-Definition make_floatoflong (e: expr) (sg: signedness) :=
- match sg with
- | Signed => Eunop Ofloatoflong e
- | Unsigned => Eunop Ofloatoflongu e
+Definition make_floatoflong (e: expr) (sg: signedness) (sz: floatsize) :=
+ match sg, sz with
+ | Signed, F64 => Eunop Ofloatoflong e
+ | Unsigned, F64 => Eunop Ofloatoflongu e
+ | Signed, F32 => Eunop Osingleoflong e
+ | Unsigned, F32 => Eunop Osingleoflongu e
end.
Definition make_longoffloat (e: expr) (sg: signedness) :=
@@ -123,7 +125,7 @@ Definition make_cast (from to: type) (e: expr) :=
| cast_case_l2l => OK e
| cast_case_i2l si1 => OK (make_longofint e si1)
| cast_case_l2i sz2 si2 => OK (make_cast_int (Eunop Ointoflong e) sz2 si2)
- | cast_case_l2f si1 sz2 => OK (make_cast_float (make_floatoflong e si1) sz2)
+ | cast_case_l2f si1 sz2 => OK (make_floatoflong e si1 sz2)
| cast_case_f2l si2 => OK (make_longoffloat e si2)
| cast_case_f2bool => OK (Ebinop (Ocmpf Cne) e (make_floatconst Float.zero))
| cast_case_l2bool => OK (Ebinop (Ocmpl Cne) e (make_longconst Int64.zero))
diff --git a/cfrontend/Cshmgenproof.v b/cfrontend/Cshmgenproof.v
index 11f8011..3d5bbba 100644
--- a/cfrontend/Cshmgenproof.v
+++ b/cfrontend/Cshmgenproof.v
@@ -172,12 +172,12 @@ Proof.
Qed.
Lemma make_floatoflong_correct:
- forall a n sg e le m,
+ forall a n sg sz e le m,
eval_expr ge e le m a (Vlong n) ->
- eval_expr ge e le m (make_floatoflong a sg) (Vfloat(cast_long_float sg n)).
+ eval_expr ge e le m (make_floatoflong a sg sz) (Vfloat(cast_long_float sg sz n)).
Proof.
intros. unfold make_floatoflong, cast_int_long.
- destruct sg; econstructor; eauto.
+ destruct sg; destruct sz; econstructor; eauto.
Qed.
Lemma make_longoffloat_correct:
diff --git a/cfrontend/SimplLocalsproof.v b/cfrontend/SimplLocalsproof.v
index 515049a..ad8a06a 100644
--- a/cfrontend/SimplLocalsproof.v
+++ b/cfrontend/SimplLocalsproof.v
@@ -287,7 +287,8 @@ Proof.
(* float *)
destruct ty; simpl in H; try discriminate; destruct v; inv H.
constructor. apply cast_float_float_idem.
- constructor. apply cast_float_float_idem.
+ constructor. unfold cast_float_float, cast_long_float.
+ destruct f; destruct s; auto. apply Float.singleoflong_idem. apply Float.singleoflongu_idem.
constructor. apply cast_float_float_idem.
(* pointer *)
destruct ty; simpl in H; try discriminate; destruct v; inv H; try constructor.