From ca39dc2e74c0c21599e0751f121140e57dfb0218 Mon Sep 17 00:00:00 2001 From: lipengfei28 Date: Fri, 21 Jun 2024 15:47:59 +0800 Subject: [PATCH] math: Optimize the implementation of log2ceil and log2floor and move common math funtions to math32.h: div_round_up div_round_closest is_power_of_2 roundup_pow_of_two rounddown_pow_of_two Signed-off-by: lipengfei28 --- drivers/clk/clk.h | 20 +--- drivers/clk/clk_divider.c | 16 +-- drivers/clk/clk_phase.c | 4 +- drivers/coresight/coresight_stm.c | 5 +- drivers/pci/pci_ecam.c | 6 +- include/nuttx/lib/math32.h | 111 ++++++++++++------- include/nuttx/wireless/ieee80211/ieee80211.h | 2 +- libs/libc/misc/CMakeLists.txt | 4 - libs/libc/misc/Make.defs | 4 - libs/libc/misc/lib_log2ceil.c | 55 --------- libs/libc/misc/lib_log2floor.c | 55 --------- 11 files changed, 90 insertions(+), 192 deletions(-) delete mode 100644 libs/libc/misc/lib_log2ceil.c delete mode 100644 libs/libc/misc/lib_log2floor.c diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h index 4167165b9d..917e565e2c 100644 --- a/drivers/clk/clk.h +++ b/drivers/clk/clk.h @@ -30,7 +30,9 @@ #include #include #include + #include +#include #ifdef CONFIG_CLK @@ -40,9 +42,6 @@ #define MASK(width) (BIT(width) - 1) #define MULT_ROUND_UP(r, m) ((r) * (m) + (m) - 1) -#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) -#define DIV_ROUND_CLOSEST(n, d) ((((n) < 0) ^ ((d) < 0)) ? \ - (((n) - (d)/2)/(d)) : (((n) + (d)/2)/(d))) /**************************************************************************** * Inline Functions @@ -84,21 +83,6 @@ static inline uint32_t gcd(uint32_t a, uint32_t b) return b; } -static inline int is_power_of_2(uint32_t n) -{ - return (n != 0 && ((n & (n - 1)) == 0)); -} - -static inline uint32_t roundup_pow_of_two(uint32_t n) -{ - return 1 << fls(n - 1); -} - -static inline uint32_t rounddown_pow_of_two(uint32_t n) -{ - return 1 << (fls(n) - 1); -} - static inline uint32_t roundup_double(double n) { uint32_t intn = (uint32_t)n; diff --git a/drivers/clk/clk_divider.c b/drivers/clk/clk_divider.c index 8f24b4de81..96fd643141 100644 --- a/drivers/clk/clk_divider.c +++ b/drivers/clk/clk_divider.c @@ -107,7 +107,7 @@ static uint32_t divider_recalc_rate(uint32_t parent_rate, return parent_rate; } - return DIV_ROUND_UP(parent_rate, div); + return div_round_up(parent_rate, div); } static uint32_t clk_divider_recalc_rate(FAR struct clk_s *clk, @@ -125,7 +125,7 @@ static uint32_t clk_divider_recalc_rate(FAR struct clk_s *clk, static uint32_t _div_round_up(uint32_t parent_rate, uint32_t rate, uint16_t flags) { - uint32_t div = DIV_ROUND_UP(parent_rate, rate); + uint32_t div = div_round_up(parent_rate, rate); if (flags & CLK_DIVIDER_POWER_OF_TWO) { @@ -143,7 +143,7 @@ static uint32_t _div_round_closest(uint32_t parent_rate, uint32_t up_rate; uint32_t down_rate; - up = DIV_ROUND_UP(parent_rate, rate); + up = div_round_up(parent_rate, rate); down = parent_rate / rate; if (flags & CLK_DIVIDER_POWER_OF_TWO) @@ -152,8 +152,8 @@ static uint32_t _div_round_closest(uint32_t parent_rate, down = rounddown_pow_of_two(down); } - up_rate = DIV_ROUND_UP(parent_rate, up); - down_rate = DIV_ROUND_UP(parent_rate, down); + up_rate = div_round_up(parent_rate, up); + down_rate = div_round_up(parent_rate, down); return (rate - up_rate) <= (down_rate - rate) ? up : down; } @@ -255,7 +255,7 @@ static uint32_t clk_divider_bestdiv(FAR struct clk_s *clk, uint32_t rate, { parent_rate = clk_round_rate(clk_get_parent(clk), rate * i); - now = DIV_ROUND_UP(parent_rate, i); + now = div_round_up(parent_rate, i); if (_is_best_div(rate, now, best, divider->flags)) { bestdiv = i; @@ -280,7 +280,7 @@ static uint32_t divider_round_rate(FAR struct clk_s *clk, uint32_t rate, div = clk_divider_bestdiv(clk, rate, prate, width); - return DIV_ROUND_UP(*prate, div); + return div_round_up(*prate, div); } static uint32_t clk_divider_round_rate(FAR struct clk_s *clk, uint32_t rate, @@ -302,7 +302,7 @@ static int32_t divider_get_val(uint32_t rate, uint32_t parent_rate, return -EINVAL; } - div = DIV_ROUND_UP(parent_rate, rate); + div = div_round_up(parent_rate, rate); if ((flags & CLK_DIVIDER_POWER_OF_TWO) && !is_power_of_2(div)) { diff --git a/drivers/clk/clk_phase.c b/drivers/clk/clk_phase.c index be0e3c920d..bcc7aa2def 100644 --- a/drivers/clk/clk_phase.c +++ b/drivers/clk/clk_phase.c @@ -42,7 +42,7 @@ static int clk_phase_get_phase(FAR struct clk_s *clk) uint32_t val; val = (clk_read(phase->reg) >> phase->shift) & MASK(phase->width); - return DIV_ROUND_CLOSEST(360 * val, MASK(phase->width) + 1); + return div_round_closest(360 * val, MASK(phase->width) + 1); } static int clk_phase_set_phase(FAR struct clk_s *clk, int degrees) @@ -51,7 +51,7 @@ static int clk_phase_set_phase(FAR struct clk_s *clk, int degrees) uint32_t pha; uint32_t val; - pha = DIV_ROUND_CLOSEST((MASK(phase->width) + 1) * degrees, 360); + pha = div_round_closest((MASK(phase->width) + 1) * degrees, 360); if (pha > MASK(phase->width)) { diff --git a/drivers/coresight/coresight_stm.c b/drivers/coresight/coresight_stm.c index 308e2d4b52..ecb8b7d0de 100644 --- a/drivers/coresight/coresight_stm.c +++ b/drivers/coresight/coresight_stm.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -92,10 +93,6 @@ #define STM_NO_MARKED BIT(4) #define STM_NO_GUARANTEED BIT(7) -/* Bit operation */ - -#define rounddown_pow_of_two(n) (1 << (fls(n) - 1)) - /**************************************************************************** * Private Types ****************************************************************************/ diff --git a/drivers/pci/pci_ecam.c b/drivers/pci/pci_ecam.c index 90d521bf8c..c125fba1b0 100644 --- a/drivers/pci/pci_ecam.c +++ b/drivers/pci/pci_ecam.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -40,8 +41,7 @@ #define readl(a) (*(FAR volatile uint32_t *)(a)) #define writel(v,a) (*(FAR volatile uint32_t *)(a) = (v)) -#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) -#define IS_ALIGNED(x, a) (((x) & ((a) - 1)) == 0) +#define IS_ALIGNED(x, a) (((x) & ((a) - 1)) == 0) /**************************************************************************** * Private Function Prototypes @@ -145,7 +145,7 @@ static bool pci_ecam_addr_valid(FAR const struct pci_bus_s *bus, uint32_t devfn) { FAR struct pci_ecam_s *ecam = pci_ecam_from_controller(bus->ctrl); - int num_buses = DIV_ROUND_UP(pci_resource_size(&ecam->cfg), 1 << 20); + int num_buses = div_round_up(pci_resource_size(&ecam->cfg), 1 << 20); return bus->number < num_buses; } diff --git a/include/nuttx/lib/math32.h b/include/nuttx/lib/math32.h index 07b955b4d0..5a728d46fb 100644 --- a/include/nuttx/lib/math32.h +++ b/include/nuttx/lib/math32.h @@ -29,11 +29,16 @@ #include #include +#include /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +#define div_round_up(n, d) (((n) + (d) - 1) / (d)) +#define div_round_closest(n, d) ((((n) < 0) ^ ((d) < 0)) ? \ + (((n) - (d)/2)/(d)) : (((n) + (d)/2)/(d))) + /* Returns one plus the index of the most significant 1-bit of n, * or if n is zero, returns zero. */ @@ -107,6 +112,68 @@ extern "C" * Public Function Prototypes ****************************************************************************/ +#define is_power_of_2(n) IS_POWER_OF_2(n) +#define flsx(n) ((sizeof(n) <= sizeof(long)) ? flsl(n) : flsll(n)) + +/**************************************************************************** + * Name: log2ceil + * + * Description: + * Calculate the up-rounded power-of-two for input. + * + * Input Parameters: + * x - Argument to calculate the power-of-two from. + * + * Returned Value: + * Power-of-two for argument, rounded up. + * + ****************************************************************************/ + +#define log2ceil(n) (is_power_of_2(n) ? (flsx(n) - 1) : flsx(n)) + +/**************************************************************************** + * Name: log2floor + * + * Description: + * Calculate the down-rounded (truncated) power-of-two for input. + * + * Input Parameters: + * x - Argument to calculate the power-of-two from. + * + * Returned Value: + * Power-of-two for argument, rounded (truncated) down. + * + ****************************************************************************/ + +#define log2floor(n) (flsx(n) - 1) + +/* roundup_pow_of_two() - Round up to nearest power of two + * n: value to round up + */ + +#define roundup_pow_of_two(n) (((n) - (n) + 1) << flsx((n) - 1)) + +/* rounddown_pow_of_two() - Round down to nearest power of two + * n: value to round down + */ + +#define rounddown_pow_of_two(n) (((n) - (n) + 1) << (flsx(n) - 1)) + +/* order_base_2 - Calculate the (rounded up) base 2 order of the argument + * n: parameter + * + * The first few values calculated by this routine: + * ob2(0) = 0 + * ob2(1) = 0 + * ob2(2) = 1 + * ob2(3) = 2 + * ob2(4) = 2 + * ob2(5) = 3 + * ... and so on. + */ + +#define order_base_2(n) ((n) > 1 ? log2floor((n) - 1) + 1 : 0) + /* If the divisor happens to be constant, we determine the appropriate * inverse at compile time to turn the division into a few inline * multiplications which ought to be much faster. @@ -115,10 +182,10 @@ extern "C" */ #ifdef CONFIG_HAVE_LONG_LONG -/* Default C implementation for __umul64_const() +/* Default C implementation for umul64_const() * - * Prototype: uint64_t __umul64_const(uint64_t retval, uint64_t m, - * uint64_t n, bool bias); + * Prototype: uint64_t umul64_const(uint64_t retval, uint64_t m, + * uint64_t n, bool bias); * Semantic: retval = ((bias ? m : 0) + m * n) >> 64 * * The product is a 128-bit value, scaled down to 64 bits. @@ -127,10 +194,10 @@ extern "C" */ # ifdef up_umul64_const -# define __umul64_const(res, m, n, bias) \ +# define umul64_const(res, m, n, bias) \ (res) = up_umul64_const(m, n, bias) # else -# define __umul64_const(res, m, n, bias) \ +# define umul64_const(res, m, n, bias) \ do \ { \ uint32_t __m_lo = (m) & 0xffffffff; \ @@ -230,7 +297,7 @@ extern "C" } \ ___bias = 0; \ } \ - __umul64_const(___res, ___m, ___n, ___bias); \ + umul64_const(___res, ___m, ___n, ___bias); \ \ ___res /= ___p; \ (n) = ___res; \ @@ -419,38 +486,6 @@ void umul64(FAR const struct uint64_s *factor1, FAR const struct uint64_s *factor2, FAR struct uint64_s *product); -/**************************************************************************** - * Name: log2ceil - * - * Description: - * Calculate the up-rounded power-of-two for input. - * - * Input Parameters: - * x - Argument to calculate the power-of-two from. - * - * Returned Value: - * Power-of-two for argument, rounded up. - * - ****************************************************************************/ - -uintptr_t log2ceil(uintptr_t x); - -/**************************************************************************** - * Name: log2floor - * - * Description: - * Calculate the down-rounded (truncated) power-of-two for input. - * - * Input Parameters: - * x - Argument to calculate the power-of-two from. - * - * Returned Value: - * Power-of-two for argument, rounded (truncated) down. - * - ****************************************************************************/ - -uintptr_t log2floor(uintptr_t x); - #undef EXTERN #ifdef __cplusplus } diff --git a/include/nuttx/wireless/ieee80211/ieee80211.h b/include/nuttx/wireless/ieee80211/ieee80211.h index bf9f5a74a5..22a0697743 100644 --- a/include/nuttx/wireless/ieee80211/ieee80211.h +++ b/include/nuttx/wireless/ieee80211/ieee80211.h @@ -2539,7 +2539,7 @@ ieee80211_he_ppe_size(uint8_t ppe_thres_hdr, FAR const uint8_t *phy_cap_info) */ n = (n * IEEE80211_PPE_THRES_INFO_PPET_SIZE * 2) + 7; - n = DIV_ROUND_UP(n, 8); + n = div_round_up(n, 8); return n; } diff --git a/libs/libc/misc/CMakeLists.txt b/libs/libc/misc/CMakeLists.txt index 61301e3d70..00fb6810d2 100644 --- a/libs/libc/misc/CMakeLists.txt +++ b/libs/libc/misc/CMakeLists.txt @@ -86,10 +86,6 @@ list( lib_err.c lib_instrument.c) -# Add generic integer math functions - -list(APPEND SRCS lib_log2ceil.c lib_log2floor.c) - # Keyboard driver encoder/decoder if(CONFIG_LIBC_KBDCODEC) diff --git a/libs/libc/misc/Make.defs b/libs/libc/misc/Make.defs index 281c662f00..9089921011 100644 --- a/libs/libc/misc/Make.defs +++ b/libs/libc/misc/Make.defs @@ -43,10 +43,6 @@ CSRCS += lib_crc64.c lib_crc32.c lib_crc16.c lib_crc16ccitt.c lib_crc8.c CSRCS += lib_crc8ccitt.c lib_crc8table.c lib_glob.c lib_execinfo.c CSRCS += lib_ftok.c lib_err.c lib_instrument.c -# Add generic integer math functions - -CSRCS += lib_log2ceil.c lib_log2floor.c - # Keyboard driver encoder/decoder ifeq ($(CONFIG_LIBC_KBDCODEC),y) diff --git a/libs/libc/misc/lib_log2ceil.c b/libs/libc/misc/lib_log2ceil.c deleted file mode 100644 index 581729a1c1..0000000000 --- a/libs/libc/misc/lib_log2ceil.c +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** - * libs/libc/misc/lib_log2ceil.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: log2ceil - * - * Description: - * Calculate the up-rounded power-of-two for input. - * - * Input Parameters: - * x - Argument to calculate the power-of-two from. - * - * Returned Value: - * Power-of-two for argument, rounded up. - * - ****************************************************************************/ - -uintptr_t log2ceil(uintptr_t x) -{ - uintptr_t pot = 0; - - for (x = x - 1; x; x >>= 1) - { - pot++; - } - - return pot; -} diff --git a/libs/libc/misc/lib_log2floor.c b/libs/libc/misc/lib_log2floor.c deleted file mode 100644 index fe90fa59fd..0000000000 --- a/libs/libc/misc/lib_log2floor.c +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** - * libs/libc/misc/lib_log2floor.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: log2floor - * - * Description: - * Calculate the down-rounded (truncated) power-of-two for input. - * - * Input Parameters: - * x - Argument to calculate the power-of-two from. - * - * Returned Value: - * Power-of-two for argument, rounded (truncated) down. - * - ****************************************************************************/ - -uintptr_t log2floor(uintptr_t x) -{ - uintptr_t pot = 0; - - for (; x > 1; x >>= 1) - { - pot++; - } - - return pot; -}