diff --git a/common/build.mk b/common/build.mk index 5e779a58c2..a792bca3ad 100644 --- a/common/build.mk +++ b/common/build.mk @@ -91,6 +91,7 @@ common-$(CONFIG_SHA1)+= sha1.o common-$(CONFIG_SHA256)+=sha256.o common-$(CONFIG_SMBUS)+= smbus.o common-$(CONFIG_SOFTWARE_CLZ)+=clz.o +common-$(CONFIG_SOFTWARE_CTZ)+=ctz.o common-$(CONFIG_CMD_SPI_XFER)+=spi_commands.o common-$(CONFIG_SPI_FLASH)+=spi_flash.o spi_flash_reg.o common-$(CONFIG_SPI_FLASH_REGS)+=spi_flash_reg.o diff --git a/common/ctz.c b/common/ctz.c new file mode 100644 index 0000000000..bb6f69624e --- /dev/null +++ b/common/ctz.c @@ -0,0 +1,27 @@ +/* Copyright 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Software emulation for CTZ instruction + */ + +#include "common.h" + +/** + * Count trailing zeros + * + * @param x non null integer. + * @return the number of trailing 0-bits in x, + * starting at the least significant bit position. + * + * Using a de Brujin sequence, as documented here: + * http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup + */ +int __keep __ctzsi2(int x) +{ + static const uint8_t MulDeBruijnBitPos[32] = { + 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, + 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 + }; + return MulDeBruijnBitPos[((uint32_t)((x & -x) * 0x077CB531U)) >> 27]; +} diff --git a/core/cortex-m0/config_core.h b/core/cortex-m0/config_core.h index e58b481704..389ed8edec 100644 --- a/core/cortex-m0/config_core.h +++ b/core/cortex-m0/config_core.h @@ -10,8 +10,9 @@ #define BFD_ARCH arm #define BFD_FORMAT "elf32-littlearm" -/* Emulate the CLZ instruction since the CPU core is lacking support */ +/* Emulate the CLZ/CTZ instructions since the CPU core is lacking support */ #define CONFIG_SOFTWARE_CLZ +#define CONFIG_SOFTWARE_CTZ #define CONFIG_SOFTWARE_PANIC #endif /* __CROS_EC_CONFIG_CORE_H */ diff --git a/core/nds32/config_core.h b/core/nds32/config_core.h index fae914f7eb..9e9a88848c 100644 --- a/core/nds32/config_core.h +++ b/core/nds32/config_core.h @@ -13,9 +13,10 @@ #define CONFIG_SOFTWARE_PANIC /* - * The Andestar v3m architecture has no CLZ instruction (contrary to v3), + * The Andestar v3m architecture has no CLZ/CTZ instructions (contrary to v3), * so let's use the software implementation. */ #define CONFIG_SOFTWARE_CLZ +#define CONFIG_SOFTWARE_CTZ #endif /* __CROS_EC_CONFIG_CORE_H */ diff --git a/include/config.h b/include/config.h index 43e487a3df..42961a3300 100644 --- a/include/config.h +++ b/include/config.h @@ -2141,6 +2141,9 @@ /* Emulate the CLZ (Count Leading Zeros) in software for CPU lacking support */ #undef CONFIG_SOFTWARE_CLZ +/* Emulate the CLZ (Count Trailing Zeros) in software for CPU lacking support */ +#undef CONFIG_SOFTWARE_CTZ + /* Support smbus interface */ #undef CONFIG_SMBUS