diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d19fa995..6f674bd2d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -833,7 +833,6 @@ endif() # Detect availability of std::span ################################################################################ unset(has_span CACHE) -include(CheckCXXSourceCompiles) check_cxx_source_compiles(" #include int main() @@ -843,6 +842,25 @@ check_cxx_source_compiles(" +################################################################################ +# Detect availability of std::rotl +################################################################################ +unset(has_rotl CACHE) +if(CMAKE_CXX_STANDARD VERSION_GREATER 17) + check_cxx_source_compiles(" + #include + #include + int main() + { + std::uint8_t i = 0b00011101; + auto k = std::rotl(i,0); + }" + has_rotl + ) +endif() + + + ################################################################################ # Detect availability of std::put_time (Workaround for gcc < 5.0) ################################################################################ diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt b/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt index 4a2403a36..5fc8e8bcd 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/CMakeLists.txt @@ -68,6 +68,12 @@ if(GNURADIO_USES_STD_POINTERS) ) endif() +if(has_rotl) + target_compile_definitions(telemetry_decoder_gr_blocks + PRIVATE -DCOMPILER_HAS_ROTL=1 + ) +endif() + if(ENABLE_CLANG_TIDY) if(CLANG_TIDY_EXE) set_target_properties(telemetry_decoder_gr_blocks diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_gs.cc index 272359030..f3954b6cf 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_gs.cc @@ -33,8 +33,14 @@ #include // for shared_ptr -#ifndef _rotl -auto _rotl = [](auto x, auto n) { return (((x) << (n)) ^ ((x) >> (32 - (n)))); }; // Used in the parity check algorithm +#ifdef COMPILER_HAS_ROTL +#include +namespace my_rotl = std; +#else +namespace my_rotl +{ +auto rotl = [](auto x, auto n) { return (((x) << (n)) ^ ((x) >> (32 - (n)))); }; // Used in the parity check algorithm +} #endif @@ -138,15 +144,15 @@ bool gps_l1_ca_telemetry_decoder_gs::gps_word_parityCheck(uint32_t gpsword) // check algorithm described in IS-GPS-200K. This avoids lengthy shift- // and-xor loops. d1 = gpsword & 0xFBFFBF00U; - d2 = _rotl(gpsword, 1U) & 0x07FFBF01U; - d3 = _rotl(gpsword, 2U) & 0xFC0F8100U; - d4 = _rotl(gpsword, 3U) & 0xF81FFE02U; - d5 = _rotl(gpsword, 4U) & 0xFC00000EU; - d6 = _rotl(gpsword, 5U) & 0x07F00001U; - d7 = _rotl(gpsword, 6U) & 0x00003000U; + d2 = my_rotl::rotl(gpsword, 1U) & 0x07FFBF01U; + d3 = my_rotl::rotl(gpsword, 2U) & 0xFC0F8100U; + d4 = my_rotl::rotl(gpsword, 3U) & 0xF81FFE02U; + d5 = my_rotl::rotl(gpsword, 4U) & 0xFC00000EU; + d6 = my_rotl::rotl(gpsword, 5U) & 0x07F00001U; + d7 = my_rotl::rotl(gpsword, 6U) & 0x00003000U; t = d1 ^ d2 ^ d3 ^ d4 ^ d5 ^ d6 ^ d7; // Now XOR the 5 6-bit fields together to produce the 6-bit final result. - parity = t ^ _rotl(t, 6U) ^ _rotl(t, 12U) ^ _rotl(t, 18U) ^ _rotl(t, 24U); + parity = t ^ my_rotl::rotl(t, 6U) ^ my_rotl::rotl(t, 12U) ^ my_rotl::rotl(t, 18U) ^ my_rotl::rotl(t, 24U); parity = parity & 0x3FU; if (parity == (gpsword & 0x3FU)) {