From eac271413f43db848429d0e393a2fee22be3a7aa Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 25 Jan 2016 11:19:25 -0600 Subject: [PATCH] Add more 32-bit math operations; Update ChangeLog --- ChangeLog | 3 + include/nuttx/math32.h | 133 +++++++++++++++++++++++++++----------- libc/misc/Make.defs | 2 +- libc/misc/lib_uadd32x64.c | 80 +++++++++++++++++++++++ libc/misc/lib_uadd64.c | 2 +- libc/misc/lib_umul32.c | 2 +- libc/misc/lib_umul64.c | 4 +- libc/misc/lib_usub64.c | 4 +- libc/misc/lib_usub64x32.c | 82 +++++++++++++++++++++++ 9 files changed, 269 insertions(+), 43 deletions(-) create mode 100644 libc/misc/lib_uadd32x64.c create mode 100644 libc/misc/lib_usub64x32.c diff --git a/ChangeLog b/ChangeLog index 226462a16d..7841c7b552 100755 --- a/ChangeLog +++ b/ChangeLog @@ -11352,3 +11352,6 @@ SPI interface (2016-01-23). * drivers/spi/Kconfig and many other files: Remove CONFIG_SPI_OWNBUS: Now its not just a good idea, its the law (2015-01-23). + * include/nuttx/math32.h and libc/misc: Add some utilities to support + 64-bit arithmetic operations for platforms that do not support long + long types. Not yet used anywhere (2015-01-25). diff --git a/include/nuttx/math32.h b/include/nuttx/math32.h index d3bda49580..64e993d790 100644 --- a/include/nuttx/math32.h +++ b/include/nuttx/math32.h @@ -88,6 +88,103 @@ extern "C" * Public Function Prototypes ****************************************************************************/ +/**************************************************************************** + * Name: uneg64 + * + * Description: + * Negate a 64-bit unsigned value. + * + * Input Parameters: + * value - The value to be negated. + * + ****************************************************************************/ + +/* void uneg64(FAR const uint64_s *value); */ + +#define uneg64(value) \ + do \ + { \ + value->ms = ~value->ms; \ + value->ls = -value->ls; \ + if (value->ls == 0) \ + { \ + value->ms++; \ + } \ + } \ + while (0) + +/**************************************************************************** + * Name: uadd32x64 + * + * Description: + * Add a 32-bit value to a 64-bit values and return the truncated 64-bit + * sum. + * + * Input Parameters: + * term1 and term2 - The values to be added + * sum - The location to return the product of the two values. sum may + * be one of term1 or term2 + * + ****************************************************************************/ + +void uadd32x64(uint32_t term1, FAR const struct uint64_s *term2, + FAR struct uint64_s *sum); + +/**************************************************************************** + * Name: uadd64 + * + * Description: + * Add two 64-bit values and return a 64-bit sum. + * + * Input Parameters: + * term1 and term2 - The values to be added + * sum - The location to return the product of the two values. sum may + * be one of term1 or term2 + * + ****************************************************************************/ + +void uadd64(FAR const struct uint64_s *term1, + FAR const struct uint64_s *term2, + FAR struct uint64_s *sum); + +/**************************************************************************** + * Name: usub64x32 + * + * Description: + * Subtract a 32-bit value from a 64-bit value and return the 64-bit + * difference. + * + * Input Parameters: + * minuend - The number from which another number (the Subtrahend) is + * to be subtracted. + * subtrahend - The number that is to be subtracted. + * difference - The location to return the difference of the two values. + * difference may the same as one of minuend or subtrahend. + * + ****************************************************************************/ + +void usub64x32(FAR const struct uint64_s *minuend, uint32_t subtrahend, + FAR struct uint64_s *difference); + +/**************************************************************************** + * Name: usub64 + * + * Description: + * Subtract two 64-bit values and return the 64-bit difference. + * + * Input Parameters: + * minuend - The number from which another number (the Subtrahend) is + * to be subtracted. + * subtrahend - The number that is to be subtracted. + * difference - The location to return the difference of the two values. + * difference may the same as one of minuend or subtrahend. + * + ****************************************************************************/ + +void usub64(FAR const struct uint64_s *minuend, + FAR const struct uint64_s *subtrahend, + FAR struct uint64_s *difference); + /**************************************************************************** * Name: umul32 * @@ -136,42 +233,6 @@ void umul64(FAR const struct uint64_s *factor1, FAR const struct uint64_s *factor2, FAR struct uint64_s *product); -/**************************************************************************** - * Name: uadd64 - * - * Description: - * Add two 64-bit values and return a 64-bit sum. - * - * Input Parameters: - * term1 and term2 - The values to be added - * sum - The location to return the product of the two values. sum may - * be one of term1 or term2 - * - ****************************************************************************/ - -void uadd64(FAR const struct uint64_s *term1, - FAR const struct uint64_s *term2, - FAR struct uint64_s *sum); - -/**************************************************************************** - * Name: usub64 - * - * Description: - * Subtract two 64-bit values and return the 64-bit difference. - * - * Input Parameters: - * minuend - The number from which another number (the Subtrahend) is - * to be subtracted. - * subtrahend - The number that is to be subtracted. - * difference - The location to return the difference of the two values. - * difference may the same as one of minuend or subtrahend. - * - ****************************************************************************/ - -void usub64(FAR const struct uint64_s *minuend, - FAR const struct uint64_s *subtrahend, - FAR struct uint64_s *difference); - #undef EXTERN #ifdef __cplusplus } diff --git a/libc/misc/Make.defs b/libc/misc/Make.defs index 5eaada16fa..1a9f7911c1 100644 --- a/libc/misc/Make.defs +++ b/libc/misc/Make.defs @@ -41,7 +41,7 @@ CSRCS += lib_tea_encrypt.c lib_tea_decrypt.c # Support for platforms that do not have long long types CSRCS += lib_umul32.c lib_umul64.c lib_umul32x64.c -CSRCS += lib_uadd64.c lib_usub64.c +CSRCS += lib_uadd32x64.c lib_uadd64.c lib_usub64x32.c lib_usub64.c # Add C files that depend on file OR socket descriptors diff --git a/libc/misc/lib_uadd32x64.c b/libc/misc/lib_uadd32x64.c new file mode 100644 index 0000000000..68800e5529 --- /dev/null +++ b/libc/misc/lib_uadd32x64.c @@ -0,0 +1,80 @@ +/**************************************************************************** + * libc/fixedmath/lib_uadd32x64.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: uadd32x64 + * + * Description: + * Add a 32-bit value to a 64-bit values and return the truncated 64-bit + * sum. + * + * Input Parameters: + * term1 and term2 - The values to be added + * sum - The location to return the product of the two values. sum may + * be one of term1 or term2 + * + ****************************************************************************/ + +void uadd32x64(uint32_t term1, FAR const struct uint64_s *term2, + FAR struct uint64_s *sum) +{ + /* Get the MS part of the sum */ + + sum->ms = term2->ms; + + /* Check for carry, i.e., that is when: + * + * term1 + term2->ls > UINT32_MAX + */ + + if ((UINT32_MAX - term1) > term2->ls) + { + sum->ms++; + } + + /* Get the LS part of the sum */ + + sum->ls = term1 + term2->ls; +} diff --git a/libc/misc/lib_uadd64.c b/libc/misc/lib_uadd64.c index 0a2f4a7588..c9e634d1ee 100644 --- a/libc/misc/lib_uadd64.c +++ b/libc/misc/lib_uadd64.c @@ -65,7 +65,7 @@ void uadd64(FAR const struct uint64_s *term1, sum->ms = term1->ms + term2->ms; /* Check for carry, i.e., that is when: - * + * * term1->ls + term2->ls > UINT32_MAX */ diff --git a/libc/misc/lib_umul32.c b/libc/misc/lib_umul32.c index 2b971dd11f..b245e10ee0 100644 --- a/libc/misc/lib_umul32.c +++ b/libc/misc/lib_umul32.c @@ -75,7 +75,7 @@ void umul32(uint32_t factor1, uint32_t factor2, FAR struct uint64_s *product) ls2 = factor2 & 0x0000ffff; /* factor1 * factor2 = (ms1 * ms2 << 32) + - * ls1 * (ms2 << 16) + ls2 * (ms1 << 16) + + * ls1 * (ms2 << 16) + ls2 * (ms1 << 16) + * ls1 * ls2 * part1 = (ms1 * ms2 << 32) + ls1 * ls2 * part2 = ls1 * (ms2 << 16) + ls2 * (ms1 << 16) diff --git a/libc/misc/lib_umul64.c b/libc/misc/lib_umul64.c index bf70a1b2a4..d20612638e 100644 --- a/libc/misc/lib_umul64.c +++ b/libc/misc/lib_umul64.c @@ -69,12 +69,12 @@ void umul64(FAR const struct uint64_s *factor1, * Full 128-bit product: * factor1 * factor2 = (factor1->ms * factor2->ms << 64) + * factor1->ls * (factor2->ms << 32) + - * factor2->ls * (factor1->ms << 32) + + * factor2->ls * (factor1->ms << 32) + * factor1->ls * factor2->ls * * Truncated, 64-bit product: * factor1 * factor2 = (factor1->ls * factor2->ms + - * factor2->ls * factor1->ms) << 32) + + * factor2->ls * factor1->ms) << 32) + * factor1->ls * factor2->ls * * part1 = (factor1->ls * factor2->ms + diff --git a/libc/misc/lib_usub64.c b/libc/misc/lib_usub64.c index ab9821cd8e..2a327245ec 100644 --- a/libc/misc/lib_usub64.c +++ b/libc/misc/lib_usub64.c @@ -53,7 +53,7 @@ * minuend - The number from which another number (the Subtrahend) is * to be subtracted. * subtrahend - The number that is to be subtracted. - * difference - The location to return the difference of the two values. + * difference - The location to return the difference of the two values. * difference may the same as one of minuend or subtrahend. * ****************************************************************************/ @@ -67,7 +67,7 @@ void usub64(FAR const struct uint64_s *minuend, difference->ms = minuend->ms - subtrahend->ms; /* Check for a borrow, i.e., that is when: - * + * * subtrahend->ls > minuend->ls */ diff --git a/libc/misc/lib_usub64x32.c b/libc/misc/lib_usub64x32.c new file mode 100644 index 0000000000..b691e5105f --- /dev/null +++ b/libc/misc/lib_usub64x32.c @@ -0,0 +1,82 @@ +/**************************************************************************** + * libc/fixedmath/lib_usub64x32.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: usub64x32 + * + * Description: + * Subtract a 32-bit value from a 64-bit value and return the 64-bit + * difference. + * + * Input Parameters: + * minuend - The number from which another number (the Subtrahend) is + * to be subtracted. + * subtrahend - The number that is to be subtracted. + * difference - The location to return the difference of the two values. + * difference may the same as one of minuend or subtrahend. + * + ****************************************************************************/ + +void usub64x32(FAR const struct uint64_s *minuend, uint32_t subtrahend, + FAR struct uint64_s *difference) +{ + /* Get the MS part of the difference */ + + difference->ms = minuend->ms; + + /* Check for a borrow, i.e., that is when: + * + * subtrahend->ls > minuend->ls + */ + + if (subtrahend > minuend->ls) + { + difference->ms--; + } + + /* Get the LS part of the difference */ + + difference->ls = minuend->ls - subtrahend; +}