aboutsummaryrefslogtreecommitdiff
path: root/kernel/byterun/coq_float64.c
diff options
context:
space:
mode:
authorPierre-Marie Pédrot2020-11-19 16:34:54 +0100
committerPierre-Marie Pédrot2020-11-19 16:34:54 +0100
commit3037172c80190b74b2c0f3017420cc871e74c996 (patch)
tree830f06071a1fc4fd3afaf2c8588645c6d55fb7b8 /kernel/byterun/coq_float64.c
parent01dea073194bf788414af549cc2753917540e964 (diff)
parent9815b5947a5c02ba9189a447f5b58d5bb81e4f93 (diff)
Merge PR #12959: Improve the bytecode interpreter
Ack-by: ppedrot Reviewed-by: proux01
Diffstat (limited to 'kernel/byterun/coq_float64.c')
-rw-r--r--kernel/byterun/coq_float64.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/kernel/byterun/coq_float64.c b/kernel/byterun/coq_float64.c
new file mode 100644
index 0000000000..bea47dd47e
--- /dev/null
+++ b/kernel/byterun/coq_float64.c
@@ -0,0 +1,74 @@
+/************************************************************************/
+/* * The Coq Proof Assistant / The Coq Development Team */
+/* v * Copyright INRIA, CNRS and contributors */
+/* <O___,, * (see version control and CREDITS file for authors & dates) */
+/* \VV/ **************************************************************/
+/* // * This file is distributed under the terms of the */
+/* * GNU Lesser General Public License Version 2.1 */
+/* * (see LICENSE file for the text of the license) */
+/************************************************************************/
+
+#include <math.h>
+#include <stdint.h>
+
+#define CAML_INTERNALS
+#include <caml/alloc.h>
+
+#include "coq_values.h"
+
+union double_bits {
+ double d;
+ uint64_t u;
+};
+
+static double next_up(double x) {
+ union double_bits bits;
+ if (!(x < INFINITY)) return x; // x is +oo or NaN
+ bits.d = x;
+ int64_t i = bits.u;
+ if (i >= 0) ++bits.u; // x >= +0.0, go away from zero
+ else if (bits.u + bits.u == 0) bits.u = 1; // x is -0.0, should almost never happen
+ else --bits.u; // x < 0.0, go toward zero
+ return bits.d;
+}
+
+static double next_down(double x) {
+ union double_bits bits;
+ if (!(x > -INFINITY)) return x; // x is -oo or NaN
+ bits.d = x;
+ int64_t i = bits.u;
+ if (i == 0) bits.u = INT64_MIN + 1; // x is +0.0
+ else if (i < 0) ++bits.u; // x <= -0.0, go away from zero
+ else --bits.u; // x > 0.0, go toward zero
+ return bits.d;
+}
+
+#define DECLARE_FBINOP(name, e) \
+ double coq_##name(double x, double y) { \
+ return e; \
+ } \
+ \
+ value coq_##name##_byte(value x, value y) { \
+ return caml_copy_double(coq_##name(Double_val(x), Double_val(y))); \
+ }
+
+#define DECLARE_FUNOP(name, e) \
+ double coq_##name(double x) { \
+ return e; \
+ } \
+ \
+ value coq_##name##_byte(value x) { \
+ return caml_copy_double(coq_##name(Double_val(x))); \
+ }
+
+DECLARE_FBINOP(fmul, x * y)
+DECLARE_FBINOP(fadd, x + y)
+DECLARE_FBINOP(fsub, x - y)
+DECLARE_FBINOP(fdiv, x / y)
+DECLARE_FUNOP(fsqrt, sqrt(x))
+DECLARE_FUNOP(next_up, next_up(x))
+DECLARE_FUNOP(next_down, next_down(x))
+
+value coq_is_double(value x) {
+ return Val_long(Is_double(x));
+}