summaryrefslogtreecommitdiffstats
path: root/runtime/arith.c
diff options
context:
space:
mode:
authorfche <fche>2005-08-12 19:43:55 +0000
committerfche <fche>2005-08-12 19:43:55 +0000
commit3a20432bc0a0aa6d8651561d508cc730e6dabc97 (patch)
tree2d957fcf675df9a8f3a909ab51f1177ae4854137 /runtime/arith.c
parentba3f9e9ebb1b8cae641159305031ec5fee637fd4 (diff)
downloadsystemtap-steved-3a20432bc0a0aa6d8651561d508cc730e6dabc97.tar.gz
systemtap-steved-3a20432bc0a0aa6d8651561d508cc730e6dabc97.tar.xz
systemtap-steved-3a20432bc0a0aa6d8651561d508cc730e6dabc97.zip
2005-08-12 Frank Ch. Eigler <fche@elastic.org>
PR systemtap/1122 et alii * parse.cxx (parse_literal): Parse and range-limit 64-bit numbers. (parse_unary): Correct precedence glitch. * staptree.h (literal_number): Store an int64_t. * staptree.cxx: Corresponding changes. * translate.cxx (check_dbz): Remove - insufficient. (emit_function): Define CONTEXT macro sibling for THIS. (c_typename): pe_long -> int64_t. (visit_literal_number): Format literal rigorously and uglily. (c_assignop, visit_binary_expression): Handle div/mod via new helper functions in runtime. * tapset/builtin_logging.stp: Add error, exit builtins. * testsuite/buildok/ten,eleven.stp: New tests. * testsuite/parse{ko,ok}/six.stp: Modify for larger numbers. * testsuite/transok/one.stp: Add more ";"s, maybe unnecessarily. 2005-08-12 Frank Ch. Eigler <fche@elastic.org> * arith.c: New file to contain arithmetic helper functions. * builtin_functions.h: Remove, unused. * runtime.h: Include it.
Diffstat (limited to 'runtime/arith.c')
-rw-r--r--runtime/arith.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/runtime/arith.c b/runtime/arith.c
new file mode 100644
index 00000000..175cc4e8
--- /dev/null
+++ b/runtime/arith.c
@@ -0,0 +1,79 @@
+#ifndef _ARITH_C_ /* -*- linux-c -*- */
+#define _ARITH_C_
+
+/** @file arith.
+ * @brief Implements 64-bit signed division/multiplication.
+ */
+
+struct context;
+void _stp_divmod64 (unsigned *errorcount, int64_t x, int64_t y,
+ int64_t *quo, int64_t *rem);
+
+
+/** Divide x by y. In case of overflow or division-by-zero,
+ * increment context errorcount, and return any old value.
+ */
+inline int64_t _stp_div64 (unsigned *errorcount, int64_t x, int64_t y)
+{
+ if (likely ((x >= LONG_MIN && x <= LONG_MAX) &&
+ (y >= LONG_MIN && y <= LONG_MAX)))
+ {
+ long xx = (long) x;
+ long yy = (long) y;
+ // check for division-by-zero and overflow
+ if (unlikely (yy == 0 || (xx == LONG_MIN && yy == -1)))
+ {
+ (*errorcount) ++;
+ return 0;
+ }
+ return xx / yy;
+ }
+ else
+ {
+ int64_t quo = 0;
+ _stp_divmod64 (errorcount, x, y, &quo, NULL);
+ return quo;
+ }
+}
+
+
+/** Modulo x by y. In case of overflow or division-by-zero,
+ * increment context errorcount, and return any old value.
+ */
+inline int64_t _stp_mod64 (unsigned *errorcount, int64_t x, int64_t y)
+{
+ if (likely ((x >= LONG_MIN && x <= LONG_MAX) &&
+ (y >= LONG_MIN && y <= LONG_MAX)))
+ {
+ long xx = (long) x;
+ long yy = (long) y;
+ // check for division-by-zero and overflow
+ if (unlikely (yy == 0 || (xx == LONG_MIN && yy == -1)))
+ {
+ (*errorcount) ++;
+ return 0;
+ }
+ return xx % yy;
+ }
+ else
+ {
+ int64_t rem = 0;
+ _stp_divmod64 (errorcount, x, y, NULL, &rem);
+ return rem;
+ }
+}
+
+
+/** Perform general long division/modulus. */
+void _stp_divmod64 (unsigned *errorcount, int64_t x, int64_t y,
+ int64_t *quo, int64_t *rem)
+{
+ // XXX: wimp out for now
+ (*errorcount) ++;
+ if (quo) *quo = 0;
+ if (rem) *rem = 0;
+}
+
+
+
+#endif /* _ARITH_C_ */