From efcfe587ec95d6a5d78f957daa904eb90d4f1c8d Mon Sep 17 00:00:00 2001 From: Krzysiek Borowy Date: Fri, 20 Mar 2026 09:17:35 +0100 Subject: [PATCH 1/3] lookup tables --- xmcu/look_up_tables.hpp | 205 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 xmcu/look_up_tables.hpp diff --git a/xmcu/look_up_tables.hpp b/xmcu/look_up_tables.hpp new file mode 100644 index 0000000..c2d0e92 --- /dev/null +++ b/xmcu/look_up_tables.hpp @@ -0,0 +1,205 @@ +#pragma once + +/* + * Copyright (c) xEmbeddedTools team and contributors. + * Licensed under the Apache License, Version 2.0. See LICENSE file in the project root for details. + */ + +// std +#include +// #include +// #include +// #include +#include +// #include + +namespace xmcu::look_up_tables { + +#define concept_allowed 1 +#if concept_allowed + +template +concept is_row = requires(const T a) { + typename T::value_type; + typename T::containter_type; + a.size(); +} && requires(T a, T b) { + { a |= b }; +}; + +template +concept is_desc = is_row && requires { + typename T::destination_type; + typename T::reduced_type<1>; +}; +template +concept is_Input_table = requires { + typename T::value_type; + { T::decode_state(0) } -> std::convertible_to; +} && xmcu::look_up_tables::is_desc && requires(const T& a) { + a.size(); + a.lut_out(0); +}; +#else +#define is_row typename +#define is_desc typename +#define is_Input_table typename +#endif + +template class Row : public std::array +{ +public: + using containter_type = std::array; + consteval containter_type& as_array() + { + return *this; + } + // operators + constexpr Row& operator|=(const Row& a_rhs) + { + auto& ref_this = *this; + + for (std::size_t i = 0; i < this->size(); ++i) + { + ref_this[i] |= a_rhs[i]; + } + return ref_this; + } + constexpr Row operator|(const Row& a_rhs) const + { + auto ref_this = *this; + + for (std::size_t i = 0; i < this->size(); ++i) + { + ref_this[i] |= a_rhs[i]; + } + return ref_this; + } +}; + +// single row +template class Input_row // might be join with row + : public Row +{ +public: + using destination_type = Row; + template using reduced_type = Input_row; +}; + +namespace decoders { +struct Direct +{ + consteval static std::size_t decode(std::size_t a_value) + { + return a_value; + } +}; +template struct Offset +{ + consteval static std::size_t decode(std::size_t a_value) + { + return a_value + OFFSET; + } +}; +template struct Offset_Mask +{ + consteval static std::size_t decode(std::size_t a_value) + { + return MASK & (a_value + OFFSET); + } +}; +} // namespace decoders + +template class Input_table : public std::array +{ +public: + // introduced for local usage only (`lut_out`) + using destination_type = typename T::destination_type; + using containter_type = std::array; + consteval Input_table(const std::array& a_table, Decoder = {}) + : std::array { a_table } + { + } + consteval static std::size_t decode_state(std::size_t a_state) + { + return Decoder::decode(a_state); + } + consteval auto lut_out(std::size_t a_index) const + { + auto binary = decode_state(a_index); + auto result = destination_type {}; + for (std::size_t i = 0; i < this->size(); ++i) + { + if (0 == (binary & 1u << i)) + { + continue; + } + result |= (*this)[i]; + } + return result; + } +}; + +template class Table + : public std::array +{ +public: + using desc_type = T; + static constexpr std::size_t output_words_count = BITS; + + template +#if concept_allowed + requires(N_dest < output_words_count && N_dest > 0) +#endif + consteval Table, BITS> + extract_words(const std::array& a_columns) const + { + static_assert(N_dest < output_words_count && N_dest > 0, + "N_dest should be in range [0 - LUT output word size]"); + using Row = typename T::reduced_type; + Table result; + + for (std::size_t i = 0; i < N; ++i) + { + Row line {}; + const auto& source_line = this->at(i); + for (std::size_t word = 0; word < a_columns.size(); ++word) + { + line[word] = source_line.at(a_columns[word]); + } + result[i] = line; + } + + return result; + } + consteval Table operator|(const Table& a_rhs) const + { + Table result; + for (std::size_t i = 0; i < N; ++i) + { + result[i] = (*this)[i] | a_rhs[i]; + } + + return result; + } +}; + +template +consteval auto compose_table_from_bitlist(const I& a_description, const Table& input_table) +{ + auto result_array { input_table }; + for (std::size_t channel = 0; channel < result_array.size(); ++channel) + { + result_array.at(channel) |= a_description.lut_out(channel); + } + return result_array; +} + +template +consteval auto compose_table_from_bitlist(const std::array& a_description) +{ + const std::array input_table = std::array {}; + return compose_table_from_bitlist(a_description, input_table); +} + +} // namespace xmcu::look_up_tables From 312e93f4e8e5c36502ae1d963ba38302250f7097 Mon Sep 17 00:00:00 2001 From: Krzysiek Borowy Date: Fri, 20 Mar 2026 10:11:38 +0100 Subject: [PATCH 2/3] submodule update --- soc/st/arm/m0/l0 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/st/arm/m0/l0 b/soc/st/arm/m0/l0 index 21155ba..204d588 160000 --- a/soc/st/arm/m0/l0 +++ b/soc/st/arm/m0/l0 @@ -1 +1 @@ -Subproject commit 21155bace56d238a293151d32caaea343ebdb7cc +Subproject commit 204d5889bad239edb276a5378f4384dd28f2165c From 700cc11af3ad2277b6b9c6b1af389ac34cb88c56 Mon Sep 17 00:00:00 2001 From: Krzysiek Borowy Date: Fri, 20 Mar 2026 14:26:32 +0100 Subject: [PATCH 3/3] extract table size from type for GCC 13 compatibility --- soc/st/arm/m0/l0 | 2 +- xmcu/look_up_tables.hpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/soc/st/arm/m0/l0 b/soc/st/arm/m0/l0 index 204d588..55293d0 160000 --- a/soc/st/arm/m0/l0 +++ b/soc/st/arm/m0/l0 @@ -1 +1 @@ -Subproject commit 204d5889bad239edb276a5378f4384dd28f2165c +Subproject commit 55293d08e19ddc22bafff1ff9f9ed11df5ae2243 diff --git a/xmcu/look_up_tables.hpp b/xmcu/look_up_tables.hpp index c2d0e92..ee8c859 100644 --- a/xmcu/look_up_tables.hpp +++ b/xmcu/look_up_tables.hpp @@ -35,6 +35,7 @@ concept is_desc = is_row && requires { template concept is_Input_table = requires { typename T::value_type; + typename T::containter_type; { T::decode_state(0) } -> std::convertible_to; } && xmcu::look_up_tables::is_desc && requires(const T& a) { a.size();