diff options
Diffstat (limited to '')
| -rw-r--r-- | Makefile | 10 | ||||
| -rw-r--r-- | config-coverage-gcc.mk | 14 | ||||
| -rw-r--r-- | config.mk | 10 | ||||
| -rw-r--r-- | libj2/addition.h | 45 | ||||
| -rw-r--r-- | libj2/bit-shifting.h | 41 | ||||
| -rw-r--r-- | libj2/division.h | 64 | ||||
| -rw-r--r-- | libj2/mixed-comparison.h | 140 | ||||
| -rw-r--r-- | libj2/multiplication.h | 61 | ||||
| -rw-r--r-- | libj2/sign-shifting.h | 45 | ||||
| -rw-r--r-- | libj2/signed-comparison.h | 6 | ||||
| -rw-r--r-- | libj2/strings.h | 6 | ||||
| -rw-r--r-- | libj2/subtraction.h | 20 | ||||
| -rw-r--r-- | libj2_abs_j2i.c | 5 | ||||
| -rw-r--r-- | libj2_j2i_add_ji.c | 2 | ||||
| -rw-r--r-- | libj2_j2i_divmod_j2i_to_j2i.c | 2 | ||||
| -rw-r--r-- | libj2_j2i_lsh.c | 59 | ||||
| -rw-r--r-- | libj2_j2i_mul_ji.c | 19 | ||||
| -rw-r--r-- | libj2_j2i_sub_j2i.c | 27 | ||||
| -rw-r--r-- | libj2_j2i_sub_ji.c | 27 | ||||
| -rw-r--r-- | libj2_j2i_xor_sign.c | 11 | ||||
| -rw-r--r-- | libj2_j2u_divmod_j2u_to_j2u.c | 2 | ||||
| -rw-r--r-- | libj2_ji_sub_ji_to_j2i.c | 5 |
22 files changed, 435 insertions, 186 deletions
@@ -600,19 +600,19 @@ $(TOBJ): $(HDR) $(TEST): libj2.a .c.o: - $(CC) -c -o $@ $< $(CFLAGS) $(CPPFLAGS) + $(CC) -c -o $@ $< $(CFLAGS) $(COV_CFLAGS) $(CPPFLAGS) $(COV_CPPFLAGS) .c.to: - $(CC) -c -o $@ $< -DTEST $(CFLAGS) $(CPPFLAGS) + $(CC) -c -o $@ $< -DTEST $(CFLAGS) $(CPPFLAGS) $(COV_CPPFLAGS) .to.t: - $(CC) -o $@ $< libj2.a $(LDFLAGS) + $(CC) -o $@ $< libj2.a $(LDFLAGS) $(COV_LDFLAGS) .c.t: - $(CC) -o $@ $< libj2.a -DTEST $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) + $(CC) -o $@ $< libj2.a -DTEST $(CFLAGS) $(CPPFLAGS) $(COV_CPPFLAGS) $(LDFLAGS) $(COV_LDFLAGS) .c.lo: - $(CC) -fPIC -c -o $@ $< $(CFLAGS) $(CPPFLAGS) + $(CC) -fPIC -c -o $@ $< $(CFLAGS) $(COV_CFLAGS) $(CPPFLAGS) $(COV_CPPFLAGS) libj2.a: $(OBJ) @rm -f -- $@ diff --git a/config-coverage-gcc.mk b/config-coverage-gcc.mk new file mode 100644 index 0000000..8fc1905 --- /dev/null +++ b/config-coverage-gcc.mk @@ -0,0 +1,14 @@ +CONFIGFILE_PROPER = config.mk +include $(CONFIGFILE_PROPER) + +CC = $(CC_PREFIX)gcc -std=c99 +GCOV = gcov + +COV_CPPFLAGS = -DCOVERAGE_TEST +COV_CFLAGS = --coverage -g -O0 +COV_LDFLAGS = --coverage -g -O0 + +LIBTEST_CHECK_PREFIX = : + +coverage: check + $(GCOV) -pr -- *.gcda 2>&1 @@ -3,6 +3,12 @@ MANPREFIX = $(PREFIX)/share/man CC = c99 +COMMON_SANITIZE = -fsanitize=alignment,shift,signed-integer-overflow,object-size,null,undefined,bounds,address +CLANG_SANITIZE = -O1 $(COMMON_SANITIZE),cfi -flto -fvisibility=hidden -fno-sanitize-trap=cfi +GCC_SANITIZE = -O1 $(COMMON_SANITIZE) +#SANITIZE = $(CLANG_SANITIZE) +#SANITIZE = $(GCC_SANITIZE) + CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE -CFLAGS = -LDFLAGS = +CFLAGS = $(SANITIZE) +LDFLAGS = $(SANITIZE) diff --git a/libj2/addition.h b/libj2/addition.h index c45716e..6d6e543 100644 --- a/libj2/addition.h +++ b/libj2/addition.h @@ -426,15 +426,17 @@ libj2_j2u_add_j2u_overflow_p(const struct libj2_j2u *a, const struct libj2_j2u * inline void libj2_j2i_add_ji(struct libj2_j2i *a, intmax_t b) { - struct libj2_j2u u; + struct libj2_j2u u, v; if (b < 0) { - u.high = UINTMAX_MAX; - u.low = ~(uintmax_t)-(b + 1); + v.high = UINTMAX_MAX; + v.low = ~(uintmax_t)-(b + 1); } else { - u.high = 0; - u.low = (uintmax_t)b; + v.high = 0; + v.low = (uintmax_t)b; } - libj2_j2u_add_j2u((void *)a, &u); + libj2_j2i_to_j2u(a, &u); + libj2_j2u_add_j2u(&u, &v); + libj2_j2u_to_j2i(&u, a); } @@ -452,7 +454,11 @@ libj2_j2i_add_ji(struct libj2_j2i *a, intmax_t b) inline void libj2_j2i_add_j2i(struct libj2_j2i *a, const struct libj2_j2i *b) { - libj2_j2u_add_j2u((void *)a, (const void *)b); + struct libj2_j2u u, v; + libj2_j2i_to_j2u(a, &u); + libj2_j2i_to_j2u(b, &v); + libj2_j2u_add_j2u(&u, &v); + libj2_j2u_to_j2i(&u, a); } @@ -472,15 +478,17 @@ libj2_j2i_add_j2i(struct libj2_j2i *a, const struct libj2_j2i *b) inline void libj2_j2i_add_ji_to_j2i(const struct libj2_j2i *a, intmax_t b, struct libj2_j2i *res) { - struct libj2_j2u u; + struct libj2_j2u u, v, r; if (b < 0) { - u.high = UINTMAX_MAX; - u.low = ~(uintmax_t)-(b + 1); + v.high = UINTMAX_MAX; + v.low = ~(uintmax_t)-(b + 1); } else { - u.high = 0; - u.low = (uintmax_t)b; + v.high = 0; + v.low = (uintmax_t)b; } - libj2_j2u_add_j2u_to_j2u((const void *)a, &u, (void *)res); + libj2_j2i_to_j2u(a, &u); + libj2_j2u_add_j2u_to_j2u(&u, &v, &r); + libj2_j2u_to_j2i(&r, res); } @@ -499,7 +507,11 @@ libj2_j2i_add_ji_to_j2i(const struct libj2_j2i *a, intmax_t b, struct libj2_j2i inline void libj2_j2i_add_j2i_to_j2i(const struct libj2_j2i *a, const struct libj2_j2i *b, struct libj2_j2i *res) { - libj2_j2u_add_j2u_to_j2u((const void *)a, (const void *)b, (void *)res); + struct libj2_j2u u, v, r; + libj2_j2i_to_j2u(a, &u); + libj2_j2i_to_j2u(b, &v); + libj2_j2u_add_j2u_to_j2u(&u, &v, &r); + libj2_j2u_to_j2i(&r, res); } @@ -520,7 +532,7 @@ libj2_j2i_add_j2i_to_j2i(const struct libj2_j2i *a, const struct libj2_j2i *b, s inline void libj2_ji_add_ji_to_j2i(intmax_t a, intmax_t b, struct libj2_j2i *res) { - struct libj2_j2u u, v; + struct libj2_j2u u, v, r; if (a < 0) { u.high = UINTMAX_MAX; u.low = ~(uintmax_t)-(a + 1); @@ -535,7 +547,8 @@ libj2_ji_add_ji_to_j2i(intmax_t a, intmax_t b, struct libj2_j2i *res) v.high = 0; v.low = (uintmax_t)b; } - libj2_j2u_add_j2u_to_j2u(&u, &v, (void *)res); + libj2_j2u_add_j2u_to_j2u(&u, &v, &r); + libj2_j2u_to_j2i(&r, res); } diff --git a/libj2/bit-shifting.h b/libj2/bit-shifting.h index 515a1d4..54c6a22 100644 --- a/libj2/bit-shifting.h +++ b/libj2/bit-shifting.h @@ -748,7 +748,10 @@ libj2_ju_rsh_underflow_p(uintmax_t a, unsigned b) inline void libj2_j2i_lsh(struct libj2_j2i *a, unsigned b) { - libj2_j2u_lsh((void *)a, b); + struct libj2_j2u u; + libj2_j2i_to_j2u(a, &u); + libj2_j2u_lsh(&u, b); + libj2_j2u_to_j2i(&u, a); } @@ -774,7 +777,10 @@ libj2_j2i_lsh(struct libj2_j2i *a, unsigned b) inline void libj2_j2i_lsh_to_j2i(const struct libj2_j2i *a, unsigned b, struct libj2_j2i *res) { - libj2_j2u_lsh_to_j2u((const void *)a, b, (void *)res); + struct libj2_j2u u, r; + libj2_j2i_to_j2u(a, &u); + libj2_j2u_lsh_to_j2u(&u, b, &r); + libj2_j2u_to_j2i(&r, res); } @@ -1037,8 +1043,11 @@ libj2_ji_lsh_to_j2i_overflow(intmax_t a, unsigned b, struct libj2_j2i *res) inline void libj2_j2i_rsh_to_j2i(const struct libj2_j2i *a, unsigned b, struct libj2_j2i *res) { + struct libj2_j2u u, r; if (!libj2_j2i_is_negative(a)) { - libj2_j2u_rsh_to_j2u((const void *)a, b, (void *)res); + libj2_j2i_to_j2u(a, &u); + libj2_j2u_rsh_to_j2u(&u, b, &r); + libj2_j2u_to_j2i(&r, res); } else if (b >= LIBJ2_J2U_BIT) { res->high = UINTMAX_MAX; res->low = UINTMAX_MAX; @@ -1052,7 +1061,9 @@ libj2_j2i_rsh_to_j2i(const struct libj2_j2i *a, unsigned b, struct libj2_j2i *re res->low >>= b; res->low |= UINTMAX_MAX << (LIBJ2_JU_BIT - b); } else if (b) { - libj2_j2u_rsh_to_j2u((const void *)a, b, (void *)res); + libj2_j2i_to_j2u(a, &u); + libj2_j2u_rsh_to_j2u(&u, b, &r); + libj2_j2u_to_j2i(&r, res); res->high |= UINTMAX_MAX << (LIBJ2_JU_BIT - b); } else { *res = *a; @@ -1146,14 +1157,20 @@ libj2_ji_rsh_to_j2i(intmax_t a, unsigned b, struct libj2_j2i *res) inline int libj2_j2i_rsh_to_j2i_underflow(const struct libj2_j2i *a, unsigned b, struct libj2_j2i *res) { + struct libj2_j2u u, r; + libj2_j2i_to_j2u(a, &u); if (libj2_j2i_is_negative(a)) { int underflow; - libj2_not_j2u_to_j2u((const void *)a, (void *)res); - underflow = libj2_j2u_rsh_underflow((void *)res, b); - libj2_not_j2u((void *)res); + libj2_not_j2u_to_j2u(&u, &r); + underflow = libj2_j2u_rsh_underflow(&r, b); + libj2_not_j2u(&r); + libj2_j2u_to_j2i(&r, res); return -underflow; } else { - return libj2_j2u_rsh_to_j2u_underflow((const void *)a, b, (void *)res); + int ret; + ret = libj2_j2u_rsh_to_j2u_underflow(&u, b, &r); + libj2_j2u_to_j2i(&r, res); + return ret; } } @@ -1254,12 +1271,12 @@ libj2_ji_rsh_to_j2i_underflow(intmax_t a, unsigned b, struct libj2_j2i *res) LIBJ2_PURE_ inline int libj2_j2i_rsh_underflow_p(const struct libj2_j2i *a, unsigned b) { + struct libj2_j2u u = {.high = a->high, .low = a->low}; if (libj2_j2i_is_negative(a)) { - struct libj2_j2u t; - libj2_not_j2u_to_j2u((const void *)a, &t); - return -libj2_j2u_rsh_underflow_p(&t, b); + libj2_not_j2u(&u); + return -libj2_j2u_rsh_underflow_p(&u, b); } else { - return libj2_j2u_rsh_underflow_p((const void *)a, b); + return libj2_j2u_rsh_underflow_p(&u, b); } } diff --git a/libj2/division.h b/libj2/division.h index 603a1b6..688768d 100644 --- a/libj2/division.h +++ b/libj2/division.h @@ -349,7 +349,7 @@ libj2_j2u_div_j2u_to_j2u(const struct libj2_j2u *a, const struct libj2_j2u *b, s * * @since 1.0 */ -inline uintmax_t +LIBJ2_PURE_ inline uintmax_t libj2_j2u_div_j2u_return(const struct libj2_j2u *a, const struct libj2_j2u *b) { struct libj2_j2u c = *a; @@ -441,7 +441,7 @@ libj2_j2u_div_ju_to_j2u(const struct libj2_j2u *a, uintmax_t b, struct libj2_j2u * * @since 1.0 */ -inline uintmax_t +LIBJ2_PURE_ inline uintmax_t libj2_j2u_div_ju_return(const struct libj2_j2u *a, uintmax_t b) { struct libj2_j2u c = *a; @@ -733,14 +733,17 @@ libj2_j2i_divmod_j2i_to_j2i(struct libj2_j2i *a, const struct libj2_j2i *b, stru { int a_neg = libj2_j2i_is_negative(a); int b_neg = libj2_j2i_is_negative(b); - struct libj2_j2u u; + struct libj2_j2u u, v, rq; if (b_neg) - libj2_minus_j2i_to_j2u(b, &u); + libj2_minus_j2i_to_j2u(b, &v); else - libj2_j2i_to_j2u(b, &u); + libj2_j2i_to_j2u(b, &v); if (a_neg) libj2_minus_j2i(a); - libj2_j2u_divmod_j2u_to_j2u((void *)a, &u, (void *)res_q); + libj2_j2i_to_j2u(a, &u); + libj2_j2u_divmod_j2u_to_j2u(&u, &v, &rq); + libj2_j2u_to_j2i(&u, a); + libj2_j2u_to_j2i(&rq, res_q); if (a_neg) libj2_minus_j2i(a); if (a_neg != b_neg) @@ -851,14 +854,17 @@ inline intmax_t libj2_j2i_divmod_ji(struct libj2_j2i *a, intmax_t b) { int a_neg = libj2_j2i_is_negative(a); - uintmax_t u, q; + struct libj2_j2u u; + uintmax_t v, q; if (a_neg) libj2_minus_j2i(a); if (b < 0) - u = (uintmax_t)-(b + 1) + 1U; + v = (uintmax_t)-(b + 1) + 1U; else - u = (uintmax_t)b; - q = libj2_j2u_divmod_ju((void *)a, u); + v = (uintmax_t)b; + libj2_j2i_to_j2u(a, &u); + q = libj2_j2u_divmod_ju(&u, v); + libj2_j2u_to_j2i(&u, a); if (a_neg) libj2_minus_j2i(a); return a_neg != (b < 0) ? -(intmax_t)q : (intmax_t)q; @@ -891,15 +897,18 @@ inline void libj2_j2i_divmod_ji_to_j2i(struct libj2_j2i *a, intmax_t b, struct libj2_j2i *res_q) { int a_neg = libj2_j2i_is_negative(a); - uintmax_t u; + struct libj2_j2u u; + uintmax_t v; if (a_neg) libj2_minus_j2i(a); if (b < 0) - u = (uintmax_t)-(b + 1) + 1U; + v = (uintmax_t)-(b + 1) + 1U; else - u = (uintmax_t)b; - res_q->high = a->high / u; - res_q->low = libj2_j2u_divmod_ju((void *)a, u); + v = (uintmax_t)b; + libj2_j2i_to_j2u(a, &u); + res_q->high = a->high / v; + res_q->low = libj2_j2u_divmod_ju(&u, v); + libj2_j2u_to_j2i(&u, a); if (a_neg) libj2_minus_j2i(a); if (a_neg != (b < 0)) @@ -933,17 +942,19 @@ inline void libj2_j2i_divmod_ji_to_j2i_j2i(const struct libj2_j2i *a, intmax_t b, struct libj2_j2i *res_q, struct libj2_j2i *res_r) { int a_neg = libj2_j2i_is_negative(a); + struct libj2_j2u rr; uintmax_t u; if (a_neg) - libj2_minus_j2i_to_j2u(a, (void *)res_r); + libj2_minus_j2i_to_j2u(a, &rr); else - *res_r = *a; + libj2_j2i_to_j2u(a, &rr); if (b < 0) u = (uintmax_t)-(b + 1) + 1U; else u = (uintmax_t)b; - res_q->high = res_r->high / u; - res_q->low = libj2_j2u_divmod_ju((void *)res_r, u); + res_q->high = rr.high / u; + res_q->low = libj2_j2u_divmod_ju(&rr, u); + libj2_j2u_to_j2i(&rr, res_r); if (a_neg) libj2_minus_j2i(res_r); if (a_neg != (b < 0)) @@ -1088,7 +1099,7 @@ libj2_j2i_div_j2i_to_j2i(const struct libj2_j2i *a, const struct libj2_j2i *b, s * * @since 1.1 */ -inline intmax_t +LIBJ2_PURE_ inline intmax_t libj2_j2i_div_j2i_return(const struct libj2_j2i *a, const struct libj2_j2i *b) { struct libj2_j2i c = *a; @@ -1188,7 +1199,7 @@ libj2_j2i_div_ji_to_j2i(const struct libj2_j2i *a, intmax_t b, struct libj2_j2i * * @since 1.1 */ -inline intmax_t +LIBJ2_PURE_ inline intmax_t libj2_j2i_div_ji_return(const struct libj2_j2i *a, intmax_t b) { struct libj2_j2i c = *a; @@ -1287,14 +1298,17 @@ inline void libj2_j2i_mod_ji(struct libj2_j2i *a, intmax_t b) { int a_neg = libj2_j2i_is_negative(a); - uintmax_t u; + struct libj2_j2u u; + uintmax_t v; if (a_neg) libj2_minus_j2i(a); if (b < 0) - u = (uintmax_t)-(b + 1) + 1U; + v = (uintmax_t)-(b + 1) + 1U; else - u = (uintmax_t)b; - libj2_j2u_mod_ju((void *)a, u); + v = (uintmax_t)b; + libj2_j2i_to_j2u(a, &u); + libj2_j2u_mod_ju(&u, v); + libj2_j2u_to_j2i(&u, a); if (a_neg) libj2_minus_j2i(a); } diff --git a/libj2/mixed-comparison.h b/libj2/mixed-comparison.h index dedf18d..525e069 100644 --- a/libj2/mixed-comparison.h +++ b/libj2/mixed-comparison.h @@ -19,7 +19,10 @@ LIBJ2_PURE_ inline int libj2_j2i_lt_j2u(const struct libj2_j2i *a, const struct libj2_j2u *b) { - return libj2_j2i_is_negative(a) ? 1 : libj2_j2u_lt_j2u((const void *)a, b); + struct libj2_j2u u = {.high = a->high, .low = a->low}; + if (libj2_j2i_is_negative(a)) + return 1; + return libj2_j2u_lt_j2u(&u, b); } @@ -38,7 +41,10 @@ libj2_j2i_lt_j2u(const struct libj2_j2i *a, const struct libj2_j2u *b) LIBJ2_PURE_ inline int libj2_j2i_le_j2u(const struct libj2_j2i *a, const struct libj2_j2u *b) { - return libj2_j2i_is_negative(a) ? 1 : libj2_j2u_le_j2u((const void *)a, b); + struct libj2_j2u u = {.high = a->high, .low = a->low}; + if (libj2_j2i_is_negative(a)) + return 1; + return libj2_j2u_le_j2u(&u, b); } @@ -57,7 +63,10 @@ libj2_j2i_le_j2u(const struct libj2_j2i *a, const struct libj2_j2u *b) LIBJ2_PURE_ inline int libj2_j2i_gt_j2u(const struct libj2_j2i *a, const struct libj2_j2u *b) { - return libj2_j2i_is_negative(a) ? 0 : libj2_j2u_gt_j2u((const void *)a, b); + struct libj2_j2u u = {.high = a->high, .low = a->low}; + if (libj2_j2i_is_negative(a)) + return 0; + return libj2_j2u_gt_j2u(&u, b); } @@ -76,7 +85,10 @@ libj2_j2i_gt_j2u(const struct libj2_j2i *a, const struct libj2_j2u *b) LIBJ2_PURE_ inline int libj2_j2i_ge_j2u(const struct libj2_j2i *a, const struct libj2_j2u *b) { - return libj2_j2i_is_negative(a) ? 0 : libj2_j2u_ge_j2u((const void *)a, b); + struct libj2_j2u u = {.high = a->high, .low = a->low}; + if (libj2_j2i_is_negative(a)) + return 0; + return libj2_j2u_ge_j2u(&u, b); } @@ -95,7 +107,10 @@ libj2_j2i_ge_j2u(const struct libj2_j2i *a, const struct libj2_j2u *b) LIBJ2_PURE_ inline int libj2_j2i_eq_j2u(const struct libj2_j2i *a, const struct libj2_j2u *b) { - return libj2_j2i_is_negative(a) ? 0 : libj2_j2u_eq_j2u((const void *)a, b); + struct libj2_j2u u = {.high = a->high, .low = a->low}; + if (libj2_j2i_is_negative(a)) + return 0; + return libj2_j2u_eq_j2u(&u, b); } @@ -114,7 +129,10 @@ libj2_j2i_eq_j2u(const struct libj2_j2i *a, const struct libj2_j2u *b) LIBJ2_PURE_ inline int libj2_j2i_ne_j2u(const struct libj2_j2i *a, const struct libj2_j2u *b) { - return libj2_j2i_is_negative(a) ? 1 : libj2_j2u_ne_j2u((const void *)a, b); + struct libj2_j2u u = {.high = a->high, .low = a->low}; + if (libj2_j2i_is_negative(a)) + return 1; + return libj2_j2u_ne_j2u(&u, b); } @@ -136,7 +154,10 @@ libj2_j2i_ne_j2u(const struct libj2_j2i *a, const struct libj2_j2u *b) LIBJ2_PURE_ inline int libj2_j2i_cmp_j2u(const struct libj2_j2i *a, const struct libj2_j2u *b) { - return libj2_j2i_is_negative(a) ? -1 : libj2_j2u_cmp_j2u((const void *)a, b); + struct libj2_j2u u = {.high = a->high, .low = a->low}; + if (libj2_j2i_is_negative(a)) + return -1; + return libj2_j2u_cmp_j2u(&u, b); } @@ -155,7 +176,10 @@ libj2_j2i_cmp_j2u(const struct libj2_j2i *a, const struct libj2_j2u *b) LIBJ2_PURE_ inline int libj2_j2u_lt_j2i(const struct libj2_j2u *a, const struct libj2_j2i *b) { - return libj2_j2i_is_negative(b) ? 0 : libj2_j2u_lt_j2u(a, (const void *)b); + struct libj2_j2u u = {.high = b->high, .low = b->low}; + if (libj2_j2i_is_negative(b)) + return 0; + return libj2_j2u_lt_j2u(a, &u); } @@ -174,7 +198,10 @@ libj2_j2u_lt_j2i(const struct libj2_j2u *a, const struct libj2_j2i *b) LIBJ2_PURE_ inline int libj2_j2u_le_j2i(const struct libj2_j2u *a, const struct libj2_j2i *b) { - return libj2_j2i_is_negative(b) ? 0 : libj2_j2u_le_j2u(a, (const void *)b); + struct libj2_j2u u = {.high = b->high, .low = b->low}; + if (libj2_j2i_is_negative(b)) + return 0; + return libj2_j2u_le_j2u(a, &u); } @@ -193,7 +220,10 @@ libj2_j2u_le_j2i(const struct libj2_j2u *a, const struct libj2_j2i *b) LIBJ2_PURE_ inline int libj2_j2u_gt_j2i(const struct libj2_j2u *a, const struct libj2_j2i *b) { - return libj2_j2i_is_negative(b) ? 1 : libj2_j2u_gt_j2u(a, (const void *)b); + struct libj2_j2u u = {.high = b->high, .low = b->low}; + if (libj2_j2i_is_negative(b)) + return 1; + return libj2_j2u_gt_j2u(a, &u); } @@ -212,7 +242,10 @@ libj2_j2u_gt_j2i(const struct libj2_j2u *a, const struct libj2_j2i *b) LIBJ2_PURE_ inline int libj2_j2u_ge_j2i(const struct libj2_j2u *a, const struct libj2_j2i *b) { - return libj2_j2i_is_negative(b) ? 1 : libj2_j2u_ge_j2u(a, (const void *)b); + struct libj2_j2u u = {.high = b->high, .low = b->low}; + if (libj2_j2i_is_negative(b)) + return 1; + return libj2_j2u_ge_j2u(a, &u); } @@ -231,7 +264,10 @@ libj2_j2u_ge_j2i(const struct libj2_j2u *a, const struct libj2_j2i *b) LIBJ2_PURE_ inline int libj2_j2u_eq_j2i(const struct libj2_j2u *a, const struct libj2_j2i *b) { - return libj2_j2i_is_negative(b) ? 0 : libj2_j2u_eq_j2u(a, (const void *)b); + struct libj2_j2u u = {.high = b->high, .low = b->low}; + if (libj2_j2i_is_negative(b)) + return 0; + return libj2_j2u_eq_j2u(a, &u); } @@ -250,7 +286,10 @@ libj2_j2u_eq_j2i(const struct libj2_j2u *a, const struct libj2_j2i *b) LIBJ2_PURE_ inline int libj2_j2u_ne_j2i(const struct libj2_j2u *a, const struct libj2_j2i *b) { - return libj2_j2i_is_negative(b) ? 1 : libj2_j2u_ne_j2u(a, (const void *)b); + struct libj2_j2u u = {.high = b->high, .low = b->low}; + if (libj2_j2i_is_negative(b)) + return 1; + return libj2_j2u_ne_j2u(a, &u); } @@ -272,7 +311,10 @@ libj2_j2u_ne_j2i(const struct libj2_j2u *a, const struct libj2_j2i *b) LIBJ2_PURE_ inline int libj2_j2u_cmp_j2i(const struct libj2_j2u *a, const struct libj2_j2i *b) { - return libj2_j2i_is_negative(b) ? +1 : libj2_j2u_cmp_j2u(a, (const void *)b); + struct libj2_j2u u = {.high = b->high, .low = b->low}; + if (libj2_j2i_is_negative(b)) + return +1; + return libj2_j2u_cmp_j2u(a, &u); } @@ -427,7 +469,10 @@ libj2_ji_cmp_j2u(intmax_t a, const struct libj2_j2u *b) LIBJ2_PURE_ inline int libj2_ju_lt_j2i(uintmax_t a, const struct libj2_j2i *b) { - return libj2_j2i_is_negative(b) ? 0 : libj2_ju_lt_j2u(a, (const void *)b); + struct libj2_j2u u = {.high = b->high, .low = b->low}; + if (libj2_j2i_is_negative(b)) + return 0; + return libj2_ju_lt_j2u(a, &u); } @@ -446,7 +491,10 @@ libj2_ju_lt_j2i(uintmax_t a, const struct libj2_j2i *b) LIBJ2_PURE_ inline int libj2_ju_le_j2i(uintmax_t a, const struct libj2_j2i *b) { - return libj2_j2i_is_negative(b) ? 0 : libj2_ju_le_j2u(a, (const void *)b); + struct libj2_j2u u = {.high = b->high, .low = b->low}; + if (libj2_j2i_is_negative(b)) + return 0; + return libj2_ju_le_j2u(a, &u); } @@ -465,7 +513,10 @@ libj2_ju_le_j2i(uintmax_t a, const struct libj2_j2i *b) LIBJ2_PURE_ inline int libj2_ju_gt_j2i(uintmax_t a, const struct libj2_j2i *b) { - return libj2_j2i_is_negative(b) ? 1 : libj2_ju_gt_j2u(a, (const void *)b); + struct libj2_j2u u = {.high = b->high, .low = b->low}; + if (libj2_j2i_is_negative(b)) + return 1; + return libj2_ju_gt_j2u(a, &u); } @@ -484,7 +535,10 @@ libj2_ju_gt_j2i(uintmax_t a, const struct libj2_j2i *b) LIBJ2_PURE_ inline int libj2_ju_ge_j2i(uintmax_t a, const struct libj2_j2i *b) { - return libj2_j2i_is_negative(b) ? 1 : libj2_ju_ge_j2u(a, (const void *)b); + struct libj2_j2u u = {.high = b->high, .low = b->low}; + if (libj2_j2i_is_negative(b)) + return 1; + return libj2_ju_ge_j2u(a, &u); } @@ -503,7 +557,10 @@ libj2_ju_ge_j2i(uintmax_t a, const struct libj2_j2i *b) LIBJ2_PURE_ inline int libj2_ju_eq_j2i(uintmax_t a, const struct libj2_j2i *b) { - return libj2_j2i_is_negative(b) ? 0 : libj2_ju_eq_j2u(a, (const void *)b); + struct libj2_j2u u = {.high = b->high, .low = b->low}; + if (libj2_j2i_is_negative(b)) + return 0; + return libj2_ju_eq_j2u(a, &u); } @@ -522,7 +579,10 @@ libj2_ju_eq_j2i(uintmax_t a, const struct libj2_j2i *b) LIBJ2_PURE_ inline int libj2_ju_ne_j2i(uintmax_t a, const struct libj2_j2i *b) { - return libj2_j2i_is_negative(b) ? 1 : libj2_ju_ne_j2u(a, (const void *)b); + struct libj2_j2u u = {.high = b->high, .low = b->low}; + if (libj2_j2i_is_negative(b)) + return 1; + return libj2_ju_ne_j2u(a, &u); } @@ -544,7 +604,10 @@ libj2_ju_ne_j2i(uintmax_t a, const struct libj2_j2i *b) LIBJ2_PURE_ inline int libj2_ju_cmp_j2i(uintmax_t a, const struct libj2_j2i *b) { - return libj2_j2i_is_negative(b) ? +1 : libj2_ju_cmp_j2u(a, (const void *)b); + struct libj2_j2u u = {.high = b->high, .low = b->low}; + if (libj2_j2i_is_negative(b)) + return +1; + return libj2_ju_cmp_j2u(a, &u); } @@ -563,7 +626,10 @@ libj2_ju_cmp_j2i(uintmax_t a, const struct libj2_j2i *b) LIBJ2_PURE_ inline int libj2_j2i_lt_ju(const struct libj2_j2i *a, uintmax_t b) { - return libj2_j2i_is_negative(a) ? 1 : libj2_j2u_lt_ju((const void *)a, b); + struct libj2_j2u u = {.high = a->high, .low = a->low}; + if (libj2_j2i_is_negative(a)) + return 1; + return libj2_j2u_lt_ju(&u, b); } @@ -582,7 +648,10 @@ libj2_j2i_lt_ju(const struct libj2_j2i *a, uintmax_t b) LIBJ2_PURE_ inline int libj2_j2i_le_ju(const struct libj2_j2i *a, uintmax_t b) { - return libj2_j2i_is_negative(a) ? 1 : libj2_j2u_le_ju((const void *)a, b); + struct libj2_j2u u = {.high = a->high, .low = a->low}; + if (libj2_j2i_is_negative(a)) + return 1; + return libj2_j2u_le_ju(&u, b); } @@ -601,7 +670,10 @@ libj2_j2i_le_ju(const struct libj2_j2i *a, uintmax_t b) LIBJ2_PURE_ inline int libj2_j2i_gt_ju(const struct libj2_j2i *a, uintmax_t b) { - return libj2_j2i_is_negative(a) ? 0 : libj2_j2u_gt_ju((const void *)a, b); + struct libj2_j2u u = {.high = a->high, .low = a->low}; + if (libj2_j2i_is_negative(a)) + return 0; + return libj2_j2u_gt_ju(&u, b); } @@ -620,7 +692,10 @@ libj2_j2i_gt_ju(const struct libj2_j2i *a, uintmax_t b) LIBJ2_PURE_ inline int libj2_j2i_ge_ju(const struct libj2_j2i *a, uintmax_t b) { - return libj2_j2i_is_negative(a) ? 0 : libj2_j2u_ge_ju((const void *)a, b); + struct libj2_j2u u = {.high = a->high, .low = a->low}; + if (libj2_j2i_is_negative(a)) + return 0; + return libj2_j2u_ge_ju(&u, b); } @@ -639,7 +714,10 @@ libj2_j2i_ge_ju(const struct libj2_j2i *a, uintmax_t b) LIBJ2_PURE_ inline int libj2_j2i_eq_ju(const struct libj2_j2i *a, uintmax_t b) { - return libj2_j2i_is_negative(a) ? 0 : libj2_j2u_eq_ju((const void *)a, b); + struct libj2_j2u u = {.high = a->high, .low = a->low}; + if (libj2_j2i_is_negative(a)) + return 0; + return libj2_j2u_eq_ju(&u, b); } @@ -658,7 +736,10 @@ libj2_j2i_eq_ju(const struct libj2_j2i *a, uintmax_t b) LIBJ2_PURE_ inline int libj2_j2i_ne_ju(const struct libj2_j2i *a, uintmax_t b) { - return libj2_j2i_is_negative(a) ? 1 : libj2_j2u_ne_ju((const void *)a, b); + struct libj2_j2u u = {.high = a->high, .low = a->low}; + if (libj2_j2i_is_negative(a)) + return 1; + return libj2_j2u_ne_ju(&u, b); } @@ -680,7 +761,10 @@ libj2_j2i_ne_ju(const struct libj2_j2i *a, uintmax_t b) LIBJ2_PURE_ inline int libj2_j2i_cmp_ju(const struct libj2_j2i *a, uintmax_t b) { - return libj2_j2i_is_negative(a) ? -1 : libj2_j2u_cmp_ju((const void *)a, b); + struct libj2_j2u u = {.high = a->high, .low = a->low}; + if (libj2_j2i_is_negative(a)) + return -1; + return libj2_j2u_cmp_ju(&u, b); } diff --git a/libj2/multiplication.h b/libj2/multiplication.h index a80161b..40d9eb0 100644 --- a/libj2/multiplication.h +++ b/libj2/multiplication.h @@ -667,18 +667,24 @@ libj2_ju_mul_j2u_to_j2u_overflow_p(uintmax_t a, const struct libj2_j2u *b, struc inline int libj2_j2i_mul_j2i_overflow(struct libj2_j2i *a, const struct libj2_j2i *b) { - struct libj2_j2u t; + struct libj2_j2u u, v; int overflow, neg = libj2_j2i_is_negative(a); if (neg) libj2_minus_j2i(a); + libj2_j2i_to_j2u(a, &u); if (a == b) { neg = 0; - } else if (libj2_j2i_is_negative(b)) { - neg ^= 1; - libj2_minus_j2i_to_j2u(b, &t); - b = (const void *)&t; + overflow = libj2_j2u_mul_j2u_overflow(&u, &u); + } else { + if (libj2_j2i_is_negative(b)) { + neg ^= 1; + libj2_minus_j2i_to_j2u(b, &v); + } else { + libj2_j2i_to_j2u(b, &v); + } + overflow = libj2_j2u_mul_j2u_overflow(&u, &v); } - overflow = libj2_j2u_mul_j2u_overflow((void *)a, (const void *)b); + libj2_j2u_to_j2i(&u, a); if (neg) { if (overflow) overflow = -overflow; @@ -823,7 +829,11 @@ inline void libj2_ji_mul_ji_to_j2i(intmax_t a, intmax_t b, struct libj2_j2i *res) { int neg = (a < 0) ^ (b < 0); - libj2_ju_mul_ju_to_j2u((uintmax_t)(a < 0 ? -a : a), (uintmax_t)(b < 0 ? -b : b), (void *)res); + uintmax_t u = a < 0 ? (uintmax_t)-(a + 1) + 1U : (uintmax_t)a; + uintmax_t v = b < 0 ? (uintmax_t)-(b + 1) + 1U : (uintmax_t)b; + struct libj2_j2u r; + libj2_ju_mul_ju_to_j2u(u, v, &r); + libj2_j2u_to_j2i(&r, res); if (neg) libj2_minus_j2i(res); } @@ -847,13 +857,19 @@ inline void libj2_j2i_mul_ji(struct libj2_j2i *a, intmax_t b) { int neg = libj2_j2i_is_negative(a); + struct libj2_j2u u; + uintmax_t v; if (neg) libj2_minus_j2i(a); if (b < 0) { neg ^= 1; - b = -b; + v = (uintmax_t)-(b + 1) + 1U; + } else { + v = (uintmax_t)b; } - libj2_j2u_mul_ju((void *)a, (uintmax_t)b); + libj2_j2i_to_j2u(a, &u); + libj2_j2u_mul_ju(&u, v); + libj2_j2u_to_j2i(&u, a); if (neg) libj2_minus_j2i(a); } @@ -1000,18 +1016,24 @@ libj2_ji_mul_j2i_to_j2i_overflow(intmax_t a, const struct libj2_j2i *b, struct l inline void libj2_j2i_mul_j2i(struct libj2_j2i *a, const struct libj2_j2i *b) { - struct libj2_j2u t; + struct libj2_j2u u, v; int neg = libj2_j2i_is_negative(a); if (neg) libj2_minus_j2i(a); + libj2_j2i_to_j2u(a, &u); if (a == b) { neg = 0; - } else if (libj2_j2i_is_negative(b)) { - neg ^= 1; - libj2_minus_j2i_to_j2u(b, &t); - b = (const void *)&t; + libj2_j2u_mul_j2u(&u, &u); + } else { + if (libj2_j2i_is_negative(b)) { + neg ^= 1; + libj2_minus_j2i_to_j2u(b, &v); + } else { + libj2_j2i_to_j2u(b, &v); + } + libj2_j2u_mul_j2u(&u, &v); } - libj2_j2u_mul_j2u((void *)a, (const void *)b); + libj2_j2u_to_j2i(&u, a); if (neg) libj2_minus_j2i(a); } @@ -1040,12 +1062,15 @@ libj2_j2i_mul_j2i_to_j2i(const struct libj2_j2i *a, const struct libj2_j2i *b, s b = a; goto common; } else if (a == b) { + struct libj2_j2u u, r; if (libj2_j2i_is_negative(a)) { - libj2_minus_j2i_to_j2u(a, (void *)res); - libj2_j2u_mul_j2u((void *)res, (const void *)res); + libj2_minus_j2i_to_j2u(a, &r); + libj2_j2u_mul_j2u(&r, &r); } else { - libj2_j2u_mul_j2u_to_j2u((const void *)a, (const void *)b, (void *)res); + libj2_j2i_to_j2u(a, &u); + libj2_j2u_mul_j2u_to_j2u(&u, &u, &r); } + libj2_j2u_to_j2i(&r, res); } else { *res = *a; goto common; diff --git a/libj2/sign-shifting.h b/libj2/sign-shifting.h index 75a4620..9ffd301 100644 --- a/libj2/sign-shifting.h +++ b/libj2/sign-shifting.h @@ -61,7 +61,10 @@ libj2_minus_j2u(struct libj2_j2u *a) inline void libj2_minus_j2i_to_j2i(const struct libj2_j2i *a, struct libj2_j2i *res) { - libj2_minus_j2u_to_j2u((const void *)a, (void *)res); + res->high = -a->high; + if (a->low) + res->high -= 1U; + res->low = -a->low; } @@ -81,7 +84,7 @@ libj2_minus_j2i_to_j2i(const struct libj2_j2i *a, struct libj2_j2i *res) inline void libj2_minus_j2i(struct libj2_j2i *a) { - libj2_minus_j2u_to_j2u((const void *)a, (void *)a); + libj2_minus_j2i_to_j2i(a, a); } @@ -103,7 +106,10 @@ libj2_minus_j2i(struct libj2_j2i *a) inline void libj2_minus_j2i_to_j2u(const struct libj2_j2i *a, struct libj2_j2u *res) { - libj2_minus_j2u_to_j2u((const void *)a, (void *)res); + res->high = -a->high; + if (a->low) + res->high -= 1U; + res->low = -a->low; } @@ -126,7 +132,10 @@ libj2_minus_j2i_to_j2u(const struct libj2_j2i *a, struct libj2_j2u *res) inline void libj2_minus_j2u_to_j2i(const struct libj2_j2u *a, struct libj2_j2i *res) { - libj2_minus_j2u_to_j2u((const void *)a, (void *)res); + res->high = -a->high; + if (a->low) + res->high -= 1U; + res->low = -a->low; } @@ -186,7 +195,10 @@ libj2_abs_j2i(struct libj2_j2i *a) inline void libj2_abs_j2i_to_j2u(const struct libj2_j2i *a, struct libj2_j2u *res) { - libj2_abs_j2i_to_j2i(a, (void *)res); + if (libj2_j2i_is_negative(a)) + libj2_minus_j2i_to_j2u(a, res); + else + libj2_j2i_to_j2u(a, res); } @@ -240,17 +252,18 @@ libj2_minus_abs_j2i(struct libj2_j2i *a) * * @param a The integer to conditionally invert * @param res Output parameter for the sign-xor - * @param res Output parameter for the inverse * * @since 1.1 */ inline void libj2_j2i_xor_sign_to_j2i(const struct libj2_j2i *a, struct libj2_j2i *res) { - if (libj2_j2i_is_negative(a)) - libj2_not_j2u_to_j2u((const void *)a, (void *)res); - else + if (libj2_j2i_is_negative(a)) { + res->high = ~a->high; + res->low = ~a->low; + } else { *res = *a; + } } @@ -266,7 +279,13 @@ libj2_j2i_xor_sign_to_j2i(const struct libj2_j2i *a, struct libj2_j2i *res) inline void libj2_j2i_xor_sign_to_j2u(const struct libj2_j2i *a, struct libj2_j2u *res) { - libj2_j2i_xor_sign_to_j2i(a, (void *)res); + if (libj2_j2i_is_negative(a)) { + res->high = ~a->high; + res->low = ~a->low; + } else { + res->high = a->high; + res->low = a->low; + } } @@ -283,6 +302,8 @@ libj2_j2i_xor_sign_to_j2u(const struct libj2_j2i *a, struct libj2_j2u *res) inline void libj2_j2i_xor_sign(struct libj2_j2i *a) { - if (libj2_j2i_is_negative(a)) - libj2_not_j2u((void *)a); + if (libj2_j2i_is_negative(a)) { + a->high = ~a->high; + a->low = ~a->low; + } } diff --git a/libj2/signed-comparison.h b/libj2/signed-comparison.h index 9d8025c..916edac 100644 --- a/libj2/signed-comparison.h +++ b/libj2/signed-comparison.h @@ -25,7 +25,7 @@ libj2_j2i_cmp_j2i(const struct libj2_j2i *a, const struct libj2_j2i *b) int cmp = libj2_sgn_j2i(a) - libj2_sgn_j2i(b); if (cmp) return cmp < 0 ? -1 : +1; - return libj2_j2u_cmp_j2u((const void *)a, (const void *)b); + return a->high < b->high ? -1 : a->high > b->high ? +1 : a->low < b->low ? -1 : a->low > b->low; } @@ -120,7 +120,7 @@ libj2_j2i_ge_j2i(const struct libj2_j2i *a, const struct libj2_j2i *b) LIBJ2_PURE_ inline int libj2_j2i_eq_j2i(const struct libj2_j2i *a, const struct libj2_j2i *b) { - return libj2_j2u_eq_j2u((const void *)a, (const void *)b); + return a->high == b->high && a->low == b->low; } @@ -139,7 +139,7 @@ libj2_j2i_eq_j2i(const struct libj2_j2i *a, const struct libj2_j2i *b) LIBJ2_PURE_ inline int libj2_j2i_ne_j2i(const struct libj2_j2i *a, const struct libj2_j2i *b) { - return libj2_j2u_ne_j2u((const void *)a, (const void *)b); + return a->high != b->high || a->low != b->low; } diff --git a/libj2/strings.h b/libj2/strings.h index 05ccc80..4b77725 100644 --- a/libj2/strings.h +++ b/libj2/strings.h @@ -197,8 +197,10 @@ libj2_j2i_to_str(const struct libj2_j2i *a, char *buf, size_t bufsize, const cha char *sigc; struct libj2_j2u t; size_t r; - if (!libj2_j2i_is_negative(a)) - return libj2_j2u_to_str((const void *)a, buf, bufsize, digits); + if (!libj2_j2i_is_negative(a)) { + libj2_j2i_to_j2u(a, &t); + return libj2_j2u_to_str(&t, buf, bufsize, digits); + } libj2_minus_j2i_to_j2u(a, &t); if (bufsize > 1U) { bufsize -= 1U; diff --git a/libj2/subtraction.h b/libj2/subtraction.h index c4291d1..2a7ff06 100644 --- a/libj2/subtraction.h +++ b/libj2/subtraction.h @@ -672,7 +672,11 @@ libj2_j2u_rsub_ju_overflow_p(const struct libj2_j2u *a, uintmax_t b) inline void libj2_j2i_sub_j2i_to_j2i(const struct libj2_j2i *a, const struct libj2_j2i *b, struct libj2_j2i *res) { - libj2_j2u_sub_j2u_to_j2u((const void *)a, (const void *)b, (void *)res); + struct libj2_j2u u, v, r; + libj2_j2i_to_j2u(a, &u); + libj2_j2i_to_j2u(b, &v); + libj2_j2u_sub_j2u_to_j2u(&u, &v, &r); + libj2_j2u_to_j2i(&r, res); } @@ -762,7 +766,11 @@ libj2_ji_sub_ji_to_j2i(intmax_t a, intmax_t b, struct libj2_j2i *res) inline void libj2_j2i_sub_j2i(struct libj2_j2i *a, const struct libj2_j2i *b) { - libj2_j2u_sub_j2u((void *)a, (const void *)b); + struct libj2_j2u u, v; + libj2_j2i_to_j2u(a, &u); + libj2_j2i_to_j2u(b, &v); + libj2_j2u_sub_j2u(&u, &v); + libj2_j2u_to_j2i(&u, a); } @@ -1240,7 +1248,7 @@ libj2_j2u_rsub_j2u_borrow(struct libj2_j2u *a, const struct libj2_j2u *b, int *b * @param a The minuend (left-hand) * @param b The subtrahend (right-hand) * @param res The output parameter for the difference - * @param borrow Shall point to the value +1, -1, or 0: + * @param carry Shall point to the value +1, -1, or 0: * the result will be incremented * with the value. When the function * returns, it will be updated to +1 @@ -1369,10 +1377,12 @@ libj2_j2u_abs_diff_j2u(struct libj2_j2u *a, const struct libj2_j2u *b) inline void libj2_j2i_abs_diff_j2i_to_j2u(const struct libj2_j2i *a, const struct libj2_j2i *b, struct libj2_j2u *res) { + struct libj2_j2i r; if (libj2_j2i_ge_j2i(a, b)) - libj2_j2i_sub_j2i_to_j2i(a, b, (void *)res); + libj2_j2i_sub_j2i_to_j2i(a, b, &r); else - libj2_j2i_sub_j2i_to_j2i(b, a, (void *)res); + libj2_j2i_sub_j2i_to_j2i(b, a, &r); + libj2_j2i_to_j2u(&r, res); } diff --git a/libj2_abs_j2i.c b/libj2_abs_j2i.c index e3c9d33..13965e0 100644 --- a/libj2_abs_j2i.c +++ b/libj2_abs_j2i.c @@ -88,7 +88,7 @@ check_min(void) const uintmax_t high = ~(UINTMAX_MAX >> 1); const uintmax_t low = 0; struct libj2_j2i a, r; - struct libj2_j2u u; + struct libj2_j2u u, v; a.high = high; a.low = low; @@ -110,7 +110,8 @@ check_min(void) libj2_abs_j2i_to_j2u((const struct libj2_j2i *)&a, &u); EXPECT(a.high == high); EXPECT(a.low == low); - EXPECT(libj2_j2u_eq_j2u((const void *)&a, &u)); + libj2_j2i_to_j2u(&a, &v); + EXPECT(libj2_j2u_eq_j2u(&v, &u)); a.high = high; a.low = low; diff --git a/libj2_j2i_add_ji.c b/libj2_j2i_add_ji.c index d1e7e32..1fd5af9 100644 --- a/libj2_j2i_add_ji.c +++ b/libj2_j2i_add_ji.c @@ -65,7 +65,7 @@ self_check(uintmax_t a_high, uintmax_t a_low, uintmax_t b_high, uintmax_t b_low, static void check(uintmax_t a_high, uintmax_t a_low, uintmax_t ub) { - intmax_t b = ub > (uintmax_t)INTMAX_MAX ? (intmax_t)ub : -(intmax_t)~ub - 1; + intmax_t b = ub > (uintmax_t)INTMAX_MAX ? -(intmax_t)~ub - 1 : (intmax_t)ub; struct libj2_j2i a, r; uintmax_t expected_high, expected_low; int expected_overflow; diff --git a/libj2_j2i_divmod_j2i_to_j2i.c b/libj2_j2i_divmod_j2i_to_j2i.c index 1a55f41..ef46f97 100644 --- a/libj2_j2i_divmod_j2i_to_j2i.c +++ b/libj2_j2i_divmod_j2i_to_j2i.c @@ -383,7 +383,7 @@ check(const struct libj2_j2i *a, const struct libj2_j2i *b) v.high = random_ju(); v.low = random_ju(); } while (!v.high && !v.low); - b = &u; + b = &v; } check_manual(a, b, NULL, NULL); } diff --git a/libj2_j2i_lsh.c b/libj2_j2i_lsh.c index aff86bb..0184e2d 100644 --- a/libj2_j2i_lsh.c +++ b/libj2_j2i_lsh.c @@ -90,7 +90,7 @@ int main(void) { struct libj2_j2i a, b; - struct libj2_j2u t; + struct libj2_j2u u, v, t; unsigned i, j, k, s; int overflow; @@ -101,29 +101,40 @@ main(void) libj2_j2i_zero(&b); check(&a, j, &b, 0); - libj2_not_j2u((void *)&a); - libj2_not_j2u((void *)&b); - libj2_j2u_lsh((void *)&b, j); + libj2_j2i_to_j2u(&a, &t); + libj2_not_j2u(&t); + libj2_j2u_to_j2i(&t, &a); + libj2_j2i_to_j2u(&b, &t); + libj2_not_j2u(&t); + libj2_j2u_lsh(&t, j); + libj2_j2u_to_j2i(&t, &b); check(&a, j, &b, j >= LIBJ2_J2I_BIT ? -1 : 0); for (i = 0; i < LIBJ2_J2I_BIT; i++) { libj2_j2i_zero(&a); - libj2_j2u_or_bit((void *)&a, i); + libj2_j2i_to_j2u(&a, &t); + libj2_j2u_or_bit(&t, i); + libj2_j2u_to_j2i(&t, &a); libj2_j2i_zero(&b); - if (i + j < LIBJ2_J2I_BIT) - libj2_j2u_or_bit((void *)&b, i + j); + if (i + j < LIBJ2_J2I_BIT) { + libj2_j2i_to_j2u(&b, &t); + libj2_j2u_or_bit(&t, i + j); + libj2_j2u_to_j2i(&t, &b); + } overflow = i == LIBJ2_J2I_VBIT ? j ? -1 : 0 : i + j < LIBJ2_J2I_VBIT ? 0 : +1; check(&a, j, &b, overflow); - libj2_j2i_zero(&a); - libj2_j2u_or_bit((void *)&a, i); - libj2_not_j2u((void *)&a); - libj2_j2i_zero(&b); + libj2_j2u_zero(&t); + libj2_j2u_or_bit(&t, i); + libj2_not_j2u(&t); + libj2_j2u_to_j2i(&t, &a); + libj2_j2u_zero(&t); if (i + j < LIBJ2_J2I_BIT) - libj2_j2u_or_bit((void *)&b, i + j); + libj2_j2u_or_bit(&t, i + j); for (k = 0; k < j; k++) - libj2_j2u_or_bit((void *)&b, k); - libj2_not_j2u((void *)&b); + libj2_j2u_or_bit(&t, k); + libj2_not_j2u(&t); + libj2_j2u_to_j2i(&t, &b); overflow = i == LIBJ2_J2I_VBIT ? j ? +1 : 0 : i + j < LIBJ2_J2I_VBIT ? 0 : -1; check(&a, j, &b, overflow); } @@ -132,24 +143,28 @@ main(void) for (i = 0; i < 32; i++) { for (j = 0; j < LIBJ2_J2I_BIT - 1U; j++) { for (k = 0; k <= LIBJ2_J2I_BIT + 1U; k++) { - libj2_j2i_zero(&a); - libj2_j2i_zero(&b); + libj2_j2u_zero(&u); + libj2_j2u_zero(&v); for (s = 0; s <= j; s++) { if (rand() < rand()) continue; - libj2_j2u_or_bit((void *)&a, s); - libj2_j2u_or_bit((void *)&b, s + k); + libj2_j2u_or_bit(&u, s); + libj2_j2u_or_bit(&v, s + k); } - overflow = libj2_co_j2u((const void *)&a) > libj2_co_j2u((const void *)&b); + libj2_j2u_to_j2i(&u, &a); + libj2_j2u_to_j2i(&v, &b); + overflow = libj2_co_j2u(&u) > libj2_co_j2u(&v); overflow |= libj2_j2i_is_negative(&b); check(&a, k, &b, overflow); - libj2_not_j2u((void *)&a); - libj2_not_j2u((void *)&b); + libj2_not_j2u(&u); + libj2_not_j2u(&v); libj2_ju_lsh_to_j2u(1, k, &t); libj2_j2u_sub_ju(&t, 1); libj2_not_j2u(&t); - libj2_j2u_and_j2u((void *)&b, &t); + libj2_j2u_and_j2u(&v, &t); + libj2_j2u_to_j2i(&u, &a); + libj2_j2u_to_j2i(&v, &b); overflow = -overflow; if (a.high == UINTMAX_MAX && a.low == UINTMAX_MAX && k >= LIBJ2_J2I_BIT) overflow = -1; diff --git a/libj2_j2i_mul_ji.c b/libj2_j2i_mul_ji.c index 9c7ac3c..67de057 100644 --- a/libj2_j2i_mul_ji.c +++ b/libj2_j2i_mul_ji.c @@ -102,8 +102,12 @@ mul_(const struct libj2_j2i *a, intmax_t b, struct libj2_j2i *expected, int expe t = *a; libj2_j2i_sat_mul_ji(&t, b); - EXPECT(expect_overflow > 0 ? libj2_j2i_is_max(&t) : - expect_overflow ? libj2_j2i_is_min(&t) : libj2_j2i_eq_j2i(&t, expected)); + if (expect_overflow > 0) + EXPECT(libj2_j2i_is_max(&t)); + else if (expect_overflow) + EXPECT(libj2_j2i_is_min(&t)); + else + EXPECT(libj2_j2i_eq_j2i(&t, expected)); t = *a; EXPECT(libj2_j2i_mul_ji_overflow_p((const struct libj2_j2i *)&t, b) == expect_overflow); @@ -195,7 +199,7 @@ static void mul(const struct libj2_j2i *a, intmax_t b, struct libj2_j2i *expected, int expect_overflow) { struct libj2_j2i r, neg_a, e; - struct libj2_j2u u; + struct libj2_j2u u, ue; libj2_minus_j2i_to_j2i(a, &neg_a); libj2_j2i_to_j2u(a, &u); @@ -215,7 +219,8 @@ mul(const struct libj2_j2i *a, intmax_t b, struct libj2_j2i *expected, int expec EXPECT(libj2_j2i_eq_j2i(&r, expected)); - expect_overflow = libj2_j2u_mul_ju_to_j2u_overflow(&u, (uintmax_t)b + 1U, (void *)&e); + expect_overflow = libj2_j2u_mul_ju_to_j2u_overflow(&u, (uintmax_t)b + 1U, &ue); + libj2_j2u_to_j2i(&ue, &e); if (libj2_j2i_is_negative(&e)) expect_overflow = 1; @@ -229,7 +234,8 @@ mul(const struct libj2_j2i *a, intmax_t b, struct libj2_j2i *expected, int expec libj2_j2u_add_ju(&u, 1U); libj2_j2i_add_ji(&neg_a, -1); - expect_overflow = libj2_j2u_mul_ju_to_j2u_overflow(&u, (uintmax_t)b, (void *)&e); + expect_overflow = libj2_j2u_mul_ju_to_j2u_overflow(&u, (uintmax_t)b, &ue); + libj2_j2u_to_j2i(&ue, &e); if (libj2_j2i_is_negative(&e)) expect_overflow = 1; @@ -238,7 +244,8 @@ mul(const struct libj2_j2i *a, intmax_t b, struct libj2_j2i *expected, int expec EXPECT(libj2_j2i_eq_j2i(&r, &e)); - expect_overflow = libj2_j2u_mul_ju_to_j2u_overflow(&u, (uintmax_t)b + 1U, (void *)&e); + expect_overflow = libj2_j2u_mul_ju_to_j2u_overflow(&u, (uintmax_t)b + 1U, &ue); + libj2_j2u_to_j2i(&ue, &e); if (libj2_j2i_is_negative(&e)) expect_overflow = 1; diff --git a/libj2_j2i_sub_j2i.c b/libj2_j2i_sub_j2i.c index 24610cd..fbb569c 100644 --- a/libj2_j2i_sub_j2i.c +++ b/libj2_j2i_sub_j2i.c @@ -23,7 +23,7 @@ static void validate(uintmax_t a_high, uintmax_t a_low, uintmax_t b_high, uintmax_t b_low, uintmax_t r_high, uintmax_t r_low, int r_overflow) { int a_neg, b_neg, overflow; - struct libj2_j2u a, b; + struct libj2_j2u a, b, u; struct libj2_j2i t, r; t = (struct libj2_j2i){.high = a_high, .low = a_low}; @@ -41,31 +41,38 @@ validate(uintmax_t a_high, uintmax_t a_low, uintmax_t b_high, uintmax_t b_low, u if (a_neg && b_neg) { overflow = 0; libj2_minus_j2u(&a); - libj2_j2u_add_j2u_to_j2u_overflow(&a, &b, (void *)&r); - EXPECT(libj2_j2i_gt_j2i(&r, (const void *)&a)); + libj2_j2u_add_j2u_to_j2u_overflow(&a, &b, &u); + libj2_j2u_to_j2i(&u, &r); + libj2_j2u_to_j2i(&a, &t); + EXPECT(libj2_j2i_gt_j2i(&r, &t)); } else if (a_neg) { - overflow = -libj2_j2u_add_j2u_to_j2u_overflow(&a, &b, (void *)&r); + overflow = -libj2_j2u_add_j2u_to_j2u_overflow(&a, &b, &u); + libj2_j2u_to_j2i(&u, &r); EXPECT(overflow == 0 || overflow == -1); libj2_minus_j2i(&r); + libj2_j2u_to_j2i(&a, &t); if (!libj2_j2i_is_negative(&r)) overflow = -1; else if (overflow) - EXPECT(libj2_j2i_gt_j2i(&r, (const void *)&a)); + EXPECT(libj2_j2i_gt_j2i(&r, &t)); if (!overflow) - EXPECT(libj2_j2i_le_j2i(&r, (const void *)&a)); + EXPECT(libj2_j2i_le_j2i(&r, &t)); } else if (b_neg) { - overflow = +libj2_j2u_add_j2u_to_j2u_overflow(&a, &b, (void *)&r); + overflow = +libj2_j2u_add_j2u_to_j2u_overflow(&a, &b, &u); + libj2_j2u_to_j2i(&u, &r); EXPECT(overflow == 0 || overflow == +1); + libj2_j2u_to_j2i(&a, &t); if (!libj2_j2i_is_positive(&r)) overflow = +1; else if (overflow) - EXPECT(libj2_j2i_lt_j2i(&r, (const void *)&a)); + EXPECT(libj2_j2i_lt_j2i(&r, &t)); if (!overflow) - EXPECT(libj2_j2i_gt_j2i(&r, (const void *)&a)); + EXPECT(libj2_j2i_gt_j2i(&r, &t)); } else { overflow = 0; libj2_minus_j2u(&b); - libj2_j2u_add_j2u_to_j2u(&a, &b, (void *)&r); + libj2_j2u_add_j2u_to_j2u(&a, &b, &u); + libj2_j2u_to_j2i(&u, &r); EXPECT(libj2_j2i_le_j2u(&r, &a)); } diff --git a/libj2_j2i_sub_ji.c b/libj2_j2i_sub_ji.c index 34222f6..1749c9d 100644 --- a/libj2_j2i_sub_ji.c +++ b/libj2_j2i_sub_ji.c @@ -23,7 +23,7 @@ static void validate(uintmax_t a_high, uintmax_t a_low, uintmax_t b_high, uintmax_t b_low, uintmax_t r_high, uintmax_t r_low, int r_overflow) { int a_neg, b_neg, overflow; - struct libj2_j2u a, b; + struct libj2_j2u a, b, u; struct libj2_j2i t, r; t = (struct libj2_j2i){.high = a_high, .low = a_low}; @@ -41,31 +41,38 @@ validate(uintmax_t a_high, uintmax_t a_low, uintmax_t b_high, uintmax_t b_low, u if (a_neg && b_neg) { overflow = 0; libj2_minus_j2u(&a); - libj2_j2u_add_j2u_to_j2u_overflow(&a, &b, (void *)&r); - EXPECT(libj2_j2i_gt_j2i(&r, (const void *)&a)); + libj2_j2u_add_j2u_to_j2u_overflow(&a, &b, &u); + libj2_j2u_to_j2i(&u, &r); + libj2_j2u_to_j2i(&a, &t); + EXPECT(libj2_j2i_gt_j2i(&r, &t)); } else if (a_neg) { - overflow = -libj2_j2u_add_j2u_to_j2u_overflow(&a, &b, (void *)&r); + overflow = -libj2_j2u_add_j2u_to_j2u_overflow(&a, &b, &u); + libj2_j2u_to_j2i(&u, &r); EXPECT(overflow == 0 || overflow == -1); libj2_minus_j2i(&r); + libj2_j2u_to_j2i(&a, &t); if (!libj2_j2i_is_negative(&r)) overflow = -1; else if (overflow) - EXPECT(libj2_j2i_gt_j2i(&r, (const void *)&a)); + EXPECT(libj2_j2i_gt_j2i(&r, &t)); if (!overflow) - EXPECT(libj2_j2i_le_j2i(&r, (const void *)&a)); + EXPECT(libj2_j2i_le_j2i(&r, &t)); } else if (b_neg) { - overflow = +libj2_j2u_add_j2u_to_j2u_overflow(&a, &b, (void *)&r); + overflow = +libj2_j2u_add_j2u_to_j2u_overflow(&a, &b, &u); EXPECT(overflow == 0 || overflow == +1); + libj2_j2u_to_j2i(&a, &t); + libj2_j2u_to_j2i(&u, &r); if (!libj2_j2i_is_positive(&r)) overflow = +1; else if (overflow) - EXPECT(libj2_j2i_lt_j2i(&r, (const void *)&a)); + EXPECT(libj2_j2i_lt_j2i(&r, &t)); if (!overflow) - EXPECT(libj2_j2i_gt_j2i(&r, (const void *)&a)); + EXPECT(libj2_j2i_gt_j2i(&r, &t)); } else { overflow = 0; libj2_minus_j2u(&b); - libj2_j2u_add_j2u_to_j2u(&a, &b, (void *)&r); + libj2_j2u_add_j2u_to_j2u(&a, &b, &u); + libj2_j2u_to_j2i(&u, &r); EXPECT(libj2_j2i_le_j2u(&r, &a)); } diff --git a/libj2_j2i_xor_sign.c b/libj2_j2i_xor_sign.c index 6826f02..707774c 100644 --- a/libj2_j2i_xor_sign.c +++ b/libj2_j2i_xor_sign.c @@ -23,6 +23,7 @@ static void check(struct libj2_j2i *a) { struct libj2_j2i r, saved, x; + struct libj2_j2u u; saved = *a; @@ -32,7 +33,8 @@ check(struct libj2_j2i *a) EXPECT(libj2_j2i_eq_j2i(&r, &saved)); r = (struct libj2_j2i){111, 222}; - libj2_j2i_xor_sign_to_j2u((const struct libj2_j2i *)a, (struct libj2_j2u *)&r); + libj2_j2i_xor_sign_to_j2u((const struct libj2_j2i *)a, &u); + libj2_j2u_to_j2i(&u, &r); EXPECT(libj2_j2i_eq_j2i(a, &saved)); EXPECT(libj2_j2i_eq_j2i(&r, &saved)); @@ -40,7 +42,9 @@ check(struct libj2_j2i *a) libj2_j2i_xor_sign(&r); EXPECT(libj2_j2i_eq_j2i(&r, &saved)); - libj2_not_j2u((void *)a); + libj2_j2i_to_j2u(a, &u); + libj2_not_j2u(&u); + libj2_j2u_to_j2i(&u, a); x = *a; r = (struct libj2_j2i){111, 222}; @@ -49,7 +53,8 @@ check(struct libj2_j2i *a) EXPECT(libj2_j2i_eq_j2i(&r, &saved)); r = (struct libj2_j2i){111, 222}; - libj2_j2i_xor_sign_to_j2u((const struct libj2_j2i *)a, (struct libj2_j2u *)&r); + libj2_j2i_xor_sign_to_j2u((const struct libj2_j2i *)a, &u); + libj2_j2u_to_j2i(&u, &r); EXPECT(libj2_j2i_eq_j2i(a, &x)); EXPECT(libj2_j2i_eq_j2i(&r, &saved)); diff --git a/libj2_j2u_divmod_j2u_to_j2u.c b/libj2_j2u_divmod_j2u_to_j2u.c index 0b9ffff..a0618da 100644 --- a/libj2_j2u_divmod_j2u_to_j2u.c +++ b/libj2_j2u_divmod_j2u_to_j2u.c @@ -380,7 +380,7 @@ check(const struct libj2_j2u *a, const struct libj2_j2u *b) v.high = random_ju(); v.low = random_ju(); } while (!v.high && !v.low); - b = &u; + b = &v; } check_manual(a, b, NULL, NULL); } diff --git a/libj2_ji_sub_ji_to_j2i.c b/libj2_ji_sub_ji_to_j2i.c index 1057db6..8bc5944 100644 --- a/libj2_ji_sub_ji_to_j2i.c +++ b/libj2_ji_sub_ji_to_j2i.c @@ -25,7 +25,7 @@ check(uintmax_t ua, uintmax_t ub) intmax_t a = ua >> (LIBJ2_JU_BIT - 1U) ? -(intmax_t)~ua - 1 : (intmax_t)ua; intmax_t b = ub >> (LIBJ2_JU_BIT - 1U) ? -(intmax_t)~ub - 1 : (intmax_t)ub; struct libj2_j2i r, expected; - struct libj2_j2u wa, wb; + struct libj2_j2u wa, wb, ue; #if INTMAX_MIN + 1 != -INTMAX_MAX if (ua == (UINTMAX >> 1) + 1U || ub == (UINTMAX >> 1) + 1U) @@ -39,7 +39,8 @@ check(uintmax_t ua, uintmax_t ub) wb.high = b < 0 ? UINTMAX_MAX : 0; libj2_minus_j2u(&wb); - libj2_j2u_add_j2u_to_j2u(&wa, &wb, (void *)&expected); + libj2_j2u_add_j2u_to_j2u(&wa, &wb, &ue); + libj2_j2u_to_j2i(&ue, &expected); libj2_ji_sub_ji_to_j2i(a, b, &r); EXPECT(libj2_j2i_eq_j2i(&r, &expected)); } |
