diff options
author | fche <fche> | 2005-08-12 19:43:55 +0000 |
---|---|---|
committer | fche <fche> | 2005-08-12 19:43:55 +0000 |
commit | 3a20432bc0a0aa6d8651561d508cc730e6dabc97 (patch) | |
tree | 2d957fcf675df9a8f3a909ab51f1177ae4854137 /runtime/arith.c | |
parent | ba3f9e9ebb1b8cae641159305031ec5fee637fd4 (diff) | |
download | systemtap-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.c | 79 |
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_ */ |