diff --git a/CMakeLists.txt b/CMakeLists.txt
index cf9d1bcda..ed856c708 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,26 +16,58 @@
# along with GNSS-SDR. If not, see .
#
-########################################################################
-if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
- message(FATAL_ERROR "Prevented in-tree build. This is bad practice. Try 'cd build && cmake ../' ")
-endif(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
########################################################################
# Project setup
########################################################################
+if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
+ message(FATAL_ERROR "Prevented in-tree build. This is bad practice. Try 'cd build && cmake ../' ")
+endif(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
cmake_minimum_required(VERSION 2.8)
project(gnss-sdr CXX C)
-
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
+file(RELATIVE_PATH RELATIVE_CMAKE_CALL ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
+
+
+########################################################################
+# Determine optional blocks/libraries to be built (default: not built)
+# Enable them here or at the command line by doing 'cmake -DENABLE_XXX=ON ../'
+########################################################################
+
+option(ENABLE_GN3S "Enable the use of the GN3S dongle as signal source (experimental)" OFF)
+option(ENABLE_ARRAY "Enable the use of CTTC's antenna array front-end as signal source (experimental)" OFF)
+option(ENABLE_RTLSDR "Enable the use of RTL dongles as signal source (experimental)" OFF)
+option(ENABLE_OPENCL "Enable building of processing blocks implemented with OpenCL (experimental)" OFF)
+option(ENABLE_GPERFTOOLS "Enable linking to Gperftools libraries (tcmalloc and profiler)" OFF)
+option(ENABLE_GENERIC_ARCH "Builds a portable binary" OFF)
+option(ENABLE_VOLK_GNSSSDR "Enable building of volk_gnsssdr module: some volk protokernels coded by gnss-sdr" OFF)
+
+
+###############################
+# GNSS-SDR version information
+###############################
+# Get the current working branch
+execute_process(
+ COMMAND git rev-parse --abbrev-ref HEAD
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ OUTPUT_VARIABLE GIT_BRANCH
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+# Get the latest abbreviated commit hash of the working branch
+execute_process(
+ COMMAND git log -1 --format=%h
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ OUTPUT_VARIABLE GIT_COMMIT_HASH
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
-# Set the version information here
set(VERSION_INFO_MAJOR_VERSION 0)
set(VERSION_INFO_API_COMPAT 0)
-set(VERSION_INFO_MINOR_VERSION 3)
+set(VERSION_INFO_MINOR_VERSION 3.git-${GIT_BRANCH}-${GIT_COMMIT_HASH})
set(VERSION ${VERSION_INFO_MAJOR_VERSION}.${VERSION_INFO_API_COMPAT}.${VERSION_INFO_MINOR_VERSION})
-file(RELATIVE_PATH RELATIVE_CMAKE_CALL ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
+
########################################################################
# Environment setup
@@ -156,10 +188,16 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
endif(${DARWIN_VERSION} MATCHES "10")
endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+
#select the release build type by default to get optimization flags
if(NOT CMAKE_BUILD_TYPE)
- set(CMAKE_BUILD_TYPE "Release")
- message(STATUS "Build type not specified: defaulting to Release.")
+ if(ENABLE_GPERFTOOLS)
+ set(CMAKE_BUILD_TYPE "RelWithDebInfo")
+ message(STATUS "Build type not specified: defaulting to RelWithDebInfo.")
+ else(ENABLE_GPERFTOOLS)
+ set(CMAKE_BUILD_TYPE "Release")
+ message(STATUS "Build type not specified: defaulting to Release.")
+ endif(ENABLE_GPERFTOOLS)
endif(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
@@ -182,6 +220,7 @@ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
endif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+
################################################################################
# Googletest - http://code.google.com/p/googletest/
################################################################################
@@ -203,7 +242,6 @@ endif(GTEST_DIR)
################################################################################
# Boost - http://www.boost.org
################################################################################
-
if(UNIX AND EXISTS "/usr/lib64")
list(APPEND BOOST_LIBRARYDIR "/usr/lib64") # Fedora 64-bit fix
endif(UNIX AND EXISTS "/usr/lib64")
@@ -231,9 +269,7 @@ endif(NOT Boost_FOUND)
################################################################################
# GNU Radio - http://gnuradio.org/redmine/projects/gnuradio/wiki
################################################################################
-
find_package(Gnuradio)
-
if(NOT GNURADIO_RUNTIME_FOUND)
message(STATUS "CMake cannot find GNU Radio >= 3.7")
if(OS_IS_LINUX)
@@ -281,6 +317,40 @@ if(NOT GNURADIO_TRELLIS_FOUND)
endif()
+###############################################################################
+# Volk_gnsssdr module
+#In order to use volk_gnsssr module it is necessary to add:
+# 1) include_directories(..${VOLK_GNSSSDR_INCLUDE_DIRS}..)
+# 2) target_link_libraries(..${VOLK_GNSSSDR_LIBRARIES}..)
+###############################################################################
+
+if(ENABLE_VOLK_GNSSSDR)
+ message(STATUS "The volk_gnsssdr module with custom protokernels coded by gnss-sdr will be compiled.")
+ message(STATUS "You can disable it with 'cmake -DENABLE_VOLK_GNSSSDR=OFF ../'" )
+else(ENABLE_VOLK_GNSSSDR)
+ message(STATUS "The volk_gnsssdr module with custom protokernels coded by gnss-sdr is not enabled. Some configurations that use custom protokernels will not work." )
+ message(STATUS "Enable it with 'cmake -D ENABLE_VOLK_GNSSSDR=ON ../'." )
+endif(ENABLE_VOLK_GNSSSDR)
+
+if(ENABLE_VOLK_GNSSSDR)
+ set(VOLK_GNSSSDR_BASE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/src/algorithms/libs/volk_gnsssdr)
+ add_subdirectory(${VOLK_GNSSSDR_BASE_PATH})
+
+ set(VOLK_GNSSSDR_INCLUDE_DIRS
+ ${VOLK_GNSSSDR_BASE_PATH}/include
+ ${CMAKE_CURRENT_BINARY_DIR}/src/algorithms/libs/volk_gnsssdr/include
+ )
+
+ set(VOLK_GNSSSDR_LIBRARIES
+ #Path to libs of volk_gnsssdr target: ${VOLK_GNSSSDR_BASE_PATH}/lib/Debug/libvolk_gnsssdr.dylib
+ volk_gnsssdr
+ )
+
+ message(" * INCLUDES: ${VOLK_GNSSSDR_INCLUDE_DIRS} ")
+ message(" * LIBS: ${VOLK_GNSSSDR_LIBRARIES} ")
+ message("-- END OF: Setup volk_gnsssdr as a subproject.")
+endif(ENABLE_VOLK_GNSSSDR)
+
################################################################################
# gflags - http://code.google.com/p/gflags/
@@ -356,7 +426,6 @@ endif(NOT GFlags_FOUND OR LOCAL_GLOG)
################################################################################
# glog - http://code.google.com/p/google-glog/
################################################################################
-
find_package(GLOG)
set(glog_RELEASE 0.3.3)
if (NOT GLOG_FOUND OR LOCAL_GFLAGS)
@@ -458,97 +527,14 @@ endif(NOT GLOG_FOUND OR LOCAL_GFLAGS)
-
-################################################################################
-# GPerftools - http://code.google.com/p/gperftools/
-################################################################################
-
-set(GCC_GPERFTOOLS_FLAGS "")
-find_package(Gperftools)
-if ( NOT GPERFTOOLS_FOUND )
- message(STATUS "The optional library GPerftools has not been found.")
-else( NOT GPERFTOOLS_FOUND )
- message (STATUS "GPerftools library found." )
- link_libraries(${GPERFTOOLS_PROFILER} ${GPERFTOOLS_TCMALLOC})
-endif( NOT GPERFTOOLS_FOUND )
-list(APPEND CMAKE_CXX_FLAGS ${GCC_GPERFTOOLS_FLAGS})
-
-
-
-
-################################################################################
-# Doxygen - http://www.stack.nl/~dimitri/doxygen/index.html
-################################################################################
-
-find_package(Doxygen)
-if(DOXYGEN_FOUND)
- message(STATUS "Doxygen found.")
- message(STATUS "You can build the documentation with 'make doc'." )
- message(STATUS "When done, point your browser to ${CMAKE_SOURCE_DIR}/html/index.html")
- set(HAVE_DOT ${DOXYGEN_DOT_FOUND})
- file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} top_srcdir)
- file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} top_builddir)
- find_package(LATEX)
- if (PDFLATEX_COMPILER)
- set(GENERATE_PDF_DOCUMENTATION "YES")
- set(GNSSSDR_USE_MATHJAX "NO")
- else(PDFLATEX_COMPILER)
- set(GENERATE_PDF_DOCUMENTATION "NO")
- set(GNSSSDR_USE_MATHJAX "YES")
- endif(PDFLATEX_COMPILER)
- configure_file(${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile.in
- ${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile
- @ONLY
- )
- add_custom_target(doc
- ${DOXYGEN_EXECUTABLE} ${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile
- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
- COMMENT "Generating API documentation with Doxygen." VERBATIM
- )
- if(LATEX_COMPILER)
- message(STATUS "'make pdfmanual' will generate a manual at ${CMAKE_SOURCE_DIR}/docs/GNSS-SDR_manual.pdf")
- add_custom_target(pdfmanual
- COMMAND ${CMAKE_MAKE_PROGRAM}
- COMMAND ${CMAKE_COMMAND} -E copy refman.pdf ${CMAKE_SOURCE_DIR}/docs/GNSS-SDR_manual.pdf
- COMMAND ${CMAKE_MAKE_PROGRAM} clean
- DEPENDS doc
- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs/latex
- COMMENT "Generating PDF manual with Doxygen." VERBATIM
- )
- endif(LATEX_COMPILER)
- message(STATUS "'make doc-clean' will clean the documentation.")
- add_custom_target(doc-clean
- COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_SOURCE_DIR}/docs/html
- COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_SOURCE_DIR}/docs/latex
- COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_SOURCE_DIR}/docs/GNSS-SDR_manual.pdf
- COMMENT "Cleaning documentation." VERBATIM
- )
-else(DOXYGEN_FOUND)
- message(STATUS " Doxygen has not been found in your system.")
- message(STATUS " You can get nice code documentation by using it!")
- message(STATUS " Get it from http://www.stack.nl/~dimitri/doxygen/index.html")
- if(OS_IS_LINUX)
- if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
- message(" or simply by doing 'sudo yum install doxygen-latex'.")
- else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
- message(" or simply by doing 'sudo apt-get install doxygen-latex'.")
- endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
- endif(OS_IS_LINUX)
- if(OS_IS_MACOSX)
- message(STATUS " or simply by doing 'sudo port install doxygen +latex'.")
- endif(OS_IS_MACOSX)
-endif(DOXYGEN_FOUND)
-
-
-
################################################################################
# Armadillo - http://arma.sourceforge.net/
################################################################################
-
if(OS_IS_LINUX)
- #############################################
+ #############################################################################
# Check that LAPACK is found in the system
- #############################################
+ # LAPACK is required for matrix decompositions (eg. SVD) and matrix inverse.
+ #############################################################################
find_library(LAPACK lapack)
if(NOT LAPACK)
message(" The LAPACK library has not been found.")
@@ -562,9 +548,11 @@ if(OS_IS_LINUX)
endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
message(FATAL_ERROR "LAPACK is required to build gnss-sdr")
endif(NOT LAPACK)
- #############################################
+ #############################################################################
# Check that BLAS is found in the system
- #############################################
+ # BLAS is used for matrix multiplication.
+ # Without BLAS, matrix multiplication will still work, but might be slower.
+ #############################################################################
find_library(BLAS blas)
if(NOT BLAS)
message(" The BLAS library has not been found.")
@@ -641,31 +629,22 @@ if(NOT ARMADILLO_FOUND)
endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
message(FATAL_ERROR "The patch command is required to download and build armadillo")
endif(NOT PATCH_EXECUTABLE)
- set(armadillo_RELEASE 4.300.9)
- set(armadillo_MD5 "d51d1beb2a335f3002702d112c4814f3")
+ set(armadillo_RELEASE 4.400.0)
+ set(armadillo_MD5 "616744dbc96af1c5d6d32c6c69f6fe94")
if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/download/armadillo-${armadillo_RELEASE}/armadillo-${armadillo_RELEASE}.tar.gz)
set(ARMADILLO_PATCH_FILE ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}/armadillo_no.patch)
file(WRITE ${ARMADILLO_PATCH_FILE} "")
- set(ARMADILLO_PATCH_FILE2 ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}/armadillo_no2.patch)
- file(WRITE ${ARMADILLO_PATCH_FILE2} "")
else(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/download/armadillo-${armadillo_RELEASE}/armadillo-${armadillo_RELEASE}.tar.gz)
- set(ARMADILLO_PATCH_FILE ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}/armadillo_staticlib.patch)
- set(ARMADILLO_PATCH_FILE2 ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}/armadillo_enable_lapack.patch)
+ set(ARMADILLO_PATCH_FILE ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}/armadillo_enable_lapack.patch)
file(WRITE ${ARMADILLO_PATCH_FILE}
-"30c30
-< set(ARMA_USE_LAPACK false)
----
-> set(ARMA_USE_LAPACK true)
-312c312
-< add_library( armadillo SHARED \${PROJECT_SOURCE_DIR}/src/wrapper.cpp )
----
-> add_library( armadillo STATIC \${PROJECT_SOURCE_DIR}/src/wrapper.cpp )
-")
- file(WRITE ${ARMADILLO_PATCH_FILE2}
"12c12
< // #define ARMA_USE_LAPACK
---
-> #define ARMA_USE_LAPACK
+> #define ARMA_USE_LAPACK
+19c19
+< // #define ARMA_USE_BLAS
+---
+> #define ARMA_USE_BLAS
")
endif(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/download/armadillo-${armadillo_RELEASE}/armadillo-${armadillo_RELEASE}.tar.gz)
ExternalProject_Add(
@@ -673,9 +652,9 @@ if(NOT ARMADILLO_FOUND)
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}
URL http://sourceforge.net/projects/arma/files/armadillo-${armadillo_RELEASE}.tar.gz
DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR}/download/armadillo-${armadillo_RELEASE}
- URL_MD5 ${armadillo_MD5}
- PATCH_COMMAND patch -N /CMakeLists.txt ${ARMADILLO_PATCH_FILE} && patch -N /include/armadillo_bits/config.hpp ${ARMADILLO_PATCH_FILE2}
- CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
+ URL_MD5 ${armadillo_MD5}
+ PATCH_COMMAND patch -N /include/armadillo_bits/config.hpp ${ARMADILLO_PATCH_FILE}
+ CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DBUILD_SHARED_LIBS=OFF
BUILD_IN_SOURCE 1
BUILD_COMMAND make
UPDATE_COMMAND ""
@@ -686,7 +665,14 @@ if(NOT ARMADILLO_FOUND)
ExternalProject_Get_Property(armadillo-${armadillo_RELEASE} binary_dir)
set(ARMADILLO_INCLUDE_DIRS ${binary_dir}/include )
find_library(LAPACK NAMES lapack HINTS /usr/lib /usr/local/lib /usr/lib64)
- set(ARMADILLO_LIBRARIES ${LAPACK} ${GFORTRAN} ${binary_dir}/${CMAKE_FIND_LIBRARY_PREFIXES}armadillo.a)
+ if(OS_IS_MACOSX)
+ find_library(BLAS blas)
+ endif(OS_IS_MACOSX)
+ find_package(OpenBLAS)
+ if(OPENBLAS_FOUND)
+ set(BLAS ${OPENBLAS})
+ endif(OPENBLAS_FOUND)
+ set(ARMADILLO_LIBRARIES ${BLAS} ${LAPACK} ${GFORTRAN} ${binary_dir}/${CMAKE_FIND_LIBRARY_PREFIXES}armadillo.a)
set(LOCAL_ARMADILLO true CACHE STRING "Armadillo downloaded and built automatically" FORCE)
# Save a copy at the thirdparty folder
file(COPY ${CMAKE_CURRENT_BINARY_DIR}/armadillo-${armadillo_RELEASE}
@@ -700,27 +686,6 @@ endif(NOT ARMADILLO_FOUND)
-###############################################################################
-# OpenCL
-###############################################################################
-find_package(OpenCL)
-if($ENV{DISABLE_OPENCL})
- set(DISABLE_OPENCL TRUE)
-endif($ENV{DISABLE_OPENCL})
-if(DISABLE_OPENCL)
- set(OPENCL_FOUND FALSE)
-else(DISABLE_OPENCL)
- if(OPENCL_FOUND)
- message(STATUS "OpenCL has been found and will be used by some processing blocks")
- message(STATUS "You can disable OpenCL use by doing 'cmake -DDISABLE_OPENCL=1 ../' ")
- endif(OPENCL_FOUND)
-endif(DISABLE_OPENCL)
-if(NOT OPENCL_FOUND)
- message(STATUS "Processing blocks using OpenCL will not be built.")
-endif(NOT OPENCL_FOUND)
-
-
-
################################################################################
# OpenSSL - http://www.openssl.org
################################################################################
@@ -742,41 +707,173 @@ if(NOT OPENSSL_FOUND)
endif(NOT OPENSSL_FOUND)
+
+################################################################################
+# Doxygen - http://www.stack.nl/~dimitri/doxygen/index.html (OPTIONAL)
+################################################################################
+find_package(Doxygen)
+if(DOXYGEN_FOUND)
+ message(STATUS "Doxygen found.")
+ message(STATUS "You can build the documentation with 'make doc'." )
+ message(STATUS "When done, point your browser to ${CMAKE_SOURCE_DIR}/html/index.html")
+ set(HAVE_DOT ${DOXYGEN_DOT_FOUND})
+ file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} top_srcdir)
+ file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} top_builddir)
+ find_package(LATEX)
+ if (PDFLATEX_COMPILER)
+ set(GENERATE_PDF_DOCUMENTATION "YES")
+ set(GNSSSDR_USE_MATHJAX "NO")
+ else(PDFLATEX_COMPILER)
+ set(GENERATE_PDF_DOCUMENTATION "NO")
+ set(GNSSSDR_USE_MATHJAX "YES")
+ endif(PDFLATEX_COMPILER)
+ configure_file(${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile.in
+ ${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile
+ @ONLY
+ )
+ add_custom_target(doc
+ ${DOXYGEN_EXECUTABLE} ${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ COMMENT "Generating API documentation with Doxygen." VERBATIM
+ )
+ if(LATEX_COMPILER)
+ message(STATUS "'make pdfmanual' will generate a manual at ${CMAKE_SOURCE_DIR}/docs/GNSS-SDR_manual.pdf")
+ add_custom_target(pdfmanual
+ COMMAND ${CMAKE_MAKE_PROGRAM}
+ COMMAND ${CMAKE_COMMAND} -E copy refman.pdf ${CMAKE_SOURCE_DIR}/docs/GNSS-SDR_manual.pdf
+ COMMAND ${CMAKE_MAKE_PROGRAM} clean
+ DEPENDS doc
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs/latex
+ COMMENT "Generating PDF manual with Doxygen." VERBATIM
+ )
+ endif(LATEX_COMPILER)
+ message(STATUS "'make doc-clean' will clean the documentation.")
+ add_custom_target(doc-clean
+ COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_SOURCE_DIR}/docs/html
+ COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_SOURCE_DIR}/docs/latex
+ COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_SOURCE_DIR}/docs/GNSS-SDR_manual.pdf
+ COMMENT "Cleaning documentation." VERBATIM
+ )
+else(DOXYGEN_FOUND)
+ message(STATUS " Doxygen has not been found in your system.")
+ message(STATUS " You can get nice code documentation by using it!")
+ message(STATUS " Get it from http://www.stack.nl/~dimitri/doxygen/index.html")
+ if(OS_IS_LINUX)
+ if(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
+ message(" or simply by doing 'sudo yum install doxygen-latex'.")
+ else(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
+ message(" or simply by doing 'sudo apt-get install doxygen-latex'.")
+ endif(${LINUX_DISTRIBUTION} MATCHES "Fedora" OR ${LINUX_DISTRIBUTION} MATCHES "Red Hat")
+ endif(OS_IS_LINUX)
+ if(OS_IS_MACOSX)
+ message(STATUS " or simply by doing 'sudo port install doxygen +latex'.")
+ endif(OS_IS_MACOSX)
+endif(DOXYGEN_FOUND)
+
+
+
+###############################################################################
+# OpenCL (OPTIONAL)
+###############################################################################
+if(ENABLE_OPENCL)
+ find_package(OpenCL)
+ if($ENV{DISABLE_OPENCL})
+ set(DISABLE_OPENCL TRUE)
+ endif($ENV{DISABLE_OPENCL})
+ if(DISABLE_OPENCL)
+ set(OPENCL_FOUND FALSE)
+ else(DISABLE_OPENCL)
+ if(OPENCL_FOUND)
+ message(STATUS "OpenCL has been found and will be used by some processing blocks")
+ message(STATUS "You can disable OpenCL use by doing 'cmake -DENABLE_OPENCL=OFF ../' ")
+ endif(OPENCL_FOUND)
+ endif(DISABLE_OPENCL)
+ if(ENABLE_GENERIC_ARCH)
+ set(OPENCL_FOUND FALSE)
+ message(STATUS "ENABLE_GENERIC_ARCH is set to ON so the use of OpenCL has been disabled.")
+ endif(ENABLE_GENERIC_ARCH)
+ if(NOT OPENCL_FOUND)
+ message(STATUS "Processing blocks using OpenCL will not be built.")
+ endif(NOT OPENCL_FOUND)
+else(ENABLE_OPENCL)
+ set(OPENCL_FOUND FALSE)
+endif(ENABLE_OPENCL)
+
+
+
+
+################################################################################
+# GPerftools - http://code.google.com/p/gperftools/ (OPTIONAL)
+################################################################################
+
+if(ENABLE_GPERFTOOLS)
+ find_package(Gperftools)
+ if ( NOT GPERFTOOLS_FOUND )
+ message(STATUS "Although ENABLE_GPERFTOOLS has been set to ON, GPerftools has not been found.")
+ message(STATUS "Binaries will be compiled without 'tcmalloc' and 'profiler' libraries.")
+ message(STATUS "You can install GPerftools from http://code.google.com/p/gperftools/")
+ else( NOT GPERFTOOLS_FOUND )
+ message(STATUS "GPerftools libraries found." )
+ message(STATUS "Binaries will be compiled with 'tcmalloc' and 'profiler' libraries.")
+ endif( NOT GPERFTOOLS_FOUND )
+endif(ENABLE_GPERFTOOLS)
+
+
+
################################################################################
# Setup of optional drivers
################################################################################
-if( $ENV{GN3S_DRIVER} )
- message(STATUS "GN3S_DRIVER variable found." )
- # copy firmware to install folder
- # Build project gr-gn3s
-else( $ENV{GN3S_DRIVER} )
- if( GN3S_DRIVER )
- message(STATUS "GN3S driver will be compiled")
- else( GNSS_DRIVER )
- message(STATUS "GN3S_DRIVER is not defined." )
- message(STATUS "Define it with 'export GN3S_DRIVER=1' to add support for the GN3S dongle." )
- endif( GN3S_DRIVER )
-endif($ENV{GN3S_DRIVER} )
-if( $ENV{RAW_ARRAY_DRIVER} )
- message(STATUS "RAW_ARRAY_DRIVER variable found." )
+if($ENV{GN3S_DRIVER})
+ message(STATUS "GN3S_DRIVER environment variable found." )
+ set(ENABLE_GN3S ON)
+endif($ENV{GN3S_DRIVER})
+if(GN3S_DRIVER)
+ set(ENABLE_GN3S ON)
+endif(GN3S_DRIVER)
+if(ENABLE_GN3S)
+ message(STATUS "The GN3S driver will be compiled.")
+ message(STATUS "You can disable it with 'cmake -DENABLE_GN3S=OFF ../'" )
+else(ENABLE_GN3S)
+ message(STATUS "The (optional and experimental) GN3S driver is not enabled." )
+ message(STATUS "Enable it with 'cmake -DENABLE_GN3S=ON ../' to add support for the GN3S dongle." )
+endif(ENABLE_GN3S)
+
+
+if($ENV{RAW_ARRAY_DRIVER})
+ message(STATUS "RAW_ARRAY_DRIVER environment variable found." )
+ set(ENABLE_ARRAY ON)
+endif($ENV{RAW_ARRAY_DRIVER})
+if(RAW_ARRAY_DRIVER)
+ set(ENABLE_ARRAY ON)
+endif(RAW_ARRAY_DRIVER)
+if(ENABLE_ARRAY)
+ message(STATUS "CTTC's Antenna Array front-end driver will be compiled." )
+ message(STATUS "You can disable it with 'cmake -DENABLE_ARRAY=OFF ../'" )
# copy firmware to install folder
# Build project gr-dbfcttc
-else( $ENV{RAW_ARRAY_DRIVER} )
- if( RAW_ARRAY_DRIVER )
- message(STATUS "RAW_ARRAY_DRIVER driver will be compiled")
- else( RAW_ARRAY_DRIVER )
- message(STATUS "RAW_ARRAY_DRIVER is not defined." )
- message(STATUS "Define it with 'export RAW_ARRAY_DRIVER=1' to add support for the CTTC experimental array front-end." )
- endif( RAW_ARRAY_DRIVER )
-endif($ENV{RAW_ARRAY_DRIVER} )
+else(ENABLE_ARRAY)
+ message(STATUS "The (optional) CTTC's Antenna Array front-end driver is not enabled." )
+ message(STATUS "Enable it with 'cmake -DENABLE_ARRAY=ON ../' to add support for the CTTC experimental array front-end." )
+endif(ENABLE_ARRAY)
-if( $ENV{RTLSDR_DRIVER} )
- message(STATUS "RTLSDR_DRIVER variable found." )
+
+if($ENV{RTLSDR_DRIVER})
+ message(STATUS "RTLSDR_DRIVER environment variable found." )
+ set(ENABLE_RTLSDR ON)
+endif($ENV{RTLSDR_DRIVER})
+if(RAW_ARRAY_DRIVER)
+ set(ENABLE_RTLSDR ON)
+endif(RAW_ARRAY_DRIVER)
+if(ENABLE_RTLSDR)
+ message(STATUS "The driver for RTL-based dongles will be compiled." )
+ message(STATUS "You can disable it with 'cmake -DENABLE_RTLSDR=OFF ../'" )
# find libosmosdr (done in src/algorithms/signal_sources/adapters)
# find gr-osmosdr (done in src/algorithms/signal_sources/adapters)
-endif($ENV{RTLSDR_DRIVER} )
-
+else(ENABLE_RTLSDR)
+ message(STATUS "The (optional) driver for RTL-based dongles is not enabled." )
+ message(STATUS "Enable it with 'cmake -DENABLE_RTLSDR=ON ../' to add support for Realtek's RTL2832U-based USB dongles." )
+endif(ENABLE_RTLSDR)
########################################################################
@@ -802,7 +899,11 @@ if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
if(OS_IS_MACOSX)
set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -march=corei7 -mfpmath=sse")
else(OS_IS_MACOSX)
- set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -march=native -mfpmath=sse")
+ if(ENABLE_GENERIC_ARCH)
+ set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -mtune=generic")
+ else(ENABLE_GENERIC_ARCH)
+ set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -march=native -mfpmath=sse")
+ endif(ENABLE_GENERIC_ARCH)
endif(OS_IS_MACOSX)
endif(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
@@ -811,13 +912,18 @@ if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
add_definitions(-fvisibility=hidden)
endif()
-# Set GPerftools related flags if it is available
-# See http://gperftools.googlecode.com/svn/trunk/README
-if(GPERFTOOLS_FOUND)
- if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
- set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free")
- endif(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
-endif(GPERFTOOLS_FOUND)
+if(ENABLE_GPERFTOOLS)
+ # Set GPerftools related flags if it is available
+ # See http://gperftools.googlecode.com/svn/trunk/README
+ if(GPERFTOOLS_FOUND)
+ if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
+ set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free")
+ endif(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ set(MY_CXX_FLAGS "${MY_CXX_FLAGS} -fno-builtin")
+ endif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ endif(GPERFTOOLS_FOUND)
+endif(ENABLE_GPERFTOOLS)
list(APPEND CMAKE_CXX_FLAGS ${MY_CXX_FLAGS})
diff --git a/src/algorithms/libs/volk_gnsssdr/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr/CMakeLists.txt
new file mode 100644
index 000000000..77481beda
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/CMakeLists.txt
@@ -0,0 +1,183 @@
+#
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+
+########################################################################
+# Project setup
+########################################################################
+cmake_minimum_required(VERSION 2.6)
+if(NOT DEFINED CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE Release)
+endif()
+set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "Choose build type: None Debug Release RelWithDebInfo MinSizeRel")
+project(volk_gnsssdr)
+enable_language(CXX)
+enable_language(C)
+enable_testing()
+set(VERSION 0.1)
+set(LIBVER 0.0.0)
+
+set(CMAKE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) #allows this to be a sub-project
+set(CMAKE_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) #allows this to be a sub-project
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) #location for custom "Modules"
+
+########################################################################
+# Environment setup
+########################################################################
+IF(NOT DEFINED BOOST_ROOT)
+ SET(BOOST_ROOT ${CMAKE_INSTALL_PREFIX})
+ENDIF()
+
+IF(NOT DEFINED CROSSCOMPILE_MULTILIB)
+ SET(CROSSCOMPILE_MULTILIB "")
+ENDIF()
+SET(CROSSCOMPILE_MULTILIB ${CROSSCOMPILE_MULTILIB} CACHE STRING "Define \"true\" if you have and want to use multiple C development libs installed for cross compile")
+
+
+########################################################################
+# Dependencies setup
+########################################################################
+include(GrPython) #sets PYTHON_EXECUTABLE and PYTHON_DASH_B
+VOLK_PYTHON_CHECK_MODULE("python >= 2.5" sys "sys.version.split()[0] >= '2.5'" PYTHON_MIN_VER_FOUND)
+VOLK_PYTHON_CHECK_MODULE("Cheetah >= 2.0.0" Cheetah "Cheetah.Version >= '2.0.0'" CHEETAH_FOUND)
+
+if(NOT PYTHON_MIN_VER_FOUND)
+ message(FATAL_ERROR "Python 2.5 or greater required to build VOLK")
+endif()
+
+if(NOT CHEETAH_FOUND)
+ message(FATAL_ERROR "Cheetah templates required to build VOLK")
+endif()
+
+if(MSVC)
+ if (NOT DEFINED BOOST_ALL_DYN_LINK)
+ set(BOOST_ALL_DYN_LINK TRUE)
+ endif()
+ set(BOOST_ALL_DYN_LINK "${BOOST_ALL_DYN_LINK}" CACHE BOOL "boost enable dynamic linking")
+ if(BOOST_ALL_DYN_LINK)
+ add_definitions(-DBOOST_ALL_DYN_LINK) #setup boost auto-linking in msvc
+ else(BOOST_ALL_DYN_LINK)
+ unset(BOOST_REQUIRED_COMPONENTS) #empty components list for static link
+ endif(BOOST_ALL_DYN_LINK)
+endif(MSVC)
+include(VolkBoost)
+
+if(NOT Boost_FOUND)
+ message(FATAL_ERROR "VOLK Requires boost to build")
+endif()
+
+option(ENABLE_ORC "Enable Orc" True)
+if(ENABLE_ORC)
+ find_package(ORC)
+else(ENABLE_ORC)
+ message(STATUS "Disabling use of ORC")
+endif(ENABLE_ORC)
+
+########################################################################
+# Setup the package config file
+########################################################################
+#set variables found in the pc.in file
+set(prefix ${CMAKE_INSTALL_PREFIX})
+set(exec_prefix "\${prefix}")
+set(libdir "\${exec_prefix}/lib${LIB_SUFFIX}")
+set(includedir "\${prefix}/include")
+
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/volk_gnsssdr.pc.in
+ ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr.pc
+@ONLY)
+
+install(
+ FILES ${CMAKE_CURRENT_BINARY_DIR}/volk_gnsssdr.pc
+ DESTINATION lib${LIB_SUFFIX}/pkgconfig
+ COMPONENT "volk_gnsssdr_devel"
+)
+
+########################################################################
+# Install all headers in the include directories
+########################################################################
+set(VOLK_RUNTIME_DIR bin)
+set(VOLK_LIBRARY_DIR lib${LIB_SUFFIX})
+set(VOLK_INCLUDE_DIR include)
+
+install(
+ DIRECTORY ${CMAKE_SOURCE_DIR}/kernels/volk_gnsssdr
+ DESTINATION include COMPONENT "volk_gnsssdr_devel"
+ FILES_MATCHING PATTERN "*.h"
+)
+
+install(FILES
+ ${CMAKE_SOURCE_DIR}/include/volk_gnsssdr/volk_gnsssdr_prefs.h
+ ${CMAKE_SOURCE_DIR}/include/volk_gnsssdr/volk_gnsssdr_complex.h
+ ${CMAKE_SOURCE_DIR}/include/volk_gnsssdr/volk_gnsssdr_common.h
+ ${CMAKE_BINARY_DIR}/include/volk_gnsssdr/volk_gnsssdr.h
+ ${CMAKE_BINARY_DIR}/include/volk_gnsssdr/volk_gnsssdr_cpu.h
+ ${CMAKE_BINARY_DIR}/include/volk_gnsssdr/volk_gnsssdr_config_fixed.h
+ ${CMAKE_BINARY_DIR}/include/volk_gnsssdr/volk_gnsssdr_typedefs.h
+ ${CMAKE_SOURCE_DIR}/include/volk_gnsssdr/volk_gnsssdr_malloc.h
+ DESTINATION include/volk_gnsssdr
+ COMPONENT "volk_gnsssdr_devel"
+)
+
+########################################################################
+# Install cmake search routine for external use
+########################################################################
+
+if(NOT CMAKE_MODULES_DIR)
+ set(CMAKE_MODULES_DIR lib${LIB_SUFFIX}/cmake)
+endif(NOT CMAKE_MODULES_DIR)
+
+install(
+ FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/VolkConfig.cmake
+ DESTINATION ${CMAKE_MODULES_DIR}/volk_gnsssdr
+ COMPONENT "volk_gnsssdr_devel"
+)
+
+########################################################################
+# On Apple only, set install name and use rpath correctly, if not already set
+########################################################################
+if(APPLE)
+ if(NOT CMAKE_INSTALL_NAME_DIR)
+ set(CMAKE_INSTALL_NAME_DIR
+ ${CMAKE_INSTALL_PREFIX}/${GR_LIBRARY_DIR} CACHE
+ PATH "Library Install Name Destination Directory" FORCE)
+ endif(NOT CMAKE_INSTALL_NAME_DIR)
+ if(NOT CMAKE_INSTALL_RPATH)
+ set(CMAKE_INSTALL_RPATH
+ ${CMAKE_INSTALL_PREFIX}/${GR_LIBRARY_DIR} CACHE
+ PATH "Library Install RPath" FORCE)
+ endif(NOT CMAKE_INSTALL_RPATH)
+ if(NOT CMAKE_BUILD_WITH_INSTALL_RPATH)
+ set(CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE
+ BOOL "Do Build Using Library Install RPath" FORCE)
+ endif(NOT CMAKE_BUILD_WITH_INSTALL_RPATH)
+endif(APPLE)
+
+########################################################################
+# Setup the library
+########################################################################
+add_subdirectory(lib)
+
+########################################################################
+# And the utility apps
+########################################################################
+add_subdirectory(apps)
+add_subdirectory(python/volk_gnsssdr_modtool)
+
+########################################################################
+# Print summary
+########################################################################
+message(STATUS "Using install prefix: ${CMAKE_INSTALL_PREFIX}")
diff --git a/src/algorithms/libs/volk_gnsssdr/apps/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr/apps/CMakeLists.txt
new file mode 100644
index 000000000..3158c4280
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/apps/CMakeLists.txt
@@ -0,0 +1,61 @@
+#
+# Copyright 2011-2013 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+
+########################################################################
+# Setup profiler
+########################################################################
+if(Boost_FOUND)
+
+if(MSVC)
+ include_directories(${CMAKE_SOURCE_DIR}/cmake/msvc)
+endif(MSVC)
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/include
+ ${CMAKE_BINARY_DIR}/include
+ ${CMAKE_SOURCE_DIR}/lib
+ ${CMAKE_BINARY_DIR}/lib
+ ${Boost_INCLUDE_DIRS}
+)
+
+# MAKE volk_gnsssdr_profile
+add_executable(volk_gnsssdr_profile
+ ${CMAKE_CURRENT_SOURCE_DIR}/volk_gnsssdr_profile.cc
+ ${CMAKE_SOURCE_DIR}/lib/qa_utils.cc
+)
+
+target_link_libraries(volk_gnsssdr_profile volk_gnsssdr ${Boost_LIBRARIES})
+
+install(
+ TARGETS volk_gnsssdr_profile
+ DESTINATION bin
+ COMPONENT "volk_gnsssdr"
+)
+
+# MAKE volk_gnsssdr-config-info
+add_executable(volk_gnsssdr-config-info volk_gnsssdr-config-info.cc)
+target_link_libraries(volk_gnsssdr-config-info volk_gnsssdr ${Boost_LIBRARIES})
+
+install(
+ TARGETS volk_gnsssdr-config-info
+ DESTINATION bin
+ COMPONENT "volk_gnsssdr"
+)
+
+endif(Boost_FOUND)
diff --git a/src/algorithms/libs/volk_gnsssdr/apps/volk_gnsssdr-config-info.cc b/src/algorithms/libs/volk_gnsssdr/apps/volk_gnsssdr-config-info.cc
new file mode 100644
index 000000000..ec8c09525
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/apps/volk_gnsssdr-config-info.cc
@@ -0,0 +1,96 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+#include
+#endif
+
+#include
+#include "volk_gnsssdr/volk_gnsssdr.h"
+#include
+#include
+
+namespace po = boost::program_options;
+
+int
+main(int argc, char **argv)
+{
+ po::options_description desc("Program options: volk_gnsssdr-config-info [options]");
+ po::variables_map vm;
+
+ desc.add_options()
+ ("help,h", "print help message")
+ ("prefix", "print VOLK installation prefix")
+ ("builddate", "print VOLK build date (RFC2822 format)")
+ ("cc", "print VOLK C compiler version")
+ ("cflags", "print VOLK CFLAGS")
+ ("all-machines", "print VOLK machines built into library")
+ ("avail-machines", "print VOLK machines the current platform can use")
+ ("machine", "print the VOLK machine that will be used")
+ ("version,v", "print VOLK version")
+ ;
+
+ try {
+ po::store(po::parse_command_line(argc, argv, desc), vm);
+ po::notify(vm);
+ }
+ catch (po::error& error){
+ std::cerr << "Error: " << error.what() << std::endl << std::endl;
+ std::cerr << desc << std::endl;
+ return 1;
+ }
+
+ if(vm.size() == 0 || vm.count("help")) {
+ std::cout << desc << std::endl;
+ return 1;
+ }
+
+ if(vm.count("prefix"))
+ std::cout << volk_gnsssdr_prefix() << std::endl;
+
+ if(vm.count("builddate"))
+ std::cout << volk_gnsssdr_build_date() << std::endl;
+
+ if(vm.count("version"))
+ std::cout << volk_gnsssdr_version() << std::endl;
+
+ if(vm.count("cc"))
+ std::cout << volk_gnsssdr_c_compiler() << std::endl;
+
+ if(vm.count("cflags"))
+ std::cout << volk_gnsssdr_compiler_flags() << std::endl;
+
+ // stick an extra ';' to make output of this and avail-machines the
+ // same structure for easier parsing
+ if(vm.count("all-machines"))
+ std::cout << volk_gnsssdr_available_machines() << ";" << std::endl;
+
+ if(vm.count("avail-machines")) {
+ volk_gnsssdr_list_machines();
+ }
+
+ if(vm.count("machine")) {
+ std::cout << volk_gnsssdr_get_machine() << std::endl;
+ }
+
+ return 0;
+}
diff --git a/src/algorithms/libs/volk_gnsssdr/apps/volk_gnsssdr_profile.cc b/src/algorithms/libs/volk_gnsssdr/apps/volk_gnsssdr_profile.cc
new file mode 100644
index 000000000..c9ca8756c
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/apps/volk_gnsssdr_profile.cc
@@ -0,0 +1,163 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012-2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "qa_utils.h"
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace fs = boost::filesystem;
+
+int main(int argc, char *argv[]) {
+ // Adding program options
+ boost::program_options::options_description desc("Options");
+ desc.add_options()
+ ("help,h", "Print help messages")
+ ("benchmark,b",
+ boost::program_options::value()->default_value( false )
+ ->implicit_value( true ),
+ "Run all kernels (benchmark mode)")
+ ("tests-regex,R",
+ boost::program_options::value(),
+ "Run tests matching regular expression.")
+ ;
+
+ // Handle the options that were given
+ boost::program_options::variables_map vm;
+ bool benchmark_mode;
+ std::string kernel_regex;
+ bool store_results = true;
+ try {
+ boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
+ boost::program_options::notify(vm);
+ benchmark_mode = vm.count("benchmark")?vm["benchmark"].as():false;
+ if ( vm.count("tests-regex" ) ) {
+ kernel_regex = vm["tests-regex"].as();
+ store_results = false;
+ std::cout << "Warning: using a regexp will not save results to a config" << std::endl;
+ }
+ else {
+ kernel_regex = ".*";
+ store_results = true;
+ }
+ } catch (boost::program_options::error& error) {
+ std::cerr << "Error: " << error.what() << std::endl << std::endl;
+ std::cerr << desc << std::endl;
+ return 1;
+ }
+ /** --help option
+*/
+ if ( vm.count("help") )
+ {
+ std::cout << "The VOLK profiler." << std::endl
+ << desc << std::endl;
+ return 0;
+ }
+
+
+ // Run tests
+ std::vector results;
+
+ //VOLK_PROFILE(volk_gnsssdr_16i_x5_add_quad_16i_x4, 1e-4, 2046, 10000, &results, benchmark_mode, kernel_regex);
+ //VOLK_PROFILE(volk_gnsssdr_16i_branch_4_state_8, 1e-4, 2046, 10000, &results, benchmark_mode, kernel_regex);
+ //VOLK_PROFILE(volk_gnsssdr_16i_max_star_16i, 0, 0, 204602, 10000, &results, benchmark_mode, kernel_regex);
+ //VOLK_PROFILE(volk_gnsssdr_16i_max_star_horizontal_16i, 0, 0, 204602, 10000, &results, benchmark_mode, kernel_regex);
+ //VOLK_PROFILE(volk_gnsssdr_16i_permute_and_scalar_add, 1e-4, 0, 2046, 10000, &results, benchmark_mode, kernel_regex);
+ //VOLK_PROFILE(volk_gnsssdr_16i_x4_quad_max_star_16i, 1e-4, 0, 2046, 10000, &results, benchmark_mode, kernel_regex);
+ //VOLK_PROFILE(volk_gnsssdr_32fc_x2_conjugate_dot_prod_32fc, 1e-4, 0, 2046, 10000, &results, benchmark_mode, kernel_regex);
+ //VOLK_PROFILE(volk_gnsssdr_32fc_s32f_x2_power_spectral_density_32f, 1e-4, 2046, 10000, &results, benchmark_mode, kernel_regex);
+ //VOLK_PROFILE(volk_gnsssdr_32f_s32f_32f_fm_detect_32f, 1e-4, 2046, 10000, &results, benchmark_mode, kernel_regex);
+ //VOLK_PROFILE(volk_gnsssdr_32u_popcnt, 0, 0, 2046, 10000, &results, benchmark_mode, kernel_regex);
+ //VOLK_PROFILE(volk_gnsssdr_64u_popcnt, 0, 0, 2046, 10000, &results, benchmark_mode, kernel_regex);
+ //VOLK_PROFILE(volk_gnsssdr_32fc_s32fc_multiply_32fc, 1e-4, lv_32fc_t(1.0, 0.5), 204602, 1000, &results, benchmark_mode, kernel_regex);
+
+ // Until we can update the config on a kernel by kernel basis
+ // do not overwrite volk_gnsssdr_config when using a regex.
+
+ //GNSS-SDR PROTO-KERNELS
+ //lv_32fc_t sfv = lv_cmake((float)1, (float)2);
+ //VOLK_PROFILE(volk_gnsssdr_8ic_s8ic_multiply_8ic, 1e-4, sfv, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3, 1e-4, 0, 204602, 250, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_32fc_x7_cw_vepl_corr_32fc_x5, 1e-4, 0, 204602, 250, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_8ic_x5_cw_epl_corr_8ic_x3, 1e-4, 0, 204602, 250, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_16i_s32f_convert_32f, 1e-4, 32768.0, 204602, 10000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_32fc_x5_cw_epl_corr_32fc_x3, 1e-4, 0, 204602, 250, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_32f_accumulator_s32f, 1e-4, 0, 204602, 10000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_8i_accumulator_s8i, 1e-4, 0, 204602, 10000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_32f_index_max_16u, 3, 0, 204602, 5000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_8i_index_max_16u, 3, 0, 204602, 5000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_8i_max_s8i, 3, 0, 204602, 5000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_32f_x2_add_32f, 1e-4, 0, 204602, 10000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_8i_x2_add_8i, 1e-4, 0, 204602, 10000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_32fc_conjugate_32fc, 1e-4, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_8ic_conjugate_8ic, 1e-4, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_32fc_magnitude_squared_32f, 1e-4, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_8ic_magnitude_squared_8i, 1e-4, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_32fc_s32fc_multiply_32fc, 1e-4, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_8ic_s8ic_multiply_8ic, 1e-4, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_32fc_x2_dot_prod_32fc, 1e-4, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_8ic_x2_dot_prod_8ic, 1e-4, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_32fc_x2_multiply_32fc, 1e-4, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_8ic_x2_multiply_8ic, 1e-4, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ VOLK_PROFILE(volk_gnsssdr_8u_x2_multiply_8u, 1e-4, 0, 204602, 1000, &results, benchmark_mode, kernel_regex);
+ if(store_results) {
+ char path[1024];
+ volk_gnsssdr_get_config_path(path);
+
+ const fs::path config_path(path);
+
+ if (not fs::exists(config_path.branch_path()))
+ {
+ std::cout << "Creating " << config_path.branch_path() << "..." << std::endl;
+ fs::create_directories(config_path.branch_path());
+ }
+
+ std::cout << "Writing " << config_path << "..." << std::endl;
+ std::ofstream config(config_path.string().c_str());
+ if(!config.is_open()) { //either we don't have write access or we don't have the dir yet
+ std::cout << "Error opening file " << config_path << std::endl;
+ }
+
+ config << "\
+#this file is generated by volk_gnsssdr_profile.\n\
+#the function name is followed by the preferred architecture.\n\
+";
+
+ BOOST_FOREACH(std::string result, results) {
+ config << result << std::endl;
+ }
+ config.close();
+ }
+ else {
+ std::cout << "Warning: config not generated" << std::endl;
+ }
+}
diff --git a/src/algorithms/libs/volk_gnsssdr/cmake/CMakeParseArgumentsCopy.cmake b/src/algorithms/libs/volk_gnsssdr/cmake/CMakeParseArgumentsCopy.cmake
new file mode 100644
index 000000000..7ce4c49ae
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/cmake/CMakeParseArgumentsCopy.cmake
@@ -0,0 +1,138 @@
+# CMAKE_PARSE_ARGUMENTS( args...)
+#
+# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions for
+# parsing the arguments given to that macro or function.
+# It processes the arguments and defines a set of variables which hold the
+# values of the respective options.
+#
+# The argument contains all options for the respective macro,
+# i.e. keywords which can be used when calling the macro without any value
+# following, like e.g. the OPTIONAL keyword of the install() command.
+#
+# The argument contains all keywords for this macro
+# which are followed by one value, like e.g. DESTINATION keyword of the
+# install() command.
+#
+# The argument contains all keywords for this macro
+# which can be followed by more than one value, like e.g. the TARGETS or
+# FILES keywords of the install() command.
+#
+# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the
+# keywords listed in , and
+# a variable composed of the given
+# followed by "_" and the name of the respective keyword.
+# These variables will then hold the respective value from the argument list.
+# For the keywords this will be TRUE or FALSE.
+#
+# All remaining arguments are collected in a variable
+# _UNPARSED_ARGUMENTS, this can be checked afterwards to see whether
+# your macro was called with unrecognized parameters.
+#
+# As an example here a my_install() macro, which takes similar arguments as the
+# real install() command:
+#
+# function(MY_INSTALL)
+# set(options OPTIONAL FAST)
+# set(oneValueArgs DESTINATION RENAME)
+# set(multiValueArgs TARGETS CONFIGURATIONS)
+# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
+# ...
+#
+# Assume my_install() has been called like this:
+# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub)
+#
+# After the cmake_parse_arguments() call the macro will have set the following
+# variables:
+# MY_INSTALL_OPTIONAL = TRUE
+# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install()
+# MY_INSTALL_DESTINATION = "bin"
+# MY_INSTALL_RENAME = "" (was not used)
+# MY_INSTALL_TARGETS = "foo;bar"
+# MY_INSTALL_CONFIGURATIONS = "" (was not used)
+# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL"
+#
+# You can the continue and process these variables.
+#
+# Keywords terminate lists of values, e.g. if directly after a one_value_keyword
+# another recognized keyword follows, this is interpreted as the beginning of
+# the new option.
+# E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in
+# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would
+# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor.
+
+#=============================================================================
+# Copyright 2010 Alexander Neundorf
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+
+if(__CMAKE_PARSE_ARGUMENTS_INCLUDED)
+ return()
+endif()
+set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE)
+
+
+function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames)
+ # first set all result variables to empty/FALSE
+ foreach(arg_name ${_singleArgNames} ${_multiArgNames})
+ set(${prefix}_${arg_name})
+ endforeach(arg_name)
+
+ foreach(option ${_optionNames})
+ set(${prefix}_${option} FALSE)
+ endforeach(option)
+
+ set(${prefix}_UNPARSED_ARGUMENTS)
+
+ set(insideValues FALSE)
+ set(currentArgName)
+
+ # now iterate over all arguments and fill the result variables
+ foreach(currentArg ${ARGN})
+ list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword
+ list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword
+ list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword
+
+ if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1)
+ if(insideValues)
+ if("${insideValues}" STREQUAL "SINGLE")
+ set(${prefix}_${currentArgName} ${currentArg})
+ set(insideValues FALSE)
+ elseif("${insideValues}" STREQUAL "MULTI")
+ list(APPEND ${prefix}_${currentArgName} ${currentArg})
+ endif()
+ else(insideValues)
+ list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg})
+ endif(insideValues)
+ else()
+ if(NOT ${optionIndex} EQUAL -1)
+ set(${prefix}_${currentArg} TRUE)
+ set(insideValues FALSE)
+ elseif(NOT ${singleArgIndex} EQUAL -1)
+ set(currentArgName ${currentArg})
+ set(${prefix}_${currentArgName})
+ set(insideValues "SINGLE")
+ elseif(NOT ${multiArgIndex} EQUAL -1)
+ set(currentArgName ${currentArg})
+ set(${prefix}_${currentArgName})
+ set(insideValues "MULTI")
+ endif()
+ endif()
+
+ endforeach(currentArg)
+
+ # propagate the result variables to the caller:
+ foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames})
+ set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE)
+ endforeach(arg_name)
+ set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE)
+
+endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs)
diff --git a/src/algorithms/libs/volk_gnsssdr/cmake/FindORC.cmake b/src/algorithms/libs/volk_gnsssdr/cmake/FindORC.cmake
new file mode 100644
index 000000000..f21513f72
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/cmake/FindORC.cmake
@@ -0,0 +1,36 @@
+FIND_PACKAGE(PkgConfig)
+PKG_CHECK_MODULES(PC_ORC "orc-0.4 > 0.4.11")
+
+
+
+
+FIND_PROGRAM(ORCC_EXECUTABLE orcc
+ HINTS ${PC_ORC_TOOLSDIR}
+ PATHS ${ORC_ROOT}/bin ${CMAKE_INSTALL_PREFIX}/bin)
+
+FIND_PATH(ORC_INCLUDE_DIR NAMES orc/orc.h
+ HINTS ${PC_ORC_INCLUDEDIR}
+ PATHS ${ORC_ROOT}/include/orc-0.4 ${CMAKE_INSTALL_PREFIX}/include/orc-0.4)
+
+
+FIND_PATH(ORC_LIBRARY_DIR NAMES ${CMAKE_SHARED_LIBRARY_PREFIX}orc-0.4${CMAKE_SHARED_LIBRARY_SUFFIX}
+ HINTS ${PC_ORC_LIBDIR}
+ PATHS ${ORC_ROOT}/lib${LIB_SUFFIX} ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX})
+
+FIND_LIBRARY(ORC_LIB orc-0.4
+ HINTS ${PC_ORC_LIBRARY_DIRS}
+ PATHS ${ORC_ROOT}/lib${LIB_SUFFIX} ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX})
+
+LIST(APPEND ORC_LIBRARY
+ ${ORC_LIB}
+)
+
+
+SET(ORC_INCLUDE_DIRS ${ORC_INCLUDE_DIR})
+SET(ORC_LIBRARIES ${ORC_LIBRARY})
+SET(ORC_LIBRARY_DIRS ${ORC_LIBRARY_DIR})
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(ORC "orc files" ORC_LIBRARY ORC_INCLUDE_DIR ORCC_EXECUTABLE)
+
+mark_as_advanced(ORC_INCLUDE_DIR ORC_LIBRARY ORCC_EXECUTABLE)
diff --git a/src/algorithms/libs/volk_gnsssdr/cmake/GrPython.cmake b/src/algorithms/libs/volk_gnsssdr/cmake/GrPython.cmake
new file mode 100644
index 000000000..b7b561b7b
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/cmake/GrPython.cmake
@@ -0,0 +1,234 @@
+# Copyright 2010-2011,2013 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+if(DEFINED __INCLUDED_VOLK_PYTHON_CMAKE)
+ return()
+endif()
+set(__INCLUDED_VOLK_PYTHON_CMAKE TRUE)
+
+########################################################################
+# Setup the python interpreter:
+# This allows the user to specify a specific interpreter,
+# or finds the interpreter via the built-in cmake module.
+########################################################################
+#this allows the user to override PYTHON_EXECUTABLE
+if(PYTHON_EXECUTABLE)
+
+ set(PYTHONINTERP_FOUND TRUE)
+
+#otherwise if not set, try to automatically find it
+else(PYTHON_EXECUTABLE)
+
+ #use the built-in find script
+ find_package(PythonInterp 2)
+
+ #and if that fails use the find program routine
+ if(NOT PYTHONINTERP_FOUND)
+ find_program(PYTHON_EXECUTABLE NAMES python python2 python2.7 python2.6 python2.5)
+ if(PYTHON_EXECUTABLE)
+ set(PYTHONINTERP_FOUND TRUE)
+ endif(PYTHON_EXECUTABLE)
+ endif(NOT PYTHONINTERP_FOUND)
+
+endif(PYTHON_EXECUTABLE)
+
+#make the path to the executable appear in the cmake gui
+set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter")
+
+#make sure we can use -B with python (introduced in 2.6)
+if(PYTHON_EXECUTABLE)
+ execute_process(
+ COMMAND ${PYTHON_EXECUTABLE} -B -c ""
+ OUTPUT_QUIET ERROR_QUIET
+ RESULT_VARIABLE PYTHON_HAS_DASH_B_RESULT
+ )
+ if(PYTHON_HAS_DASH_B_RESULT EQUAL 0)
+ set(PYTHON_DASH_B "-B")
+ endif()
+endif(PYTHON_EXECUTABLE)
+
+########################################################################
+# Check for the existence of a python module:
+# - desc a string description of the check
+# - mod the name of the module to import
+# - cmd an additional command to run
+# - have the result variable to set
+########################################################################
+macro(VOLK_PYTHON_CHECK_MODULE desc mod cmd have)
+ message(STATUS "")
+ message(STATUS "Python checking for ${desc}")
+ execute_process(
+ COMMAND ${PYTHON_EXECUTABLE} -c "
+#########################################
+try: import ${mod}
+except:
+ try: ${mod}
+ except: exit(-1)
+try: assert ${cmd}
+except: exit(-1)
+#########################################"
+ RESULT_VARIABLE ${have}
+ )
+ if(${have} EQUAL 0)
+ message(STATUS "Python checking for ${desc} - found")
+ set(${have} TRUE)
+ else(${have} EQUAL 0)
+ message(STATUS "Python checking for ${desc} - not found")
+ set(${have} FALSE)
+ endif(${have} EQUAL 0)
+endmacro(VOLK_PYTHON_CHECK_MODULE)
+
+########################################################################
+# Sets the python installation directory VOLK_PYTHON_DIR
+########################################################################
+execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "
+from distutils import sysconfig
+print sysconfig.get_python_lib(plat_specific=True, prefix='')
+" OUTPUT_VARIABLE VOLK_PYTHON_DIR OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+file(TO_CMAKE_PATH ${VOLK_PYTHON_DIR} VOLK_PYTHON_DIR)
+
+########################################################################
+# Create an always-built target with a unique name
+# Usage: VOLK_UNIQUE_TARGET( )
+########################################################################
+function(VOLK_UNIQUE_TARGET desc)
+ file(RELATIVE_PATH reldir ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
+ execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib
+unique = hashlib.md5('${reldir}${ARGN}').hexdigest()[:5]
+print(re.sub('\\W', '_', '${desc} ${reldir} ' + unique))"
+ OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE)
+ add_custom_target(${_target} ALL DEPENDS ${ARGN})
+endfunction(VOLK_UNIQUE_TARGET)
+
+########################################################################
+# Install python sources (also builds and installs byte-compiled python)
+########################################################################
+function(VOLK_PYTHON_INSTALL)
+ include(CMakeParseArgumentsCopy)
+ CMAKE_PARSE_ARGUMENTS(VOLK_PYTHON_INSTALL "" "DESTINATION;COMPONENT" "FILES;PROGRAMS" ${ARGN})
+
+ ####################################################################
+ if(VOLK_PYTHON_INSTALL_FILES)
+ ####################################################################
+ install(${ARGN}) #installs regular python files
+
+ #create a list of all generated files
+ unset(pysrcfiles)
+ unset(pycfiles)
+ unset(pyofiles)
+ foreach(pyfile ${VOLK_PYTHON_INSTALL_FILES})
+ get_filename_component(pyfile ${pyfile} ABSOLUTE)
+ list(APPEND pysrcfiles ${pyfile})
+
+ #determine if this file is in the source or binary directory
+ file(RELATIVE_PATH source_rel_path ${CMAKE_CURRENT_SOURCE_DIR} ${pyfile})
+ string(LENGTH "${source_rel_path}" source_rel_path_len)
+ file(RELATIVE_PATH binary_rel_path ${CMAKE_CURRENT_BINARY_DIR} ${pyfile})
+ string(LENGTH "${binary_rel_path}" binary_rel_path_len)
+
+ #and set the generated path appropriately
+ if(${source_rel_path_len} GREATER ${binary_rel_path_len})
+ set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${binary_rel_path})
+ else()
+ set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${source_rel_path})
+ endif()
+ list(APPEND pycfiles ${pygenfile}c)
+ list(APPEND pyofiles ${pygenfile}o)
+
+ #ensure generation path exists
+ get_filename_component(pygen_path ${pygenfile} PATH)
+ file(MAKE_DIRECTORY ${pygen_path})
+
+ endforeach(pyfile)
+
+ #the command to generate the pyc files
+ add_custom_command(
+ DEPENDS ${pysrcfiles} OUTPUT ${pycfiles}
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pycfiles}
+ )
+
+ #the command to generate the pyo files
+ add_custom_command(
+ DEPENDS ${pysrcfiles} OUTPUT ${pyofiles}
+ COMMAND ${PYTHON_EXECUTABLE} -O ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pyofiles}
+ )
+
+ #create install rule and add generated files to target list
+ set(python_install_gen_targets ${pycfiles} ${pyofiles})
+ install(FILES ${python_install_gen_targets}
+ DESTINATION ${VOLK_PYTHON_INSTALL_DESTINATION}
+ COMPONENT ${VOLK_PYTHON_INSTALL_COMPONENT}
+ )
+
+
+ ####################################################################
+ elseif(VOLK_PYTHON_INSTALL_PROGRAMS)
+ ####################################################################
+ file(TO_NATIVE_PATH ${PYTHON_EXECUTABLE} pyexe_native)
+
+ if (CMAKE_CROSSCOMPILING)
+ set(pyexe_native "/usr/bin/env python")
+ endif()
+
+ foreach(pyfile ${VOLK_PYTHON_INSTALL_PROGRAMS})
+ get_filename_component(pyfile_name ${pyfile} NAME)
+ get_filename_component(pyfile ${pyfile} ABSOLUTE)
+ string(REPLACE "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" pyexefile "${pyfile}.exe")
+ list(APPEND python_install_gen_targets ${pyexefile})
+
+ get_filename_component(pyexefile_path ${pyexefile} PATH)
+ file(MAKE_DIRECTORY ${pyexefile_path})
+
+ add_custom_command(
+ OUTPUT ${pyexefile} DEPENDS ${pyfile}
+ COMMAND ${PYTHON_EXECUTABLE} -c
+ "open('${pyexefile}','w').write('\#!${pyexe_native}\\n'+open('${pyfile}').read())"
+ COMMENT "Shebangin ${pyfile_name}"
+ VERBATIM
+ )
+
+ #on windows, python files need an extension to execute
+ get_filename_component(pyfile_ext ${pyfile} EXT)
+ if(WIN32 AND NOT pyfile_ext)
+ set(pyfile_name "${pyfile_name}.py")
+ endif()
+
+ install(PROGRAMS ${pyexefile} RENAME ${pyfile_name}
+ DESTINATION ${VOLK_PYTHON_INSTALL_DESTINATION}
+ COMPONENT ${VOLK_PYTHON_INSTALL_COMPONENT}
+ )
+ endforeach(pyfile)
+
+ endif()
+
+ VOLK_UNIQUE_TARGET("pygen" ${python_install_gen_targets})
+
+endfunction(VOLK_PYTHON_INSTALL)
+
+########################################################################
+# Write the python helper script that generates byte code files
+########################################################################
+file(WRITE ${CMAKE_BINARY_DIR}/python_compile_helper.py "
+import sys, py_compile
+files = sys.argv[1:]
+srcs, gens = files[:len(files)/2], files[len(files)/2:]
+for src, gen in zip(srcs, gens):
+ py_compile.compile(file=src, cfile=gen, doraise=True)
+")
diff --git a/src/algorithms/libs/volk_gnsssdr/cmake/VolkBoost.cmake b/src/algorithms/libs/volk_gnsssdr/cmake/VolkBoost.cmake
new file mode 100644
index 000000000..318820e10
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/cmake/VolkBoost.cmake
@@ -0,0 +1,98 @@
+# Copyright 2010-2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+if(DEFINED __INCLUDED_VOLK_BOOST_CMAKE)
+ return()
+endif()
+set(__INCLUDED_VOLK_BOOST_CMAKE TRUE)
+
+########################################################################
+# Setup Boost and handle some system specific things
+########################################################################
+
+set(BOOST_REQUIRED_COMPONENTS
+ filesystem
+ system
+ unit_test_framework
+ program_options
+)
+
+if(UNIX AND NOT BOOST_ROOT AND EXISTS "/usr/lib64")
+ list(APPEND BOOST_LIBRARYDIR "/usr/lib64") #fedora 64-bit fix
+endif(UNIX AND NOT BOOST_ROOT AND EXISTS "/usr/lib64")
+
+if(MSVC)
+ set(BOOST_REQUIRED_COMPONENTS ${BOOST_REQUIRED_COMPONENTS} chrono)
+
+ if (NOT DEFINED BOOST_ALL_DYN_LINK)
+ set(BOOST_ALL_DYN_LINK TRUE)
+ endif()
+ set(BOOST_ALL_DYN_LINK "${BOOST_ALL_DYN_LINK}" CACHE BOOL "boost enable dynamic linking")
+ if(BOOST_ALL_DYN_LINK)
+ add_definitions(-DBOOST_ALL_DYN_LINK) #setup boost auto-linking in msvc
+ else(BOOST_ALL_DYN_LINK)
+ unset(BOOST_REQUIRED_COMPONENTS) #empty components list for static link
+ endif(BOOST_ALL_DYN_LINK)
+endif(MSVC)
+
+find_package(Boost "1.35" COMPONENTS ${BOOST_REQUIRED_COMPONENTS})
+
+# This does not allow us to disable specific versions. It is used
+# internally by cmake to know the formation newer versions. As newer
+# Boost version beyond what is shown here are produced, we must extend
+# this list. To disable Boost versions, see below.
+set(Boost_ADDITIONAL_VERSIONS
+ "1.35.0" "1.35" "1.36.0" "1.36" "1.37.0" "1.37" "1.38.0" "1.38" "1.39.0" "1.39"
+ "1.40.0" "1.40" "1.41.0" "1.41" "1.42.0" "1.42" "1.43.0" "1.43" "1.44.0" "1.44"
+ "1.45.0" "1.45" "1.46.0" "1.46" "1.47.0" "1.47" "1.48.0" "1.48" "1.49.0" "1.49"
+ "1.50.0" "1.50" "1.51.0" "1.51" "1.52.0" "1.52" "1.53.0" "1.53" "1.54.0" "1.54"
+ "1.55.0" "1.55" "1.56.0" "1.56" "1.57.0" "1.57" "1.58.0" "1.58" "1.59.0" "1.59"
+ "1.60.0" "1.60" "1.61.0" "1.61" "1.62.0" "1.62" "1.63.0" "1.63" "1.64.0" "1.64"
+ "1.65.0" "1.65" "1.66.0" "1.66" "1.67.0" "1.67" "1.68.0" "1.68" "1.69.0" "1.69"
+)
+
+# Boost 1.52 disabled, see https://svn.boost.org/trac/boost/ticket/7669
+# Similar problems with Boost 1.46 and 1.47.
+
+OPTION(ENABLE_BAD_BOOST "Enable known bad versions of Boost" OFF)
+if(ENABLE_BAD_BOOST)
+ MESSAGE(STATUS "Enabling use of known bad versions of Boost.")
+endif(ENABLE_BAD_BOOST)
+
+# For any unsuitable Boost version, add the version number below in
+# the following format: XXYYZZ
+# Where:
+# XX is the major version ('10' for version 1)
+# YY is the minor version number ('46' for 1.46)
+# ZZ is the patcher version number (typically just '00')
+set(Boost_NOGO_VERSIONS
+ 104600 104601 104700 105200
+ )
+
+foreach(ver ${Boost_NOGO_VERSIONS})
+ if(${Boost_VERSION} EQUAL ${ver})
+ if(NOT ENABLE_BAD_BOOST)
+ MESSAGE(STATUS "WARNING: Found a known bad version of Boost (v${Boost_VERSION}). Disabling.")
+ set(Boost_FOUND FALSE)
+ else(NOT ENABLE_BAD_BOOST)
+ MESSAGE(STATUS "WARNING: Found a known bad version of Boost (v${Boost_VERSION}). Continuing anyway.")
+ set(Boost_FOUND TRUE)
+ endif(NOT ENABLE_BAD_BOOST)
+ endif(${Boost_VERSION} EQUAL ${ver})
+endforeach(ver)
diff --git a/src/algorithms/libs/volk_gnsssdr/cmake/VolkConfig.cmake b/src/algorithms/libs/volk_gnsssdr/cmake/VolkConfig.cmake
new file mode 100644
index 000000000..7d58b1923
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/cmake/VolkConfig.cmake
@@ -0,0 +1,26 @@
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(PC_VOLK volk_gnsssdr)
+
+FIND_PATH(
+ VOLK_INCLUDE_DIRS
+ NAMES volk_gnsssdr/volk_gnsssdr.h
+ HINTS $ENV{VOLK_DIR}/include
+ ${PC_VOLK_INCLUDEDIR}
+ PATHS /usr/local/include
+ /usr/include
+)
+
+FIND_LIBRARY(
+ VOLK_LIBRARIES
+ NAMES volk_gnsssdr
+ HINTS $ENV{VOLK_DIR}/lib
+ ${PC_VOLK_LIBDIR}
+ PATHS /usr/local/lib
+ /usr/local/lib64
+ /usr/lib
+ /usr/lib64
+)
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(VOLK DEFAULT_MSG VOLK_LIBRARIES VOLK_INCLUDE_DIRS)
+MARK_AS_ADVANCED(VOLK_LIBRARIES VOLK_INCLUDE_DIRS)
diff --git a/src/algorithms/libs/volk_gnsssdr/cmake/msvc/config.h b/src/algorithms/libs/volk_gnsssdr/cmake/msvc/config.h
new file mode 100644
index 000000000..43792c783
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/cmake/msvc/config.h
@@ -0,0 +1,58 @@
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_CONFIG_H_ // [
+#define _MSC_CONFIG_H_
+
+////////////////////////////////////////////////////////////////////////
+// enable inline functions for C code
+////////////////////////////////////////////////////////////////////////
+#ifndef __cplusplus
+# define inline __inline
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// signed size_t
+////////////////////////////////////////////////////////////////////////
+#include
+typedef ptrdiff_t ssize_t;
+
+////////////////////////////////////////////////////////////////////////
+// rint functions
+////////////////////////////////////////////////////////////////////////
+#include
+static inline long lrint(double x){return (long)(x > 0.0 ? x + 0.5 : x - 0.5);}
+static inline long lrintf(float x){return (long)(x > 0.0f ? x + 0.5f : x - 0.5f);}
+static inline long long llrint(double x){return (long long)(x > 0.0 ? x + 0.5 : x - 0.5);}
+static inline long long llrintf(float x){return (long long)(x > 0.0f ? x + 0.5f : x - 0.5f);}
+static inline double rint(double x){return (x > 0.0)? floor(x + 0.5) : ceil(x - 0.5);}
+static inline float rintf(float x){return (x > 0.0f)? floorf(x + 0.5f) : ceilf(x - 0.5f);}
+
+////////////////////////////////////////////////////////////////////////
+// math constants
+////////////////////////////////////////////////////////////////////////
+#define INFINITY HUGE_VAL
+
+# define M_E 2.7182818284590452354 /* e */
+# define M_LOG2E 1.4426950408889634074 /* log_2 e */
+# define M_LOG10E 0.43429448190325182765 /* log_10 e */
+# define M_LN2 0.69314718055994530942 /* log_e 2 */
+# define M_LN10 2.30258509299404568402 /* log_e 10 */
+# define M_PI 3.14159265358979323846 /* pi */
+# define M_PI_2 1.57079632679489661923 /* pi/2 */
+# define M_PI_4 0.78539816339744830962 /* pi/4 */
+# define M_1_PI 0.31830988618379067154 /* 1/pi */
+# define M_2_PI 0.63661977236758134308 /* 2/pi */
+# define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */
+# define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
+# define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
+
+////////////////////////////////////////////////////////////////////////
+// random and srandom
+////////////////////////////////////////////////////////////////////////
+#include
+static inline long int random (void) { return rand(); }
+static inline void srandom (unsigned int seed) { srand(seed); }
+
+#endif // _MSC_CONFIG_H_ ]
diff --git a/src/algorithms/libs/volk_gnsssdr/cmake/msvc/inttypes.h b/src/algorithms/libs/volk_gnsssdr/cmake/msvc/inttypes.h
new file mode 100644
index 000000000..0a1b60fc1
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/cmake/msvc/inttypes.h
@@ -0,0 +1,301 @@
+// ISO C9x compliant inttypes.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+// Copyright (c) 2006 Alexander Chemeris
+//
+// 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. The name of the author may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_INTTYPES_H_ // [
+#define _MSC_INTTYPES_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include
+
+// 7.8 Format conversion of integer types
+
+typedef struct {
+ intmax_t quot;
+ intmax_t rem;
+} imaxdiv_t;
+
+// 7.8.1 Macros for format specifiers
+
+// The fprintf macros for signed integers are:
+#define PRId8 "d"
+#define PRIi8 "i"
+#define PRIdLEAST8 "d"
+#define PRIiLEAST8 "i"
+#define PRIdFAST8 "d"
+#define PRIiFAST8 "i"
+
+#define PRId16 "hd"
+#define PRIi16 "hi"
+#define PRIdLEAST16 "hd"
+#define PRIiLEAST16 "hi"
+#define PRIdFAST16 "hd"
+#define PRIiFAST16 "hi"
+
+#define PRId32 "I32d"
+#define PRIi32 "I32i"
+#define PRIdLEAST32 "I32d"
+#define PRIiLEAST32 "I32i"
+#define PRIdFAST32 "I32d"
+#define PRIiFAST32 "I32i"
+
+#define PRId64 "I64d"
+#define PRIi64 "I64i"
+#define PRIdLEAST64 "I64d"
+#define PRIiLEAST64 "I64i"
+#define PRIdFAST64 "I64d"
+#define PRIiFAST64 "I64i"
+
+#define PRIdMAX "I64d"
+#define PRIiMAX "I64i"
+
+#define PRIdPTR "Id"
+#define PRIiPTR "Ii"
+
+// The fprintf macros for unsigned integers are:
+#define PRIo8 "o"
+#define PRIu8 "u"
+#define PRIx8 "x"
+#define PRIX8 "X"
+#define PRIoLEAST8 "o"
+#define PRIuLEAST8 "u"
+#define PRIxLEAST8 "x"
+#define PRIXLEAST8 "X"
+#define PRIoFAST8 "o"
+#define PRIuFAST8 "u"
+#define PRIxFAST8 "x"
+#define PRIXFAST8 "X"
+
+#define PRIo16 "ho"
+#define PRIu16 "hu"
+#define PRIx16 "hx"
+#define PRIX16 "hX"
+#define PRIoLEAST16 "ho"
+#define PRIuLEAST16 "hu"
+#define PRIxLEAST16 "hx"
+#define PRIXLEAST16 "hX"
+#define PRIoFAST16 "ho"
+#define PRIuFAST16 "hu"
+#define PRIxFAST16 "hx"
+#define PRIXFAST16 "hX"
+
+#define PRIo32 "I32o"
+#define PRIu32 "I32u"
+#define PRIx32 "I32x"
+#define PRIX32 "I32X"
+#define PRIoLEAST32 "I32o"
+#define PRIuLEAST32 "I32u"
+#define PRIxLEAST32 "I32x"
+#define PRIXLEAST32 "I32X"
+#define PRIoFAST32 "I32o"
+#define PRIuFAST32 "I32u"
+#define PRIxFAST32 "I32x"
+#define PRIXFAST32 "I32X"
+
+#define PRIo64 "I64o"
+#define PRIu64 "I64u"
+#define PRIx64 "I64x"
+#define PRIX64 "I64X"
+#define PRIoLEAST64 "I64o"
+#define PRIuLEAST64 "I64u"
+#define PRIxLEAST64 "I64x"
+#define PRIXLEAST64 "I64X"
+#define PRIoFAST64 "I64o"
+#define PRIuFAST64 "I64u"
+#define PRIxFAST64 "I64x"
+#define PRIXFAST64 "I64X"
+
+#define PRIoMAX "I64o"
+#define PRIuMAX "I64u"
+#define PRIxMAX "I64x"
+#define PRIXMAX "I64X"
+
+#define PRIoPTR "Io"
+#define PRIuPTR "Iu"
+#define PRIxPTR "Ix"
+#define PRIXPTR "IX"
+
+// The fscanf macros for signed integers are:
+#define SCNd8 "d"
+#define SCNi8 "i"
+#define SCNdLEAST8 "d"
+#define SCNiLEAST8 "i"
+#define SCNdFAST8 "d"
+#define SCNiFAST8 "i"
+
+#define SCNd16 "hd"
+#define SCNi16 "hi"
+#define SCNdLEAST16 "hd"
+#define SCNiLEAST16 "hi"
+#define SCNdFAST16 "hd"
+#define SCNiFAST16 "hi"
+
+#define SCNd32 "ld"
+#define SCNi32 "li"
+#define SCNdLEAST32 "ld"
+#define SCNiLEAST32 "li"
+#define SCNdFAST32 "ld"
+#define SCNiFAST32 "li"
+
+#define SCNd64 "I64d"
+#define SCNi64 "I64i"
+#define SCNdLEAST64 "I64d"
+#define SCNiLEAST64 "I64i"
+#define SCNdFAST64 "I64d"
+#define SCNiFAST64 "I64i"
+
+#define SCNdMAX "I64d"
+#define SCNiMAX "I64i"
+
+#ifdef _WIN64 // [
+# define SCNdPTR "I64d"
+# define SCNiPTR "I64i"
+#else // _WIN64 ][
+# define SCNdPTR "ld"
+# define SCNiPTR "li"
+#endif // _WIN64 ]
+
+// The fscanf macros for unsigned integers are:
+#define SCNo8 "o"
+#define SCNu8 "u"
+#define SCNx8 "x"
+#define SCNX8 "X"
+#define SCNoLEAST8 "o"
+#define SCNuLEAST8 "u"
+#define SCNxLEAST8 "x"
+#define SCNXLEAST8 "X"
+#define SCNoFAST8 "o"
+#define SCNuFAST8 "u"
+#define SCNxFAST8 "x"
+#define SCNXFAST8 "X"
+
+#define SCNo16 "ho"
+#define SCNu16 "hu"
+#define SCNx16 "hx"
+#define SCNX16 "hX"
+#define SCNoLEAST16 "ho"
+#define SCNuLEAST16 "hu"
+#define SCNxLEAST16 "hx"
+#define SCNXLEAST16 "hX"
+#define SCNoFAST16 "ho"
+#define SCNuFAST16 "hu"
+#define SCNxFAST16 "hx"
+#define SCNXFAST16 "hX"
+
+#define SCNo32 "lo"
+#define SCNu32 "lu"
+#define SCNx32 "lx"
+#define SCNX32 "lX"
+#define SCNoLEAST32 "lo"
+#define SCNuLEAST32 "lu"
+#define SCNxLEAST32 "lx"
+#define SCNXLEAST32 "lX"
+#define SCNoFAST32 "lo"
+#define SCNuFAST32 "lu"
+#define SCNxFAST32 "lx"
+#define SCNXFAST32 "lX"
+
+#define SCNo64 "I64o"
+#define SCNu64 "I64u"
+#define SCNx64 "I64x"
+#define SCNX64 "I64X"
+#define SCNoLEAST64 "I64o"
+#define SCNuLEAST64 "I64u"
+#define SCNxLEAST64 "I64x"
+#define SCNXLEAST64 "I64X"
+#define SCNoFAST64 "I64o"
+#define SCNuFAST64 "I64u"
+#define SCNxFAST64 "I64x"
+#define SCNXFAST64 "I64X"
+
+#define SCNoMAX "I64o"
+#define SCNuMAX "I64u"
+#define SCNxMAX "I64x"
+#define SCNXMAX "I64X"
+
+#ifdef _WIN64 // [
+# define SCNoPTR "I64o"
+# define SCNuPTR "I64u"
+# define SCNxPTR "I64x"
+# define SCNXPTR "I64X"
+#else // _WIN64 ][
+# define SCNoPTR "lo"
+# define SCNuPTR "lu"
+# define SCNxPTR "lx"
+# define SCNXPTR "lX"
+#endif // _WIN64 ]
+
+// 7.8.2 Functions for greatest-width integer types
+
+// 7.8.2.1 The imaxabs function
+#define imaxabs _abs64
+
+// 7.8.2.2 The imaxdiv function
+
+// This is modified version of div() function from Microsoft's div.c found
+// in %MSVC.NET%\crt\src\div.c
+#ifdef STATIC_IMAXDIV // [
+static
+#else // STATIC_IMAXDIV ][
+_inline
+#endif // STATIC_IMAXDIV ]
+imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
+{
+ imaxdiv_t result;
+
+ result.quot = numer / denom;
+ result.rem = numer % denom;
+
+ if (numer < 0 && result.rem > 0) {
+ // did division wrong; must fix up
+ ++result.quot;
+ result.rem -= denom;
+ }
+
+ return result;
+}
+
+// 7.8.2.3 The strtoimax and strtoumax functions
+#define strtoimax _strtoi64
+#define strtoumax _strtoui64
+
+// 7.8.2.4 The wcstoimax and wcstoumax functions
+#define wcstoimax _wcstoi64
+#define wcstoumax _wcstoui64
+
+
+#endif // _MSC_INTTYPES_H_ ]
diff --git a/src/algorithms/libs/volk_gnsssdr/cmake/msvc/stdbool.h b/src/algorithms/libs/volk_gnsssdr/cmake/msvc/stdbool.h
new file mode 100644
index 000000000..ca4581d37
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/cmake/msvc/stdbool.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2005, 2006 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef STDBOOL_WIN32_H
+#define STDBOOL_WIN32_H
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef __cplusplus
+
+typedef unsigned char bool;
+
+#define true 1
+#define false 0
+
+#ifndef CASSERT
+#define CASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1];
+#endif
+
+CASSERT(sizeof(bool) == 1, bool_is_one_byte)
+CASSERT(true, true_is_true)
+CASSERT(!false, false_is_false)
+
+#endif
+
+#endif
diff --git a/src/algorithms/libs/volk_gnsssdr/cmake/msvc/stdint.h b/src/algorithms/libs/volk_gnsssdr/cmake/msvc/stdint.h
new file mode 100644
index 000000000..108bc8982
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/cmake/msvc/stdint.h
@@ -0,0 +1,251 @@
+// ISO C9x compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+// Copyright (c) 2006-2008 Alexander Chemeris
+//
+// 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. The name of the author may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap include with 'extern "C++" {}'
+// or compiler give many errors like this:
+// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+# include
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+# define _W64 __w64
+# else
+# define _W64
+# endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+ typedef signed char int8_t;
+ typedef signed short int16_t;
+ typedef signed int int32_t;
+ typedef unsigned char uint8_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+#else
+ typedef signed __int8 int8_t;
+ typedef signed __int16 int16_t;
+ typedef signed __int32 int32_t;
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int32 uint32_t;
+#endif
+typedef signed __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t int_least8_t;
+typedef int16_t int_least16_t;
+typedef int32_t int_least32_t;
+typedef int64_t int_least64_t;
+typedef uint8_t uint_least8_t;
+typedef uint16_t uint_least16_t;
+typedef uint32_t uint_least32_t;
+typedef uint64_t uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t int_fast8_t;
+typedef int16_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef int64_t int_fast64_t;
+typedef uint8_t uint_fast8_t;
+typedef uint16_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+typedef uint64_t uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+ typedef signed __int64 intptr_t;
+ typedef unsigned __int64 uintptr_t;
+#else // _WIN64 ][
+ typedef _W64 signed int intptr_t;
+ typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t intmax_t;
+typedef uint64_t uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN ((int8_t)_I8_MIN)
+#define INT8_MAX _I8_MAX
+#define INT16_MIN ((int16_t)_I16_MIN)
+#define INT16_MAX _I16_MAX
+#define INT32_MIN ((int32_t)_I32_MIN)
+#define INT32_MAX _I32_MAX
+#define INT64_MIN ((int64_t)_I64_MIN)
+#define INT64_MAX _I64_MAX
+#define UINT8_MAX _UI8_MAX
+#define UINT16_MAX _UI16_MAX
+#define UINT32_MAX _UI32_MAX
+#define UINT64_MAX _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST16_MAX INT16_MAX
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST32_MAX INT32_MAX
+#define INT_LEAST64_MIN INT64_MIN
+#define INT_LEAST64_MAX INT64_MAX
+#define UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN INT8_MIN
+#define INT_FAST8_MAX INT8_MAX
+#define INT_FAST16_MIN INT16_MIN
+#define INT_FAST16_MAX INT16_MAX
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST32_MAX INT32_MAX
+#define INT_FAST64_MIN INT64_MIN
+#define INT_FAST64_MAX INT64_MAX
+#define UINT_FAST8_MAX UINT8_MAX
+#define UINT_FAST16_MAX UINT16_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+# define INTPTR_MIN INT64_MIN
+# define INTPTR_MAX INT64_MAX
+# define UINTPTR_MAX UINT64_MAX
+#else // _WIN64 ][
+# define INTPTR_MIN INT32_MIN
+# define INTPTR_MAX INT32_MAX
+# define UINTPTR_MAX UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+# define PTRDIFF_MIN _I64_MIN
+# define PTRDIFF_MAX _I64_MAX
+#else // _WIN64 ][
+# define PTRDIFF_MIN _I32_MIN
+# define PTRDIFF_MAX _I32_MAX
+#endif // _WIN64 ]
+
+#define SIG_ATOMIC_MIN INT_MIN
+#define SIG_ATOMIC_MAX INT_MAX
+
+#ifndef SIZE_MAX // [
+# ifdef _WIN64 // [
+# define SIZE_MAX _UI64_MAX
+# else // _WIN64 ][
+# define SIZE_MAX _UI32_MAX
+# endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in
+#ifndef WCHAR_MIN // [
+# define WCHAR_MIN 0
+#endif // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+# define WCHAR_MAX _UI16_MAX
+#endif // WCHAR_MAX ]
+
+#define WINT_MIN 0
+#define WINT_MAX _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val) val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val) val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+#ifndef INTMAX_C
+#define INTMAX_C INT64_C
+#endif
+#ifndef UINTMAX_C
+#define UINTMAX_C UINT64_C
+#endif
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+
+#endif // _MSC_STDINT_H_ ]
diff --git a/src/algorithms/libs/volk_gnsssdr/gen/archs.xml b/src/algorithms/libs/volk_gnsssdr/gen/archs.xml
new file mode 100644
index 000000000..e570fe5d2
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/gen/archs.xml
@@ -0,0 +1,204 @@
+
+
+
+
+
+
+
+ -maltivec
+ 16
+
+
+
+
+ -mfloat-abi=softfp
+
+
+
+ -mfloat-abi=hard
+
+
+
+ -mfpu=neon
+ -funsafe-math-optimizations
+ 16
+
+
+
+
+ -m32
+
+
+
+
+ 0x80000001
+
+
+ 3
+ 0x80000001
+ 29
+
+ -m64
+ -m64
+
+
+
+
+ 3
+ 0x80000001
+ 31
+
+ -m3dnow
+ -m3dnow
+ 8
+
+
+
+
+ 3
+ 0x80000001
+ 5
+
+ -msse4.2
+ -msse4.2
+ 16
+
+
+
+
+ 2
+ 0x00000001
+ 23
+
+ -mpopcnt
+ -mpopcnt
+ /arch:AVX
+
+
+
+
+ 3
+ 0x00000001
+ 23
+
+ -mmmx
+ -mmmx
+ /arch:SSE
+ 8
+
+
+
+
+ 3
+ 0x00000001
+ 25
+
+ -msse
+ -msse
+ /arch:SSE
+ _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
+ xmmintrin.h
+ 16
+
+
+
+
+ 3
+ 0x00000001
+ 26
+
+ -msse2
+ -msse2
+ /arch:SSE2
+ 16
+
+
+
+
+
+
+
+
+
+
+
+ 2
+ 0x00000001
+ 0
+
+ -msse3
+ -msse3
+ /arch:AVX
+ _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
+ pmmintrin.h
+ 16
+
+
+
+
+ 2
+ 0x00000001
+ 9
+
+ -mssse3
+ -mssse3
+ /arch:AVX
+ 16
+
+
+
+
+ 2
+ 0x80000001
+ 6
+
+ -msse4a
+ -msse4a
+ 16
+
+
+
+
+ 2
+ 0x00000001
+ 19
+
+ -msse4.1
+ -msse4.1
+ /arch:AVX
+ 16
+
+
+
+
+ 2
+ 0x00000001
+ 20
+
+ -msse4.2
+ -msse4.2
+ /arch:AVX
+ 16
+
+
+
+
+ 2
+ 0x00000001
+ 28
+
+
+
+ 2
+ 0x00000001
+ 27
+
+
+
+ -mavx
+ -mavx
+ /arch:AVX
+ 32
+
+
+
diff --git a/src/algorithms/libs/volk_gnsssdr/gen/machines.xml b/src/algorithms/libs/volk_gnsssdr/gen/machines.xml
new file mode 100644
index 000000000..357bf7519
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/gen/machines.xml
@@ -0,0 +1,55 @@
+
+
+
+generic orc|
+
+
+
+
+
+generic neon softfp|hardfp orc|
+
+
+
+
+generic 32|64| mmx| sse sse2 orc|
+
+
+
+generic 32|64 mmx sse sse2 sse3 orc|
+
+
+
+generic 32|64 mmx sse sse2 sse3 ssse3 orc|
+
+
+
+generic 32|64 mmx sse sse2 sse3 sse4_a popcount orc|
+
+
+
+generic 32|64 mmx sse sse2 sse3 ssse3 sse4_1 orc|
+
+
+
+generic 32|64 mmx sse sse2 sse3 ssse3 sse4_1 sse4_2 popcount orc|
+
+
+
+
+generic 32|64| mmx| sse sse2 sse3 ssse3 sse4_1 sse4_2 popcount avx orc|
+
+
+
+generic altivec
+
+
+
diff --git a/src/algorithms/libs/volk_gnsssdr/gen/volk_gnsssdr_arch_defs.py b/src/algorithms/libs/volk_gnsssdr/gen/volk_gnsssdr_arch_defs.py
new file mode 100644
index 000000000..3c75e1374
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/gen/volk_gnsssdr_arch_defs.py
@@ -0,0 +1,85 @@
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+
+archs = list()
+arch_dict = dict()
+
+class arch_class:
+ def __init__(self, flags, checks, **kwargs):
+ for key, cast, failval in (
+ ('name', str, None),
+ ('environment', str, None),
+ ('include', str, None),
+ ('alignment', int, 1)
+ ):
+ try: setattr(self, key, cast(kwargs[key]))
+ except: setattr(self, key, failval)
+ self.checks = checks
+ assert(self.name)
+ self._flags = flags
+
+ def is_supported(self, compiler):
+ if not self._flags.keys(): return True
+ return compiler in self._flags.keys()
+
+ def get_flags(self, compiler):
+ try: return self._flags[compiler]
+ except KeyError: return list()
+
+ def __repr__(self): return self.name
+
+def register_arch(**kwargs):
+ arch = arch_class(**kwargs)
+ archs.append(arch)
+ arch_dict[arch.name] = arch
+
+########################################################################
+# register the arches
+########################################################################
+#TODO skip the XML and put it here
+from xml.dom import minidom
+import os
+gendir = os.path.dirname(__file__)
+archs_xml = minidom.parse(os.path.join(gendir, 'archs.xml')).getElementsByTagName('arch')
+for arch_xml in archs_xml:
+ kwargs = dict()
+ for attr in arch_xml.attributes.keys():
+ kwargs[attr] = arch_xml.attributes[attr].value
+ for node in arch_xml.childNodes:
+ try:
+ name = node.tagName
+ val = arch_xml.getElementsByTagName(name)[0].firstChild.data
+ kwargs[name] = val
+ except: pass
+ checks = list()
+ for check_xml in arch_xml.getElementsByTagName("check"):
+ name = check_xml.attributes["name"].value
+ params = list()
+ for param_xml in check_xml.getElementsByTagName("param"):
+ params.append(param_xml.firstChild.data)
+ checks.append([name, params])
+ flags = dict()
+ for flag_xml in arch_xml.getElementsByTagName("flag"):
+ name = flag_xml.attributes["compiler"].value
+ if not flags.has_key(name): flags[name] = list()
+ flags[name].append(flag_xml.firstChild.data)
+ #force kwargs keys to be of type str, not unicode for py25
+ kwargs = dict((str(k), v) for k, v in kwargs.iteritems())
+ register_arch(flags=flags, checks=checks, **kwargs)
+
+if __name__ == '__main__':
+ print archs
diff --git a/src/algorithms/libs/volk_gnsssdr/gen/volk_gnsssdr_compile_utils.py b/src/algorithms/libs/volk_gnsssdr/gen/volk_gnsssdr_compile_utils.py
new file mode 100644
index 000000000..05de9a546
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/gen/volk_gnsssdr_compile_utils.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+
+import optparse
+import volk_gnsssdr_arch_defs
+import volk_gnsssdr_machine_defs
+
+def do_arch_flags_list(compiler):
+ output = list()
+ for arch in volk_gnsssdr_arch_defs.archs:
+ if not arch.is_supported(compiler): continue
+ fields = [arch.name] + arch.get_flags(compiler)
+ output.append(','.join(fields))
+ print ';'.join(output)
+
+def do_machines_list(arch_names):
+ output = list()
+ for machine in volk_gnsssdr_machine_defs.machines:
+ machine_arch_set = set(machine.arch_names)
+ if set(arch_names).intersection(machine_arch_set) == machine_arch_set:
+ output.append(machine.name)
+ print ';'.join(output)
+
+def do_machine_flags_list(compiler, machine_name):
+ output = list()
+ machine = volk_gnsssdr_machine_defs.machine_dict[machine_name]
+ for arch in machine.archs:
+ output.extend(arch.get_flags(compiler))
+ print ' '.join(output)
+
+def main():
+ parser = optparse.OptionParser()
+ parser.add_option('--mode', type='string')
+ parser.add_option('--compiler', type='string')
+ parser.add_option('--archs', type='string')
+ parser.add_option('--machine', type='string')
+ (opts, args) = parser.parse_args()
+
+ if opts.mode == 'arch_flags': return do_arch_flags_list(opts.compiler.lower())
+ if opts.mode == 'machines': return do_machines_list(opts.archs.split(';'))
+ if opts.mode == 'machine_flags': return do_machine_flags_list(opts.compiler.lower(), opts.machine)
+
+if __name__ == '__main__': main()
diff --git a/src/algorithms/libs/volk_gnsssdr/gen/volk_gnsssdr_kernel_defs.py b/src/algorithms/libs/volk_gnsssdr/gen/volk_gnsssdr_kernel_defs.py
new file mode 100644
index 000000000..b3f03f627
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/gen/volk_gnsssdr_kernel_defs.py
@@ -0,0 +1,209 @@
+#
+# Copyright 2011-2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import os
+import re
+import sys
+import glob
+
+########################################################################
+# Strip comments from a c/cpp file.
+# Input is code string, output is code string without comments.
+# http://stackoverflow.com/questions/241327/python-snippet-to-remove-c-and-c-comments
+########################################################################
+def comment_remover(text):
+ def replacer(match):
+ s = match.group(0)
+ if s.startswith('/'):
+ return ""
+ else:
+ return s
+ pattern = re.compile(
+ r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
+ re.DOTALL | re.MULTILINE
+ )
+ return re.sub(pattern, replacer, text)
+
+########################################################################
+# Split code into nested sections according to ifdef preprocessor macros
+########################################################################
+def split_into_nested_ifdef_sections(code):
+ sections = list()
+ section = ''
+ header = 'text'
+ in_section_depth = 0
+ for i, line in enumerate(code.splitlines()):
+ m = re.match('^(\s*)#(\s*)(\w+)(.*)$', line)
+ line_is = 'normal'
+ if m:
+ p0, p1, fcn, stuff = m.groups()
+ if fcn in ('if', 'ifndef', 'ifdef'): line_is = 'if'
+ if fcn in ('else', 'elif'): line_is = 'else'
+ if fcn in ('endif',): line_is = 'end'
+
+ if line_is == 'if': in_section_depth += 1
+ if line_is == 'end': in_section_depth -= 1
+
+ if in_section_depth == 1 and line_is == 'if':
+ sections.append((header, section))
+ section = ''
+ header = line
+ continue
+
+ if in_section_depth == 1 and line_is == 'else':
+ sections.append((header, section))
+ section = ''
+ header = line
+ continue
+
+ if in_section_depth == 0 and line_is == 'end':
+ sections.append((header, section))
+ section = ''
+ header = 'text'
+ continue
+
+ section += line + '\n'
+
+ sections.append((header, section)) #and pack remainder into sections
+ sections = [sec for sec in sections if sec[1].strip()] #filter empty sections
+
+ #recurse into non-text sections to fill subsections
+ for i, (header, section) in enumerate(sections):
+ if header == 'text': continue
+ sections[i] = (header, split_into_nested_ifdef_sections(section))
+
+ return sections
+
+########################################################################
+# Recursive print of sections to test code above
+########################################################################
+def print_sections(sections, indent = ' '):
+ for header, body in sections:
+ if header == 'text':
+ print indent, ('\n'+indent).join(body.splitlines())
+ continue
+ print indent.replace(' ', '-') + '>', header
+ print_sections(body, indent + ' ')
+
+########################################################################
+# Flatten a section to just body text
+########################################################################
+def flatten_section_text(sections):
+ output = ''
+ for hdr, bdy in sections:
+ if hdr != 'text': output += flatten_section_text(bdy)
+ else: output += bdy
+ return output
+
+########################################################################
+# Extract kernel info from section, represent as an implementation
+########################################################################
+class impl_class:
+ def __init__(self, kern_name, header, body):
+ #extract LV_HAVE_*
+ self.deps = set(map(str.lower, re.findall('LV_HAVE_(\w+)', header)))
+ #extract function suffix and args
+ body = flatten_section_text(body)
+ try:
+ fcn_matcher = re.compile('^.*(%s\\w*)\\s*\\((.*)$'%kern_name, re.DOTALL | re.MULTILINE)
+ body = body.split('{')[0].rsplit(')', 1)[0] #get the part before the open ){ bracket
+ m = fcn_matcher.match(body)
+ impl_name, the_rest = m.groups()
+ self.name = impl_name.replace(kern_name+'_', '')
+ self.args = list()
+ fcn_args = the_rest.split(',')
+ for fcn_arg in fcn_args:
+ arg_matcher = re.compile('^\s*(.*\\W)\s*(\w+)\s*$', re.DOTALL | re.MULTILINE)
+ m = arg_matcher.match(fcn_arg)
+ arg_type, arg_name = m.groups()
+ self.args.append((arg_type, arg_name))
+ except Exception as ex:
+ raise Exception, 'I cant parse the function prototype from: %s in %s\n%s'%(kern_name, body, ex)
+
+ assert self.name
+ self.is_aligned = self.name.startswith('a_')
+
+ def __repr__(self):
+ return self.name
+
+########################################################################
+# Get sets of LV_HAVE_* from the code
+########################################################################
+def extract_lv_haves(code):
+ haves = list()
+ for line in code.splitlines():
+ if not line.strip().startswith('#'): continue
+ have_set = set(map(str.lower, re.findall('LV_HAVE_(\w+)', line)))
+ if have_set: haves.append(have_set)
+ return haves
+
+########################################################################
+# Represent a processing kernel, parse from file
+########################################################################
+class kernel_class:
+ def __init__(self, kernel_file):
+ self.name = os.path.splitext(os.path.basename(kernel_file))[0]
+ self.pname = self.name.replace('volk_gnsssdr_', 'p_')
+ code = open(kernel_file, 'r').read()
+ code = comment_remover(code)
+ sections = split_into_nested_ifdef_sections(code)
+ self._impls = list()
+ for header, section in sections:
+ if 'ifndef' not in header.lower(): continue
+ for sub_hdr, body in section:
+ if 'if' not in sub_hdr.lower(): continue
+ if 'LV_HAVE_' not in sub_hdr: continue
+ self._impls.append(impl_class(
+ kern_name=self.name, header=sub_hdr, body=body,
+ ))
+ assert(self._impls)
+ self.has_dispatcher = False
+ for impl in self._impls:
+ if impl.name == 'dispatcher':
+ self._impls.remove(impl)
+ self.has_dispatcher = True
+ break
+ self.args = self._impls[0].args
+ self.arglist_types = ', '.join([a[0] for a in self.args])
+ self.arglist_full = ', '.join(['%s %s'%a for a in self.args])
+ self.arglist_names = ', '.join([a[1] for a in self.args])
+
+ def get_impls(self, archs):
+ archs = set(archs)
+ impls = list()
+ for impl in self._impls:
+ if impl.deps.intersection(archs) == impl.deps:
+ impls.append(impl)
+ return impls
+
+ def __repr__(self):
+ return self.name
+
+########################################################################
+# Extract information from the VOLK kernels
+########################################################################
+__file__ = os.path.abspath(__file__)
+srcdir = os.path.dirname(os.path.dirname(__file__))
+kernel_files = glob.glob(os.path.join(srcdir, "kernels", "volk_gnsssdr", "*.h"))
+kernels = map(kernel_class, kernel_files)
+
+if __name__ == '__main__':
+ print kernels
diff --git a/src/algorithms/libs/volk_gnsssdr/gen/volk_gnsssdr_machine_defs.py b/src/algorithms/libs/volk_gnsssdr/gen/volk_gnsssdr_machine_defs.py
new file mode 100644
index 000000000..174106634
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/gen/volk_gnsssdr_machine_defs.py
@@ -0,0 +1,74 @@
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+
+from volk_gnsssdr_arch_defs import arch_dict
+
+machines = list()
+machine_dict = dict()
+
+class machine_class:
+ def __init__(self, name, archs):
+ self.name = name
+ self.archs = list()
+ self.arch_names = list()
+ for arch_name in archs:
+ if not arch_name: continue
+ arch = arch_dict[arch_name]
+ self.archs.append(arch)
+ self.arch_names.append(arch_name)
+ self.alignment = max(map(lambda a: a.alignment, self.archs))
+
+ def __repr__(self): return self.name
+
+def register_machine(name, archs):
+ for i, arch_name in enumerate(archs):
+ if '|' in arch_name: #handle special arch names with the '|'
+ for arch_sub in arch_name.split('|'):
+ if arch_sub:
+ register_machine(name+'_'+arch_sub, archs[:i] + [arch_sub] + archs[i+1:])
+ else:
+ register_machine(name, archs[:i] + archs[i+1:])
+ return
+ machine = machine_class(name=name, archs=archs)
+ machines.append(machine)
+ machine_dict[machine.name] = machine
+
+########################################################################
+# register the machines
+########################################################################
+#TODO skip the XML and put it here
+from xml.dom import minidom
+import os
+gendir = os.path.dirname(__file__)
+machines_xml = minidom.parse(os.path.join(gendir, 'machines.xml')).getElementsByTagName('machine')
+for machine_xml in machines_xml:
+ kwargs = dict()
+ for attr in machine_xml.attributes.keys():
+ kwargs[attr] = machine_xml.attributes[attr].value
+ for node in machine_xml.childNodes:
+ try:
+ name = node.tagName
+ val = machine_xml.getElementsByTagName(name)[0].firstChild.data
+ kwargs[name] = val
+ except: pass
+ kwargs['archs'] = kwargs['archs'].split()
+ #force kwargs keys to be of type str, not unicode for py25
+ kwargs = dict((str(k), v) for k, v in kwargs.iteritems())
+ register_machine(**kwargs)
+
+if __name__ == '__main__':
+ print machines
diff --git a/src/algorithms/libs/volk_gnsssdr/gen/volk_gnsssdr_tmpl_utils.py b/src/algorithms/libs/volk_gnsssdr/gen/volk_gnsssdr_tmpl_utils.py
new file mode 100644
index 000000000..c4577af62
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/gen/volk_gnsssdr_tmpl_utils.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import os
+import re
+import sys
+import optparse
+import volk_gnsssdr_arch_defs
+import volk_gnsssdr_machine_defs
+import volk_gnsssdr_kernel_defs
+from Cheetah import Template
+
+def __escape_pre_processor(code):
+ out = list()
+ for line in code.splitlines():
+ m = re.match('^(\s*)#(\s*)(\w+)(.*)$', line)
+ if m:
+ p0, p1, fcn, stuff = m.groups()
+ conly = fcn in ('include', 'define', 'ifdef', 'ifndef', 'endif', 'elif', 'pragma')
+ both = fcn in ('if', 'else')
+ istmpl = '$' in stuff
+ if 'defined' in stuff: istmpl = False
+ if conly or (both and not istmpl):
+ line = '%s\\#%s%s%s'%(p0, p1, fcn, stuff)
+ out.append(line)
+ return '\n'.join(out)
+
+def __parse_tmpl(_tmpl, **kwargs):
+ defs = {
+ 'archs': volk_gnsssdr_arch_defs.archs,
+ 'arch_dict': volk_gnsssdr_arch_defs.arch_dict,
+ 'machines': volk_gnsssdr_machine_defs.machines,
+ 'machine_dict': volk_gnsssdr_machine_defs.machine_dict,
+ 'kernels': volk_gnsssdr_kernel_defs.kernels,
+ }
+ defs.update(kwargs)
+ _tmpl = __escape_pre_processor(_tmpl)
+ _tmpl = """
+
+/* this file was generated by volk_gnsssdr template utils, do not edit! */
+
+""" + _tmpl
+ return str(Template.Template(_tmpl, defs))
+
+def main():
+ parser = optparse.OptionParser()
+ parser.add_option('--input', type='string')
+ parser.add_option('--output', type='string')
+ (opts, args) = parser.parse_args()
+
+ output = __parse_tmpl(open(opts.input).read(), args=args)
+ if opts.output: open(opts.output, 'w').write(output)
+ else: print output
+
+if __name__ == '__main__': main()
diff --git a/src/algorithms/libs/volk_gnsssdr/include/volk_gnsssdr/constants.h b/src/algorithms/libs/volk_gnsssdr/include/volk_gnsssdr/constants.h
new file mode 100644
index 000000000..f08960557
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/include/volk_gnsssdr/constants.h
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_VOLK_CONSTANTS_H
+#define INCLUDED_VOLK_CONSTANTS_H
+
+#include
+
+__VOLK_DECL_BEGIN
+
+VOLK_API char* volk_gnsssdr_prefix();
+VOLK_API char* volk_gnsssdr_build_date();
+VOLK_API char* volk_gnsssdr_version();
+VOLK_API char* volk_gnsssdr_c_compiler();
+VOLK_API char* volk_gnsssdr_compiler_flags();
+VOLK_API char* volk_gnsssdr_available_machines();
+
+__VOLK_DECL_END
+
+#endif /* INCLUDED_VOLK_CONSTANTS_H */
diff --git a/src/algorithms/libs/volk_gnsssdr/include/volk_gnsssdr/volk_gnsssdr_common.h b/src/algorithms/libs/volk_gnsssdr/include/volk_gnsssdr/volk_gnsssdr_common.h
new file mode 100644
index 000000000..c48057cd9
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/include/volk_gnsssdr/volk_gnsssdr_common.h
@@ -0,0 +1,96 @@
+#ifndef INCLUDED_LIBVOLK_COMMON_H
+#define INCLUDED_LIBVOLK_COMMON_H
+
+////////////////////////////////////////////////////////////////////////
+// Cross-platform attribute macros
+////////////////////////////////////////////////////////////////////////
+#if defined __GNUC__
+# define __VOLK_ATTR_ALIGNED(x) __attribute__((aligned(x)))
+# define __VOLK_ATTR_UNUSED __attribute__((unused))
+# define __VOLK_ATTR_INLINE __attribute__((always_inline))
+# define __VOLK_ATTR_DEPRECATED __attribute__((deprecated))
+# if __GNUC__ >= 4
+# define __VOLK_ATTR_EXPORT __attribute__((visibility("default")))
+# define __VOLK_ATTR_IMPORT __attribute__((visibility("default")))
+# else
+# define __VOLK_ATTR_EXPORT
+# define __VOLK_ATTR_IMPORT
+# endif
+#elif _MSC_VER
+# define __VOLK_ATTR_ALIGNED(x) __declspec(align(x))
+# define __VOLK_ATTR_UNUSED
+# define __VOLK_ATTR_INLINE __forceinline
+# define __VOLK_ATTR_DEPRECATED __declspec(deprecated)
+# define __VOLK_ATTR_EXPORT __declspec(dllexport)
+# define __VOLK_ATTR_IMPORT __declspec(dllimport)
+#else
+# define __VOLK_ATTR_ALIGNED(x)
+# define __VOLK_ATTR_UNUSED
+# define __VOLK_ATTR_INLINE
+# define __VOLK_ATTR_DEPRECATED
+# define __VOLK_ATTR_EXPORT
+# define __VOLK_ATTR_IMPORT
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// Ignore annoying warnings in MSVC
+////////////////////////////////////////////////////////////////////////
+#if defined(_MSC_VER)
+# pragma warning(disable: 4244) //'conversion' conversion from 'type1' to 'type2', possible loss of data
+# pragma warning(disable: 4305) //'identifier' : truncation from 'type1' to 'type2'
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// C-linkage declaration macros
+// FIXME: due to the usage of complex.h, require gcc for c-linkage
+////////////////////////////////////////////////////////////////////////
+#if defined(__cplusplus) && (__GNUC__)
+# define __VOLK_DECL_BEGIN extern "C" {
+# define __VOLK_DECL_END }
+#else
+# define __VOLK_DECL_BEGIN
+# define __VOLK_DECL_END
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// Define VOLK_API for library symbols
+// http://gcc.gnu.org/wiki/Visibility
+////////////////////////////////////////////////////////////////////////
+#ifdef volk_gnsssdr_EXPORTS
+# define VOLK_API __VOLK_ATTR_EXPORT
+#else
+# define VOLK_API __VOLK_ATTR_IMPORT
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// The bit128 union used by some
+////////////////////////////////////////////////////////////////////////
+#include
+
+#ifdef LV_HAVE_SSE
+#include
+#endif
+
+#ifdef LV_HAVE_SSE2
+#include
+#endif
+
+union bit128{
+ uint16_t i16[8];
+ uint32_t i[4];
+ float f[4];
+ double d[2];
+
+ #ifdef LV_HAVE_SSE
+ __m128 float_vec;
+ #endif
+
+ #ifdef LV_HAVE_SSE2
+ __m128i int_vec;
+ __m128d double_vec;
+ #endif
+};
+
+#define bit128_p(x) ((union bit128 *)(x))
+
+#endif /*INCLUDED_LIBVOLK_COMMON_H*/
diff --git a/src/algorithms/libs/volk_gnsssdr/include/volk_gnsssdr/volk_gnsssdr_complex.h b/src/algorithms/libs/volk_gnsssdr/include/volk_gnsssdr/volk_gnsssdr_complex.h
new file mode 100644
index 000000000..5bd925044
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/include/volk_gnsssdr/volk_gnsssdr_complex.h
@@ -0,0 +1,86 @@
+#ifndef INCLUDE_VOLK_COMPLEX_H
+#define INCLUDE_VOLK_COMPLEX_H
+
+/*!
+ * \brief Provide typedefs and operators for all complex types in C and C++.
+ *
+ * The typedefs encompass all signed integer and floating point types.
+ * Each operator function is intended to work across all data types.
+ * Under C++, these operators are defined as inline templates.
+ * Under C, these operators are defined as preprocessor macros.
+ * The use of macros makes the operators agnostic to the type.
+ *
+ * The following operator functions are defined:
+ * - lv_cmake - make a complex type from components
+ * - lv_creal - get the real part of the complex number
+ * - lv_cimag - get the imaginary part of the complex number
+ * - lv_conj - take the conjugate of the complex number
+ */
+
+#ifdef __cplusplus
+
+#include
+#include
+
+typedef std::complex lv_8sc_t;
+typedef std::complex lv_16sc_t;
+typedef std::complex lv_32sc_t;
+typedef std::complex lv_64sc_t;
+typedef std::complex lv_32fc_t;
+typedef std::complex lv_64fc_t;
+
+template inline std::complex lv_cmake(const T &r, const T &i){
+ return std::complex(r, i);
+}
+
+template inline typename T::value_type lv_creal(const T &x){
+ return x.real();
+}
+
+template inline typename T::value_type lv_cimag(const T &x){
+ return x.imag();
+}
+
+template inline T lv_conj(const T &x){
+ return std::conj(x);
+}
+
+#else /* __cplusplus */
+
+#include
+
+typedef char complex lv_8sc_t;
+typedef short complex lv_16sc_t;
+typedef long complex lv_32sc_t;
+typedef long long complex lv_64sc_t;
+typedef float complex lv_32fc_t;
+typedef double complex lv_64fc_t;
+
+#define lv_cmake(r, i) ((r) + _Complex_I*(i))
+
+// When GNUC is available, use the complex extensions.
+// The extensions always return the correct value type.
+// http://gcc.gnu.org/onlinedocs/gcc/Complex.html
+#ifdef __GNUC__
+
+#define lv_creal(x) (__real__(x))
+
+#define lv_cimag(x) (__imag__(x))
+
+#define lv_conj(x) (~(x))
+
+// When not available, use the c99 complex function family,
+// which always returns double regardless of the input type.
+#else /* __GNUC__ */
+
+#define lv_creal(x) (creal(x))
+
+#define lv_cimag(x) (cimag(x))
+
+#define lv_conj(x) (conj(x))
+
+#endif /* __GNUC__ */
+
+#endif /* __cplusplus */
+
+#endif /* INCLUDE_VOLK_COMPLEX_H */
diff --git a/src/algorithms/libs/volk_gnsssdr/include/volk_gnsssdr/volk_gnsssdr_malloc.h b/src/algorithms/libs/volk_gnsssdr/include/volk_gnsssdr/volk_gnsssdr_malloc.h
new file mode 100644
index 000000000..7136bc135
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/include/volk_gnsssdr/volk_gnsssdr_malloc.h
@@ -0,0 +1,66 @@
+/* -*- c -*- */
+/*
+ * Copyright 2014 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_VOLK_MALLOC_H
+#define INCLUDED_VOLK_MALLOC_H
+
+#include
+#include
+
+__VOLK_DECL_BEGIN
+
+/*!
+ * \brief Allocate \p size bytes of data aligned to \p alignment.
+ *
+ * \details
+ * Because we don't have a standard method to allocate buffers in
+ * memory that are guaranteed to be on an alignment, VOLK handles this
+ * itself. The volk_gnsssdr_malloc function behaves like malloc in that it
+ * returns a pointer to the allocated memory. However, it also takes
+ * in an alignment specfication, which is usually something like 16 or
+ * 32 to ensure that the aligned memory is located on a particular
+ * byte boundary for use with SIMD.
+ *
+ * Internally, the volk_gnsssdr_malloc first checks if the compiler is C11
+ * compliant and uses the new aligned_alloc method. If not, it checks
+ * if the system is POSIX compliant and uses posix_memalign. If that
+ * fails, volk_gnsssdr_malloc handles the memory allocation and alignment
+ * internally.
+ *
+ * Because of the ways in which volk_gnsssdr_malloc may allocate memory, it is
+ * important to always free volk_gnsssdr_malloc pointers using volk_gnsssdr_free.
+ *
+ * \param size The number of bytes to allocate.
+ * \param alignment The byte alignment of the allocated memory.
+ * \return pointer to aligned memory.
+ */
+VOLK_API void *volk_gnsssdr_malloc(size_t size, size_t alignment);
+
+/*!
+ * \brief Free's memory allocated by volk_gnsssdr_malloc.
+ * \param aptr The aligned pointer allocaed by volk_gnsssdr_malloc.
+ */
+VOLK_API void volk_gnsssdr_free(void *aptr);
+
+__VOLK_DECL_END
+
+#endif /* INCLUDED_VOLK_MALLOC_H */
diff --git a/src/algorithms/libs/volk_gnsssdr/include/volk_gnsssdr/volk_gnsssdr_prefs.h b/src/algorithms/libs/volk_gnsssdr/include/volk_gnsssdr/volk_gnsssdr_prefs.h
new file mode 100644
index 000000000..6e13fc07a
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/include/volk_gnsssdr/volk_gnsssdr_prefs.h
@@ -0,0 +1,28 @@
+#ifndef INCLUDED_VOLK_PREFS_H
+#define INCLUDED_VOLK_PREFS_H
+
+#include
+#include
+
+__VOLK_DECL_BEGIN
+
+typedef struct volk_gnsssdr_arch_pref
+{
+ char name[128]; //name of the kernel
+ char impl_a[128]; //best aligned impl
+ char impl_u[128]; //best unaligned impl
+} volk_gnsssdr_arch_pref_t;
+
+////////////////////////////////////////////////////////////////////////
+// get path to volk_gnsssdr_config profiling info
+////////////////////////////////////////////////////////////////////////
+VOLK_API void volk_gnsssdr_get_config_path(char *);
+
+////////////////////////////////////////////////////////////////////////
+// load prefs into global prefs struct
+////////////////////////////////////////////////////////////////////////
+VOLK_API size_t volk_gnsssdr_load_preferences(volk_gnsssdr_arch_pref_t **);
+
+__VOLK_DECL_END
+
+#endif //INCLUDED_VOLK_PREFS_H
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/README.txt b/src/algorithms/libs/volk_gnsssdr/kernels/README.txt
new file mode 100644
index 000000000..69ee93d06
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/README.txt
@@ -0,0 +1,67 @@
+########################################################################
+# How to create custom kernel dispatchers
+########################################################################
+A kernel dispatcher is kernel implementation that calls other kernel implementations.
+By default, a dispatcher is generated by the build system for every kernel such that:
+ * the best aligned implemention is called when all pointer arguments are aligned,
+ * and otherwise the best unaligned implementation is called.
+
+The author of a VOLK kernel may create a custom dispatcher,
+to be called in place of the automatically generated one.
+A custom dispatcher may be useful to handle head and tail cases,
+or to implement different alignment and bounds checking logic.
+
+########################################################################
+# Code for an example dispatcher w/ tail case
+########################################################################
+#include
+
+#ifdef LV_HAVE_DISPATCHER
+
+static inline void volk_gnsssdr_32f_x2_add_32f_dispatcher(float* cVector, const float* aVector, const float* bVector, unsigned int num_points)
+{
+ const unsigned int num_points_r = num_points%4;
+ const unsigned int num_points_x = num_points - num_points_r;
+
+ if (volk_gnsssdr_is_aligned(VOLK_OR_PTR(cVector, VOLK_OR_PTR(aVector, bVector))))
+ {
+ volk_gnsssdr_32f_x2_add_32f_a(cVector, aVector, bVector, num_points_x);
+ }
+ else
+ {
+ volk_gnsssdr_32f_x2_add_32f_u(cVector, aVector, bVector, num_points_x);
+ }
+
+ volk_gnsssdr_32f_x2_add_32f_g(cVector+num_points_x, aVector+num_points_x, bVector+num_points_x, num_points_r);
+}
+
+#endif //LV_HAVE_DISPATCHER
+
+########################################################################
+# Code for an example dispatcher w/ tail case and accumulator
+########################################################################
+#include
+
+#ifdef LV_HAVE_DISPATCHER
+
+static inline void volk_gnsssdr_32f_x2_dot_prod_32f_dispatcher(float * result, const float * input, const float * taps, unsigned int num_points)
+{
+ const unsigned int num_points_r = num_points%16;
+ const unsigned int num_points_x = num_points - num_points_r;
+
+ if (volk_gnsssdr_is_aligned(VOLK_OR_PTR(input, taps)))
+ {
+ volk_gnsssdr_32f_x2_dot_prod_32f_a(result, input, taps, num_points_x);
+ }
+ else
+ {
+ volk_gnsssdr_32f_x2_dot_prod_32f_u(result, input, taps, num_points_x);
+ }
+
+ float result_tail = 0;
+ volk_gnsssdr_32f_x2_dot_prod_32f_g(&result_tail, input+num_points_x, taps+num_points_x, num_points_r);
+
+ *result += result_tail;
+}
+
+#endif //LV_HAVE_DISPATCHER
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16i_s32f_convert_32f.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16i_s32f_convert_32f.h
new file mode 100644
index 000000000..ccb13171c
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_16i_s32f_convert_32f.h
@@ -0,0 +1,241 @@
+#ifndef INCLUDED_volk_gnsssdr_16i_s32f_convert_32f_u_H
+#define INCLUDED_volk_gnsssdr_16i_s32f_convert_32f_u_H
+
+#include
+#include
+
+#ifdef LV_HAVE_SSE4_1
+#include
+
+ /*!
+ \brief Converts the input 16 bit integer data into floating point data, and divides the each floating point output data point by the scalar value
+ \param inputVector The 16 bit input data buffer
+ \param outputVector The floating point output data buffer
+ \param scalar The value divided against each point in the output buffer
+ \param num_points The number of data values to be converted
+ \note Output buffer does NOT need to be properly aligned
+ */
+static inline void volk_gnsssdr_16i_s32f_convert_32f_u_sse4_1(float* outputVector, const int16_t* inputVector, const float scalar, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int eighthPoints = num_points / 8;
+
+ float* outputVectorPtr = outputVector;
+ __m128 invScalar = _mm_set_ps1(1.0/scalar);
+ int16_t* inputPtr = (int16_t*)inputVector;
+ __m128i inputVal;
+ __m128i inputVal2;
+ __m128 ret;
+
+ for(;number < eighthPoints; number++){
+
+ // Load the 8 values
+ inputVal = _mm_loadu_si128((__m128i*)inputPtr);
+
+ // Shift the input data to the right by 64 bits ( 8 bytes )
+ inputVal2 = _mm_srli_si128(inputVal, 8);
+
+ // Convert the lower 4 values into 32 bit words
+ inputVal = _mm_cvtepi16_epi32(inputVal);
+ inputVal2 = _mm_cvtepi16_epi32(inputVal2);
+
+ ret = _mm_cvtepi32_ps(inputVal);
+ ret = _mm_mul_ps(ret, invScalar);
+ _mm_storeu_ps(outputVectorPtr, ret);
+ outputVectorPtr += 4;
+
+ ret = _mm_cvtepi32_ps(inputVal2);
+ ret = _mm_mul_ps(ret, invScalar);
+ _mm_storeu_ps(outputVectorPtr, ret);
+
+ outputVectorPtr += 4;
+
+ inputPtr += 8;
+ }
+
+ number = eighthPoints * 8;
+ for(; number < num_points; number++){
+ outputVector[number] =((float)(inputVector[number])) / scalar;
+ }
+}
+#endif /* LV_HAVE_SSE4_1 */
+
+#ifdef LV_HAVE_SSE
+#include
+
+ /*!
+ \brief Converts the input 16 bit integer data into floating point data, and divides the each floating point output data point by the scalar value
+ \param inputVector The 16 bit input data buffer
+ \param outputVector The floating point output data buffer
+ \param scalar The value divided against each point in the output buffer
+ \param num_points The number of data values to be converted
+ \note Output buffer does NOT need to be properly aligned
+ */
+static inline void volk_gnsssdr_16i_s32f_convert_32f_u_sse(float* outputVector, const int16_t* inputVector, const float scalar, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ float* outputVectorPtr = outputVector;
+ __m128 invScalar = _mm_set_ps1(1.0/scalar);
+ int16_t* inputPtr = (int16_t*)inputVector;
+ __m128 ret;
+
+ for(;number < quarterPoints; number++){
+ ret = _mm_set_ps((float)(inputPtr[3]), (float)(inputPtr[2]), (float)(inputPtr[1]), (float)(inputPtr[0]));
+
+ ret = _mm_mul_ps(ret, invScalar);
+ _mm_storeu_ps(outputVectorPtr, ret);
+
+ inputPtr += 4;
+ outputVectorPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(; number < num_points; number++){
+ outputVector[number] = (float)(inputVector[number]) / scalar;
+ }
+}
+#endif /* LV_HAVE_SSE */
+
+#ifdef LV_HAVE_GENERIC
+ /*!
+ \brief Converts the input 16 bit integer data into floating point data, and divides the each floating point output data point by the scalar value
+ \param inputVector The 16 bit input data buffer
+ \param outputVector The floating point output data buffer
+ \param scalar The value divided against each point in the output buffer
+ \param num_points The number of data values to be converted
+ \note Output buffer does NOT need to be properly aligned
+ */
+static inline void volk_gnsssdr_16i_s32f_convert_32f_generic(float* outputVector, const int16_t* inputVector, const float scalar, unsigned int num_points){
+ float* outputVectorPtr = outputVector;
+ const int16_t* inputVectorPtr = inputVector;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ *outputVectorPtr++ = ((float)(*inputVectorPtr++)) / scalar;
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+
+
+
+#endif /* INCLUDED_volk_gnsssdr_16i_s32f_convert_32f_u_H */
+#ifndef INCLUDED_volk_gnsssdr_16i_s32f_convert_32f_a_H
+#define INCLUDED_volk_gnsssdr_16i_s32f_convert_32f_a_H
+
+#include
+#include
+
+#ifdef LV_HAVE_SSE4_1
+#include
+
+ /*!
+ \brief Converts the input 16 bit integer data into floating point data, and divides the each floating point output data point by the scalar value
+ \param inputVector The 16 bit input data buffer
+ \param outputVector The floating point output data buffer
+ \param scalar The value divided against each point in the output buffer
+ \param num_points The number of data values to be converted
+ */
+static inline void volk_gnsssdr_16i_s32f_convert_32f_a_sse4_1(float* outputVector, const int16_t* inputVector, const float scalar, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int eighthPoints = num_points / 8;
+
+ float* outputVectorPtr = outputVector;
+ __m128 invScalar = _mm_set_ps1(1.0/scalar);
+ int16_t* inputPtr = (int16_t*)inputVector;
+ __m128i inputVal;
+ __m128i inputVal2;
+ __m128 ret;
+
+ for(;number < eighthPoints; number++){
+
+ // Load the 8 values
+ inputVal = _mm_loadu_si128((__m128i*)inputPtr);
+
+ // Shift the input data to the right by 64 bits ( 8 bytes )
+ inputVal2 = _mm_srli_si128(inputVal, 8);
+
+ // Convert the lower 4 values into 32 bit words
+ inputVal = _mm_cvtepi16_epi32(inputVal);
+ inputVal2 = _mm_cvtepi16_epi32(inputVal2);
+
+ ret = _mm_cvtepi32_ps(inputVal);
+ ret = _mm_mul_ps(ret, invScalar);
+ _mm_storeu_ps(outputVectorPtr, ret);
+ outputVectorPtr += 4;
+
+ ret = _mm_cvtepi32_ps(inputVal2);
+ ret = _mm_mul_ps(ret, invScalar);
+ _mm_storeu_ps(outputVectorPtr, ret);
+
+ outputVectorPtr += 4;
+
+ inputPtr += 8;
+ }
+
+ number = eighthPoints * 8;
+ for(; number < num_points; number++){
+ outputVector[number] =((float)(inputVector[number])) / scalar;
+ }
+}
+#endif /* LV_HAVE_SSE4_1 */
+
+#ifdef LV_HAVE_SSE
+#include
+
+ /*!
+ \brief Converts the input 16 bit integer data into floating point data, and divides the each floating point output data point by the scalar value
+ \param inputVector The 16 bit input data buffer
+ \param outputVector The floating point output data buffer
+ \param scalar The value divided against each point in the output buffer
+ \param num_points The number of data values to be converted
+ */
+static inline void volk_gnsssdr_16i_s32f_convert_32f_a_sse(float* outputVector, const int16_t* inputVector, const float scalar, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ float* outputVectorPtr = outputVector;
+ __m128 invScalar = _mm_set_ps1(1.0/scalar);
+ int16_t* inputPtr = (int16_t*)inputVector;
+ __m128 ret;
+
+ for(;number < quarterPoints; number++){
+ ret = _mm_set_ps((float)(inputPtr[3]), (float)(inputPtr[2]), (float)(inputPtr[1]), (float)(inputPtr[0]));
+
+ ret = _mm_mul_ps(ret, invScalar);
+ _mm_storeu_ps(outputVectorPtr, ret);
+
+ inputPtr += 4;
+ outputVectorPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(; number < num_points; number++){
+ outputVector[number] = (float)(inputVector[number]) / scalar;
+ }
+}
+#endif /* LV_HAVE_SSE */
+
+#ifdef LV_HAVE_GENERIC
+ /*!
+ \brief Converts the input 16 bit integer data into floating point data, and divides the each floating point output data point by the scalar value
+ \param inputVector The 16 bit input data buffer
+ \param outputVector The floating point output data buffer
+ \param scalar The value divided against each point in the output buffer
+ \param num_points The number of data values to be converted
+ */
+static inline void volk_gnsssdr_16i_s32f_convert_32f_a_generic(float* outputVector, const int16_t* inputVector, const float scalar, unsigned int num_points){
+ float* outputVectorPtr = outputVector;
+ const int16_t* inputVectorPtr = inputVector;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ *outputVectorPtr++ = ((float)(*inputVectorPtr++)) / scalar;
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+
+
+
+#endif /* INCLUDED_volk_gnsssdr_16i_s32f_convert_32f_a_H */
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_accumulator_s32f.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_accumulator_s32f.h
new file mode 100644
index 000000000..82f1b3efd
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_accumulator_s32f.h
@@ -0,0 +1,68 @@
+#ifndef INCLUDED_volk_gnsssdr_32f_accumulator_s32f_a_H
+#define INCLUDED_volk_gnsssdr_32f_accumulator_s32f_a_H
+
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE
+#include
+/*!
+ \brief Accumulates the values in the input buffer
+ \param result The accumulated result
+ \param inputBuffer The buffer of data to be accumulated
+ \param num_points The number of values in inputBuffer to be accumulated
+*/
+static inline void volk_gnsssdr_32f_accumulator_s32f_a_sse(float* result, const float* inputBuffer, unsigned int num_points){
+ float returnValue = 0;
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ const float* aPtr = inputBuffer;
+ __VOLK_ATTR_ALIGNED(16) float tempBuffer[4];
+
+ __m128 accumulator = _mm_setzero_ps();
+ __m128 aVal = _mm_setzero_ps();
+
+ for(;number < quarterPoints; number++){
+ aVal = _mm_load_ps(aPtr);
+ accumulator = _mm_add_ps(accumulator, aVal);
+ aPtr += 4;
+ }
+ _mm_store_ps(tempBuffer,accumulator); // Store the results back into the C container
+ returnValue = tempBuffer[0];
+ returnValue += tempBuffer[1];
+ returnValue += tempBuffer[2];
+ returnValue += tempBuffer[3];
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ returnValue += (*aPtr++);
+ }
+ *result = returnValue;
+}
+#endif /* LV_HAVE_SSE */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Accumulates the values in the input buffer
+ \param result The accumulated result
+ \param inputBuffer The buffer of data to be accumulated
+ \param num_points The number of values in inputBuffer to be accumulated
+*/
+static inline void volk_gnsssdr_32f_accumulator_s32f_generic(float* result, const float* inputBuffer, unsigned int num_points){
+ const float* aPtr = inputBuffer;
+ unsigned int number = 0;
+ float returnValue = 0;
+
+ for(;number < num_points; number++){
+ returnValue += (*aPtr++);
+ }
+ *result = returnValue;
+}
+#endif /* LV_HAVE_GENERIC */
+
+
+
+
+#endif /* INCLUDED_volk_gnsssdr_32f_accumulator_s32f_a_H */
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_index_max_16u.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_index_max_16u.h
new file mode 100644
index 000000000..c815609b2
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_index_max_16u.h
@@ -0,0 +1,149 @@
+#ifndef INCLUDED_volk_gnsssdr_32f_index_max_16u_a_H
+#define INCLUDED_volk_gnsssdr_32f_index_max_16u_a_H
+
+#include
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE4_1
+#include
+
+static inline void volk_gnsssdr_32f_index_max_16u_a_sse4_1(unsigned int* target, const float* src0, unsigned int num_points) {
+ if(num_points > 0){
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ float* inputPtr = (float*)src0;
+
+ __m128 indexIncrementValues = _mm_set1_ps(4);
+ __m128 currentIndexes = _mm_set_ps(-1,-2,-3,-4);
+
+ float max = src0[0];
+ float index = 0;
+ __m128 maxValues = _mm_set1_ps(max);
+ __m128 maxValuesIndex = _mm_setzero_ps();
+ __m128 compareResults;
+ __m128 currentValues;
+
+ __VOLK_ATTR_ALIGNED(16) float maxValuesBuffer[4];
+ __VOLK_ATTR_ALIGNED(16) float maxIndexesBuffer[4];
+
+ for(;number < quarterPoints; number++){
+
+ currentValues = _mm_load_ps(inputPtr); inputPtr += 4;
+ currentIndexes = _mm_add_ps(currentIndexes, indexIncrementValues);
+
+ compareResults = _mm_cmpgt_ps(maxValues, currentValues);
+
+ maxValuesIndex = _mm_blendv_ps(currentIndexes, maxValuesIndex, compareResults);
+ maxValues = _mm_blendv_ps(currentValues, maxValues, compareResults);
+ }
+
+ // Calculate the largest value from the remaining 4 points
+ _mm_store_ps(maxValuesBuffer, maxValues);
+ _mm_store_ps(maxIndexesBuffer, maxValuesIndex);
+
+ for(number = 0; number < 4; number++){
+ if(maxValuesBuffer[number] > max){
+ index = maxIndexesBuffer[number];
+ max = maxValuesBuffer[number];
+ }
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ if(src0[number] > max){
+ index = number;
+ max = src0[number];
+ }
+ }
+ target[0] = (unsigned int)index;
+ }
+}
+
+#endif /*LV_HAVE_SSE4_1*/
+
+#ifdef LV_HAVE_SSE
+#include
+
+static inline void volk_gnsssdr_32f_index_max_16u_a_sse(unsigned int* target, const float* src0, unsigned int num_points) {
+ if(num_points > 0){
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ float* inputPtr = (float*)src0;
+
+ __m128 indexIncrementValues = _mm_set1_ps(4);
+ __m128 currentIndexes = _mm_set_ps(-1,-2,-3,-4);
+
+ float max = src0[0];
+ float index = 0;
+ __m128 maxValues = _mm_set1_ps(max);
+ __m128 maxValuesIndex = _mm_setzero_ps();
+ __m128 compareResults;
+ __m128 currentValues;
+
+ __VOLK_ATTR_ALIGNED(16) float maxValuesBuffer[4];
+ __VOLK_ATTR_ALIGNED(16) float maxIndexesBuffer[4];
+
+ for(;number < quarterPoints; number++){
+
+ currentValues = _mm_load_ps(inputPtr); inputPtr += 4;
+ currentIndexes = _mm_add_ps(currentIndexes, indexIncrementValues);
+
+ compareResults = _mm_cmpgt_ps(maxValues, currentValues);
+
+ maxValuesIndex = _mm_or_ps(_mm_and_ps(compareResults, maxValuesIndex) , _mm_andnot_ps(compareResults, currentIndexes));
+
+ maxValues = _mm_or_ps(_mm_and_ps(compareResults, maxValues) , _mm_andnot_ps(compareResults, currentValues));
+ }
+
+ // Calculate the largest value from the remaining 4 points
+ _mm_store_ps(maxValuesBuffer, maxValues);
+ _mm_store_ps(maxIndexesBuffer, maxValuesIndex);
+
+ for(number = 0; number < 4; number++){
+ if(maxValuesBuffer[number] > max){
+ index = maxIndexesBuffer[number];
+ max = maxValuesBuffer[number];
+ }
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ if(src0[number] > max){
+ index = number;
+ max = src0[number];
+ }
+ }
+ target[0] = (unsigned int)index;
+ }
+}
+
+#endif /*LV_HAVE_SSE*/
+
+#ifdef LV_HAVE_GENERIC
+static inline void volk_gnsssdr_32f_index_max_16u_generic(unsigned int* target, const float* src0, unsigned int num_points) {
+ if(num_points > 0){
+ float max = src0[0];
+ unsigned int index = 0;
+
+ unsigned int i = 1;
+
+ for(; i < num_points; ++i) {
+
+ if(src0[i] > max){
+ index = i;
+ max = src0[i];
+ }
+
+ }
+ target[0] = index;
+ }
+}
+
+#endif /*LV_HAVE_GENERIC*/
+
+
+#endif /*INCLUDED_volk_gnsssdr_32f_index_max_16u_a_H*/
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_x2_add_32f.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_x2_add_32f.h
new file mode 100644
index 000000000..ee647b2d7
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32f_x2_add_32f.h
@@ -0,0 +1,147 @@
+#ifndef INCLUDED_volk_gnsssdr_32f_x2_add_32f_u_H
+#define INCLUDED_volk_gnsssdr_32f_x2_add_32f_u_H
+
+#include
+#include
+
+#ifdef LV_HAVE_SSE
+#include
+/*!
+ \brief Adds the two input vectors and store their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be added
+ \param bVector One of the vectors to be added
+ \param num_points The number of values in aVector and bVector to be added together and stored into cVector
+*/
+static inline void volk_gnsssdr_32f_x2_add_32f_u_sse(float* cVector, const float* aVector, const float* bVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ float* cPtr = cVector;
+ const float* aPtr = aVector;
+ const float* bPtr= bVector;
+
+ __m128 aVal, bVal, cVal;
+ for(;number < quarterPoints; number++){
+
+ aVal = _mm_loadu_ps(aPtr);
+ bVal = _mm_loadu_ps(bPtr);
+
+ cVal = _mm_add_ps(aVal, bVal);
+
+ _mm_storeu_ps(cPtr,cVal); // Store the results back into the C container
+
+ aPtr += 4;
+ bPtr += 4;
+ cPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *cPtr++ = (*aPtr++) + (*bPtr++);
+ }
+}
+#endif /* LV_HAVE_SSE */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Adds the two input vectors and store their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be added
+ \param bVector One of the vectors to be added
+ \param num_points The number of values in aVector and bVector to be added together and stored into cVector
+*/
+static inline void volk_gnsssdr_32f_x2_add_32f_generic(float* cVector, const float* aVector, const float* bVector, unsigned int num_points){
+ float* cPtr = cVector;
+ const float* aPtr = aVector;
+ const float* bPtr= bVector;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ *cPtr++ = (*aPtr++) + (*bPtr++);
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_volk_gnsssdr_32f_x2_add_32f_u_H */
+#ifndef INCLUDED_volk_gnsssdr_32f_x2_add_32f_a_H
+#define INCLUDED_volk_gnsssdr_32f_x2_add_32f_a_H
+
+#include
+#include
+
+#ifdef LV_HAVE_SSE
+#include
+/*!
+ \brief Adds the two input vectors and store their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be added
+ \param bVector One of the vectors to be added
+ \param num_points The number of values in aVector and bVector to be added together and stored into cVector
+*/
+static inline void volk_gnsssdr_32f_x2_add_32f_a_sse(float* cVector, const float* aVector, const float* bVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ float* cPtr = cVector;
+ const float* aPtr = aVector;
+ const float* bPtr= bVector;
+
+ __m128 aVal, bVal, cVal;
+ for(;number < quarterPoints; number++){
+
+ aVal = _mm_load_ps(aPtr);
+ bVal = _mm_load_ps(bPtr);
+
+ cVal = _mm_add_ps(aVal, bVal);
+
+ _mm_store_ps(cPtr,cVal); // Store the results back into the C container
+
+ aPtr += 4;
+ bPtr += 4;
+ cPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(;number < num_points; number++){
+ *cPtr++ = (*aPtr++) + (*bPtr++);
+ }
+}
+#endif /* LV_HAVE_SSE */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Adds the two input vectors and store their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be added
+ \param bVector One of the vectors to be added
+ \param num_points The number of values in aVector and bVector to be added together and stored into cVector
+*/
+static inline void volk_gnsssdr_32f_x2_add_32f_a_generic(float* cVector, const float* aVector, const float* bVector, unsigned int num_points){
+ float* cPtr = cVector;
+ const float* aPtr = aVector;
+ const float* bPtr= bVector;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ *cPtr++ = (*aPtr++) + (*bPtr++);
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+#ifdef LV_HAVE_ORC
+/*!
+ \brief Adds the two input vectors and store their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be added
+ \param bVector One of the vectors to be added
+ \param num_points The number of values in aVector and bVector to be added together and stored into cVector
+*/
+extern void volk_gnsssdr_32f_x2_add_32f_a_orc_impl(float* cVector, const float* aVector, const float* bVector, unsigned int num_points);
+static inline void volk_gnsssdr_32f_x2_add_32f_u_orc(float* cVector, const float* aVector, const float* bVector, unsigned int num_points){
+ volk_gnsssdr_32f_x2_add_32f_a_orc_impl(cVector, aVector, bVector, num_points);
+}
+#endif /* LV_HAVE_ORC */
+
+
+#endif /* INCLUDED_volk_gnsssdr_32f_x2_add_32f_a_H */
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_conjugate_32fc.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_conjugate_32fc.h
new file mode 100644
index 000000000..a3b8848aa
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_conjugate_32fc.h
@@ -0,0 +1,127 @@
+#ifndef INCLUDED_volk_gnsssdr_32fc_conjugate_32fc_u_H
+#define INCLUDED_volk_gnsssdr_32fc_conjugate_32fc_u_H
+
+#include
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE3
+#include
+ /*!
+ \brief Takes the conjugate of a complex vector.
+ \param cVector The vector where the results will be stored
+ \param aVector Vector to be conjugated
+ \param num_points The number of complex values in aVector to be conjugated and stored into cVector
+ */
+static inline void volk_gnsssdr_32fc_conjugate_32fc_u_sse3(lv_32fc_t* cVector, const lv_32fc_t* aVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int halfPoints = num_points / 2;
+
+ __m128 x;
+ lv_32fc_t* c = cVector;
+ const lv_32fc_t* a = aVector;
+
+ __m128 conjugator = _mm_setr_ps(0, -0.f, 0, -0.f);
+
+ for(;number < halfPoints; number++){
+
+ x = _mm_loadu_ps((float*)a); // Load the complex data as ar,ai,br,bi
+
+ x = _mm_xor_ps(x, conjugator); // conjugate register
+
+ _mm_storeu_ps((float*)c,x); // Store the results back into the C container
+
+ a += 2;
+ c += 2;
+ }
+
+ if((num_points % 2) != 0) {
+ *c = lv_conj(*a);
+ }
+}
+#endif /* LV_HAVE_SSE3 */
+
+#ifdef LV_HAVE_GENERIC
+ /*!
+ \brief Takes the conjugate of a complex vector.
+ \param cVector The vector where the results will be stored
+ \param aVector Vector to be conjugated
+ \param num_points The number of complex values in aVector to be conjugated and stored into cVector
+ */
+static inline void volk_gnsssdr_32fc_conjugate_32fc_generic(lv_32fc_t* cVector, const lv_32fc_t* aVector, unsigned int num_points){
+ lv_32fc_t* cPtr = cVector;
+ const lv_32fc_t* aPtr = aVector;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ *cPtr++ = lv_conj(*aPtr++);
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+
+#endif /* INCLUDED_volk_gnsssdr_32fc_conjugate_32fc_u_H */
+#ifndef INCLUDED_volk_gnsssdr_32fc_conjugate_32fc_a_H
+#define INCLUDED_volk_gnsssdr_32fc_conjugate_32fc_a_H
+
+#include
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE3
+#include
+ /*!
+ \brief Takes the conjugate of a complex vector.
+ \param cVector The vector where the results will be stored
+ \param aVector Vector to be conjugated
+ \param num_points The number of complex values in aVector to be conjugated and stored into cVector
+ */
+static inline void volk_gnsssdr_32fc_conjugate_32fc_a_sse3(lv_32fc_t* cVector, const lv_32fc_t* aVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int halfPoints = num_points / 2;
+
+ __m128 x;
+ lv_32fc_t* c = cVector;
+ const lv_32fc_t* a = aVector;
+
+ __m128 conjugator = _mm_setr_ps(0, -0.f, 0, -0.f);
+
+ for(;number < halfPoints; number++){
+
+ x = _mm_load_ps((float*)a); // Load the complex data as ar,ai,br,bi
+
+ x = _mm_xor_ps(x, conjugator); // conjugate register
+
+ _mm_store_ps((float*)c,x); // Store the results back into the C container
+
+ a += 2;
+ c += 2;
+ }
+
+ if((num_points % 2) != 0) {
+ *c = lv_conj(*a);
+ }
+}
+#endif /* LV_HAVE_SSE3 */
+
+#ifdef LV_HAVE_GENERIC
+ /*!
+ \brief Takes the conjugate of a complex vector.
+ \param cVector The vector where the results will be stored
+ \param aVector Vector to be conjugated
+ \param num_points The number of complex values in aVector to be conjugated and stored into cVector
+ */
+static inline void volk_gnsssdr_32fc_conjugate_32fc_a_generic(lv_32fc_t* cVector, const lv_32fc_t* aVector, unsigned int num_points){
+ lv_32fc_t* cPtr = cVector;
+ const lv_32fc_t* aPtr = aVector;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ *cPtr++ = lv_conj(*aPtr++);
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_volk_gnsssdr_32fc_conjugate_32fc_a_H */
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_magnitude_squared_32f.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_magnitude_squared_32f.h
new file mode 100644
index 000000000..ce28f866e
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_magnitude_squared_32f.h
@@ -0,0 +1,228 @@
+#ifndef INCLUDED_volk_gnsssdr_32fc_magnitude_squared_32f_u_H
+#define INCLUDED_volk_gnsssdr_32fc_magnitude_squared_32f_u_H
+
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE3
+#include
+ /*!
+ \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
+ \param complexVector The vector containing the complex input values
+ \param magnitudeVector The vector containing the real output values
+ \param num_points The number of complex values in complexVector to be calculated and stored into cVector
+ */
+static inline void volk_gnsssdr_32fc_magnitude_squared_32f_u_sse3(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ const float* complexVectorPtr = (float*)complexVector;
+ float* magnitudeVectorPtr = magnitudeVector;
+
+ __m128 cplxValue1, cplxValue2, result;
+ for(;number < quarterPoints; number++){
+ cplxValue1 = _mm_loadu_ps(complexVectorPtr);
+ complexVectorPtr += 4;
+
+ cplxValue2 = _mm_loadu_ps(complexVectorPtr);
+ complexVectorPtr += 4;
+
+ cplxValue1 = _mm_mul_ps(cplxValue1, cplxValue1); // Square the values
+ cplxValue2 = _mm_mul_ps(cplxValue2, cplxValue2); // Square the Values
+
+ result = _mm_hadd_ps(cplxValue1, cplxValue2); // Add the I2 and Q2 values
+
+ _mm_storeu_ps(magnitudeVectorPtr, result);
+ magnitudeVectorPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(; number < num_points; number++){
+ float val1Real = *complexVectorPtr++;
+ float val1Imag = *complexVectorPtr++;
+ *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
+ }
+}
+#endif /* LV_HAVE_SSE3 */
+
+#ifdef LV_HAVE_SSE
+#include
+ /*!
+ \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
+ \param complexVector The vector containing the complex input values
+ \param magnitudeVector The vector containing the real output values
+ \param num_points The number of complex values in complexVector to be calculated and stored into cVector
+ */
+static inline void volk_gnsssdr_32fc_magnitude_squared_32f_u_sse(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ const float* complexVectorPtr = (float*)complexVector;
+ float* magnitudeVectorPtr = magnitudeVector;
+
+ __m128 cplxValue1, cplxValue2, iValue, qValue, result;
+ for(;number < quarterPoints; number++){
+ cplxValue1 = _mm_loadu_ps(complexVectorPtr);
+ complexVectorPtr += 4;
+
+ cplxValue2 = _mm_loadu_ps(complexVectorPtr);
+ complexVectorPtr += 4;
+
+ // Arrange in i1i2i3i4 format
+ iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2,0,2,0));
+ // Arrange in q1q2q3q4 format
+ qValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3,1,3,1));
+
+ iValue = _mm_mul_ps(iValue, iValue); // Square the I values
+ qValue = _mm_mul_ps(qValue, qValue); // Square the Q Values
+
+ result = _mm_add_ps(iValue, qValue); // Add the I2 and Q2 values
+
+ _mm_storeu_ps(magnitudeVectorPtr, result);
+ magnitudeVectorPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(; number < num_points; number++){
+ float val1Real = *complexVectorPtr++;
+ float val1Imag = *complexVectorPtr++;
+ *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
+ }
+}
+#endif /* LV_HAVE_SSE */
+
+#ifdef LV_HAVE_GENERIC
+ /*!
+ \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
+ \param complexVector The vector containing the complex input values
+ \param magnitudeVector The vector containing the real output values
+ \param num_points The number of complex values in complexVector to be calculated and stored into cVector
+ */
+static inline void volk_gnsssdr_32fc_magnitude_squared_32f_generic(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
+ const float* complexVectorPtr = (float*)complexVector;
+ float* magnitudeVectorPtr = magnitudeVector;
+ unsigned int number = 0;
+ for(number = 0; number < num_points; number++){
+ const float real = *complexVectorPtr++;
+ const float imag = *complexVectorPtr++;
+ *magnitudeVectorPtr++ = (real*real) + (imag*imag);
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_volk_gnsssdr_32fc_magnitude_32f_u_H */
+#ifndef INCLUDED_volk_gnsssdr_32fc_magnitude_squared_32f_a_H
+#define INCLUDED_volk_gnsssdr_32fc_magnitude_squared_32f_a_H
+
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE3
+#include
+ /*!
+ \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
+ \param complexVector The vector containing the complex input values
+ \param magnitudeVector The vector containing the real output values
+ \param num_points The number of complex values in complexVector to be calculated and stored into cVector
+ */
+static inline void volk_gnsssdr_32fc_magnitude_squared_32f_a_sse3(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ const float* complexVectorPtr = (float*)complexVector;
+ float* magnitudeVectorPtr = magnitudeVector;
+
+ __m128 cplxValue1, cplxValue2, result;
+ for(;number < quarterPoints; number++){
+ cplxValue1 = _mm_load_ps(complexVectorPtr);
+ complexVectorPtr += 4;
+
+ cplxValue2 = _mm_load_ps(complexVectorPtr);
+ complexVectorPtr += 4;
+
+ cplxValue1 = _mm_mul_ps(cplxValue1, cplxValue1); // Square the values
+ cplxValue2 = _mm_mul_ps(cplxValue2, cplxValue2); // Square the Values
+
+ result = _mm_hadd_ps(cplxValue1, cplxValue2); // Add the I2 and Q2 values
+
+ _mm_store_ps(magnitudeVectorPtr, result);
+ magnitudeVectorPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(; number < num_points; number++){
+ float val1Real = *complexVectorPtr++;
+ float val1Imag = *complexVectorPtr++;
+ *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
+ }
+}
+#endif /* LV_HAVE_SSE3 */
+
+#ifdef LV_HAVE_SSE
+#include
+ /*!
+ \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
+ \param complexVector The vector containing the complex input values
+ \param magnitudeVector The vector containing the real output values
+ \param num_points The number of complex values in complexVector to be calculated and stored into cVector
+ */
+static inline void volk_gnsssdr_32fc_magnitude_squared_32f_a_sse(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int quarterPoints = num_points / 4;
+
+ const float* complexVectorPtr = (float*)complexVector;
+ float* magnitudeVectorPtr = magnitudeVector;
+
+ __m128 cplxValue1, cplxValue2, iValue, qValue, result;
+ for(;number < quarterPoints; number++){
+ cplxValue1 = _mm_load_ps(complexVectorPtr);
+ complexVectorPtr += 4;
+
+ cplxValue2 = _mm_load_ps(complexVectorPtr);
+ complexVectorPtr += 4;
+
+ // Arrange in i1i2i3i4 format
+ iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2,0,2,0));
+ // Arrange in q1q2q3q4 format
+ qValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3,1,3,1));
+
+ iValue = _mm_mul_ps(iValue, iValue); // Square the I values
+ qValue = _mm_mul_ps(qValue, qValue); // Square the Q Values
+
+ result = _mm_add_ps(iValue, qValue); // Add the I2 and Q2 values
+
+ _mm_store_ps(magnitudeVectorPtr, result);
+ magnitudeVectorPtr += 4;
+ }
+
+ number = quarterPoints * 4;
+ for(; number < num_points; number++){
+ float val1Real = *complexVectorPtr++;
+ float val1Imag = *complexVectorPtr++;
+ *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
+ }
+}
+#endif /* LV_HAVE_SSE */
+
+#ifdef LV_HAVE_GENERIC
+ /*!
+ \brief Calculates the magnitude squared of the complexVector and stores the results in the magnitudeVector
+ \param complexVector The vector containing the complex input values
+ \param magnitudeVector The vector containing the real output values
+ \param num_points The number of complex values in complexVector to be calculated and stored into cVector
+ */
+static inline void volk_gnsssdr_32fc_magnitude_squared_32f_a_generic(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
+ const float* complexVectorPtr = (float*)complexVector;
+ float* magnitudeVectorPtr = magnitudeVector;
+ unsigned int number = 0;
+ for(number = 0; number < num_points; number++){
+ const float real = *complexVectorPtr++;
+ const float imag = *complexVectorPtr++;
+ *magnitudeVectorPtr++ = (real*real) + (imag*imag);
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_volk_gnsssdr_32fc_magnitude_32f_a_H */
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_s32fc_multiply_32fc.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_s32fc_multiply_32fc.h
new file mode 100644
index 000000000..d5135d89f
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_s32fc_multiply_32fc.h
@@ -0,0 +1,178 @@
+#ifndef INCLUDED_volk_gnsssdr_32fc_s32fc_multiply_32fc_u_H
+#define INCLUDED_volk_gnsssdr_32fc_s32fc_multiply_32fc_u_H
+
+#include
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE3
+#include
+/*!
+ \brief Multiplies the input vector by a scalar and stores the results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector The vector to be multiplied
+ \param scalar The complex scalar to multiply aVector
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+*/
+static inline void volk_gnsssdr_32fc_s32fc_multiply_32fc_u_sse3(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t scalar, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int halfPoints = num_points / 2;
+
+ __m128 x, yl, yh, z, tmp1, tmp2;
+ lv_32fc_t* c = cVector;
+ const lv_32fc_t* a = aVector;
+
+ // Set up constant scalar vector
+ yl = _mm_set_ps1(lv_creal(scalar));
+ yh = _mm_set_ps1(lv_cimag(scalar));
+
+ for(;number < halfPoints; number++){
+
+ x = _mm_loadu_ps((float*)a); // Load the ar + ai, br + bi as ar,ai,br,bi
+
+ tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+
+ x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+
+ _mm_storeu_ps((float*)c,z); // Store the results back into the C container
+
+ a += 2;
+ c += 2;
+ }
+
+ if((num_points % 2) != 0) {
+ *c = (*a) * scalar;
+ }
+}
+#endif /* LV_HAVE_SSE */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Multiplies the input vector by a scalar and stores the results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector The vector to be multiplied
+ \param scalar The complex scalar to multiply aVector
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+*/
+static inline void volk_gnsssdr_32fc_s32fc_multiply_32fc_generic(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t scalar, unsigned int num_points){
+ lv_32fc_t* cPtr = cVector;
+ const lv_32fc_t* aPtr = aVector;
+ unsigned int number = num_points;
+
+ // unwrap loop
+ while (number >= 8){
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ number -= 8;
+ }
+
+ // clean up any remaining
+ while (number-- > 0)
+ *cPtr++ = *aPtr++ * scalar;
+}
+#endif /* LV_HAVE_GENERIC */
+
+
+#endif /* INCLUDED_volk_gnsssdr_32fc_x2_multiply_32fc_u_H */
+#ifndef INCLUDED_volk_gnsssdr_32fc_s32fc_multiply_32fc_a_H
+#define INCLUDED_volk_gnsssdr_32fc_s32fc_multiply_32fc_a_H
+
+#include
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE3
+#include
+ /*!
+ \brief Multiplies the two input complex vectors and stores their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be multiplied
+ \param bVector One of the vectors to be multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+static inline void volk_gnsssdr_32fc_s32fc_multiply_32fc_a_sse3(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t scalar, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int halfPoints = num_points / 2;
+
+ __m128 x, yl, yh, z, tmp1, tmp2;
+ lv_32fc_t* c = cVector;
+ const lv_32fc_t* a = aVector;
+
+ // Set up constant scalar vector
+ yl = _mm_set_ps1(lv_creal(scalar));
+ yh = _mm_set_ps1(lv_cimag(scalar));
+
+ for(;number < halfPoints; number++){
+
+ x = _mm_load_ps((float*)a); // Load the ar + ai, br + bi as ar,ai,br,bi
+
+ tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+
+ x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+
+ _mm_store_ps((float*)c,z); // Store the results back into the C container
+
+ a += 2;
+ c += 2;
+ }
+
+ if((num_points % 2) != 0) {
+ *c = (*a) * scalar;
+ }
+}
+#endif /* LV_HAVE_SSE */
+
+
+#ifdef LV_HAVE_GENERIC
+ /*!
+ \brief Multiplies the two input complex vectors and stores their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be multiplied
+ \param bVector One of the vectors to be multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+static inline void volk_gnsssdr_32fc_s32fc_multiply_32fc_a_generic(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t scalar, unsigned int num_points){
+ lv_32fc_t* cPtr = cVector;
+ const lv_32fc_t* aPtr = aVector;
+ unsigned int number = num_points;
+
+ // unwrap loop
+ while (number >= 8){
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ number -= 8;
+ }
+
+ // clean up any remaining
+ while (number-- > 0)
+ *cPtr++ = *aPtr++ * scalar;
+}
+#endif /* LV_HAVE_GENERIC */
+
+
+
+
+
+#endif /* INCLUDED_volk_gnsssdr_32fc_x2_multiply_32fc_a_H */
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_x2_dot_prod_32fc.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_x2_dot_prod_32fc.h
new file mode 100644
index 000000000..08a10aa6e
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_x2_dot_prod_32fc.h
@@ -0,0 +1,763 @@
+#ifndef INCLUDED_volk_gnsssdr_32fc_x2_dot_prod_32fc_u_H
+#define INCLUDED_volk_gnsssdr_32fc_x2_dot_prod_32fc_u_H
+
+#include
+#include
+#include
+#include
+
+
+#ifdef LV_HAVE_GENERIC
+
+
+static inline void volk_gnsssdr_32fc_x2_dot_prod_32fc_generic(lv_32fc_t* result, const lv_32fc_t* input, const lv_32fc_t* taps, unsigned int num_points) {
+
+ float * res = (float*) result;
+ float * in = (float*) input;
+ float * tp = (float*) taps;
+ unsigned int n_2_ccomplex_blocks = num_points/2;
+ unsigned int isodd = num_points & 1;
+
+ float sum0[2] = {0,0};
+ float sum1[2] = {0,0};
+ unsigned int i = 0;
+
+ for(i = 0; i < n_2_ccomplex_blocks; ++i) {
+ sum0[0] += in[0] * tp[0] - in[1] * tp[1];
+ sum0[1] += in[0] * tp[1] + in[1] * tp[0];
+ sum1[0] += in[2] * tp[2] - in[3] * tp[3];
+ sum1[1] += in[2] * tp[3] + in[3] * tp[2];
+
+ in += 4;
+ tp += 4;
+ }
+
+ res[0] = sum0[0] + sum1[0];
+ res[1] = sum0[1] + sum1[1];
+
+ // Cleanup if we had an odd number of points
+ for(i = 0; i < isodd; ++i) {
+ *result += input[num_points - 1] * taps[num_points - 1];
+ }
+}
+
+#endif /*LV_HAVE_GENERIC*/
+
+
+
+#if LV_HAVE_SSE && LV_HAVE_64
+
+static inline void volk_gnsssdr_32fc_x2_dot_prod_32fc_u_sse_64(lv_32fc_t* result, const lv_32fc_t* input, const lv_32fc_t* taps, unsigned int num_points) {
+
+ const unsigned int num_bytes = num_points*8;
+ unsigned int isodd = num_points & 1;
+
+ asm
+ (
+ "# ccomplex_dotprod_generic (float* result, const float *input,\n\t"
+ "# const float *taps, unsigned num_bytes)\n\t"
+ "# float sum0 = 0;\n\t"
+ "# float sum1 = 0;\n\t"
+ "# float sum2 = 0;\n\t"
+ "# float sum3 = 0;\n\t"
+ "# do {\n\t"
+ "# sum0 += input[0] * taps[0] - input[1] * taps[1];\n\t"
+ "# sum1 += input[0] * taps[1] + input[1] * taps[0];\n\t"
+ "# sum2 += input[2] * taps[2] - input[3] * taps[3];\n\t"
+ "# sum3 += input[2] * taps[3] + input[3] * taps[2];\n\t"
+ "# input += 4;\n\t"
+ "# taps += 4; \n\t"
+ "# } while (--n_2_ccomplex_blocks != 0);\n\t"
+ "# result[0] = sum0 + sum2;\n\t"
+ "# result[1] = sum1 + sum3;\n\t"
+ "# TODO: prefetch and better scheduling\n\t"
+ " xor %%r9, %%r9\n\t"
+ " xor %%r10, %%r10\n\t"
+ " movq %%rcx, %%rax\n\t"
+ " movq %%rcx, %%r8\n\t"
+ " movq %[rsi], %%r9\n\t"
+ " movq %[rdx], %%r10\n\t"
+ " xorps %%xmm6, %%xmm6 # zero accumulators\n\t"
+ " movups 0(%%r9), %%xmm0\n\t"
+ " xorps %%xmm7, %%xmm7 # zero accumulators\n\t"
+ " movups 0(%%r10), %%xmm2\n\t"
+ " shr $5, %%rax # rax = n_2_ccomplex_blocks / 2\n\t"
+ " shr $4, %%r8\n\t"
+ " jmp .%=L1_test\n\t"
+ " # 4 taps / loop\n\t"
+ " # something like ?? cycles / loop\n\t"
+ ".%=Loop1: \n\t"
+ "# complex prod: C += A * B, w/ temp Z & Y (or B), xmmPN=$0x8000000080000000\n\t"
+ "# movups (%%r9), %%xmmA\n\t"
+ "# movups (%%r10), %%xmmB\n\t"
+ "# movups %%xmmA, %%xmmZ\n\t"
+ "# shufps $0xb1, %%xmmZ, %%xmmZ # swap internals\n\t"
+ "# mulps %%xmmB, %%xmmA\n\t"
+ "# mulps %%xmmZ, %%xmmB\n\t"
+ "# # SSE replacement for: pfpnacc %%xmmB, %%xmmA\n\t"
+ "# xorps %%xmmPN, %%xmmA\n\t"
+ "# movups %%xmmA, %%xmmZ\n\t"
+ "# unpcklps %%xmmB, %%xmmA\n\t"
+ "# unpckhps %%xmmB, %%xmmZ\n\t"
+ "# movups %%xmmZ, %%xmmY\n\t"
+ "# shufps $0x44, %%xmmA, %%xmmZ # b01000100\n\t"
+ "# shufps $0xee, %%xmmY, %%xmmA # b11101110\n\t"
+ "# addps %%xmmZ, %%xmmA\n\t"
+ "# addps %%xmmA, %%xmmC\n\t"
+ "# A=xmm0, B=xmm2, Z=xmm4\n\t"
+ "# A'=xmm1, B'=xmm3, Z'=xmm5\n\t"
+ " movups 16(%%r9), %%xmm1\n\t"
+ " movups %%xmm0, %%xmm4\n\t"
+ " mulps %%xmm2, %%xmm0\n\t"
+ " shufps $0xb1, %%xmm4, %%xmm4 # swap internals\n\t"
+ " movups 16(%%r10), %%xmm3\n\t"
+ " movups %%xmm1, %%xmm5\n\t"
+ " addps %%xmm0, %%xmm6\n\t"
+ " mulps %%xmm3, %%xmm1\n\t"
+ " shufps $0xb1, %%xmm5, %%xmm5 # swap internals\n\t"
+ " addps %%xmm1, %%xmm6\n\t"
+ " mulps %%xmm4, %%xmm2\n\t"
+ " movups 32(%%r9), %%xmm0\n\t"
+ " addps %%xmm2, %%xmm7\n\t"
+ " mulps %%xmm5, %%xmm3\n\t"
+ " add $32, %%r9\n\t"
+ " movups 32(%%r10), %%xmm2\n\t"
+ " addps %%xmm3, %%xmm7\n\t"
+ " add $32, %%r10\n\t"
+ ".%=L1_test:\n\t"
+ " dec %%rax\n\t"
+ " jge .%=Loop1\n\t"
+ " # We've handled the bulk of multiplies up to here.\n\t"
+ " # Let's sse if original n_2_ccomplex_blocks was odd.\n\t"
+ " # If so, we've got 2 more taps to do.\n\t"
+ " and $1, %%r8\n\t"
+ " je .%=Leven\n\t"
+ " # The count was odd, do 2 more taps.\n\t"
+ " # Note that we've already got mm0/mm2 preloaded\n\t"
+ " # from the main loop.\n\t"
+ " movups %%xmm0, %%xmm4\n\t"
+ " mulps %%xmm2, %%xmm0\n\t"
+ " shufps $0xb1, %%xmm4, %%xmm4 # swap internals\n\t"
+ " addps %%xmm0, %%xmm6\n\t"
+ " mulps %%xmm4, %%xmm2\n\t"
+ " addps %%xmm2, %%xmm7\n\t"
+ ".%=Leven:\n\t"
+ " # neg inversor\n\t"
+ " xorps %%xmm1, %%xmm1\n\t"
+ " mov $0x80000000, %%r9\n\t"
+ " movd %%r9, %%xmm1\n\t"
+ " shufps $0x11, %%xmm1, %%xmm1 # b00010001 # 0 -0 0 -0\n\t"
+ " # pfpnacc\n\t"
+ " xorps %%xmm1, %%xmm6\n\t"
+ " movups %%xmm6, %%xmm2\n\t"
+ " unpcklps %%xmm7, %%xmm6\n\t"
+ " unpckhps %%xmm7, %%xmm2\n\t"
+ " movups %%xmm2, %%xmm3\n\t"
+ " shufps $0x44, %%xmm6, %%xmm2 # b01000100\n\t"
+ " shufps $0xee, %%xmm3, %%xmm6 # b11101110\n\t"
+ " addps %%xmm2, %%xmm6\n\t"
+ " # xmm6 = r1 i2 r3 i4\n\t"
+ " movhlps %%xmm6, %%xmm4 # xmm4 = r3 i4 ?? ??\n\t"
+ " addps %%xmm4, %%xmm6 # xmm6 = r1+r3 i2+i4 ?? ??\n\t"
+ " movlps %%xmm6, (%[rdi]) # store low 2x32 bits (complex) to memory\n\t"
+ :
+ :[rsi] "r" (input), [rdx] "r" (taps), "c" (num_bytes), [rdi] "r" (result)
+ :"rax", "r8", "r9", "r10"
+ );
+
+
+ if(isodd) {
+ *result += input[num_points - 1] * taps[num_points - 1];
+ }
+
+ return;
+
+}
+
+#endif /* LV_HAVE_SSE && LV_HAVE_64 */
+
+
+
+
+#ifdef LV_HAVE_SSE3
+
+#include
+
+static inline void volk_gnsssdr_32fc_x2_dot_prod_32fc_u_sse3(lv_32fc_t* result, const lv_32fc_t* input, const lv_32fc_t* taps, unsigned int num_points) {
+
+ lv_32fc_t dotProduct;
+ memset(&dotProduct, 0x0, 2*sizeof(float));
+
+ unsigned int number = 0;
+ const unsigned int halfPoints = num_points/2;
+ unsigned int isodd = num_points & 1;
+
+ __m128 x, y, yl, yh, z, tmp1, tmp2, dotProdVal;
+
+ const lv_32fc_t* a = input;
+ const lv_32fc_t* b = taps;
+
+ dotProdVal = _mm_setzero_ps();
+
+ for(;number < halfPoints; number++){
+
+ x = _mm_loadu_ps((float*)a); // Load the ar + ai, br + bi as ar,ai,br,bi
+ y = _mm_loadu_ps((float*)b); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+
+ x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+
+ dotProdVal = _mm_add_ps(dotProdVal, z); // Add the complex multiplication results together
+
+ a += 2;
+ b += 2;
+ }
+
+ __VOLK_ATTR_ALIGNED(16) lv_32fc_t dotProductVector[2];
+
+ _mm_storeu_ps((float*)dotProductVector,dotProdVal); // Store the results back into the dot product vector
+
+ dotProduct += ( dotProductVector[0] + dotProductVector[1] );
+
+ if(isodd) {
+ dotProduct += input[num_points - 1] * taps[num_points - 1];
+ }
+
+ *result = dotProduct;
+}
+
+#endif /*LV_HAVE_SSE3*/
+
+#ifdef LV_HAVE_SSE4_1
+
+#include
+
+static inline void volk_gnsssdr_32fc_x2_dot_prod_32fc_u_sse4_1(lv_32fc_t* result, const lv_32fc_t* input, const lv_32fc_t* taps, unsigned int num_points) {
+
+ unsigned int i = 0;
+ const unsigned int qtr_points = num_points/4;
+ const unsigned int isodd = num_points & 3;
+
+ __m128 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, real0, real1, im0, im1;
+ float *p_input, *p_taps;
+ __m64 *p_result;
+
+ p_result = (__m64*)result;
+ p_input = (float*)input;
+ p_taps = (float*)taps;
+
+ static const __m128i neg = {0x000000000000000080000000};
+
+ real0 = _mm_setzero_ps();
+ real1 = _mm_setzero_ps();
+ im0 = _mm_setzero_ps();
+ im1 = _mm_setzero_ps();
+
+ for(; i < qtr_points; ++i) {
+ xmm0 = _mm_loadu_ps(p_input);
+ xmm1 = _mm_loadu_ps(p_taps);
+
+ p_input += 4;
+ p_taps += 4;
+
+ xmm2 = _mm_loadu_ps(p_input);
+ xmm3 = _mm_loadu_ps(p_taps);
+
+ p_input += 4;
+ p_taps += 4;
+
+ xmm4 = _mm_unpackhi_ps(xmm0, xmm2);
+ xmm5 = _mm_unpackhi_ps(xmm1, xmm3);
+ xmm0 = _mm_unpacklo_ps(xmm0, xmm2);
+ xmm2 = _mm_unpacklo_ps(xmm1, xmm3);
+
+ //imaginary vector from input
+ xmm1 = _mm_unpackhi_ps(xmm0, xmm4);
+ //real vector from input
+ xmm3 = _mm_unpacklo_ps(xmm0, xmm4);
+ //imaginary vector from taps
+ xmm0 = _mm_unpackhi_ps(xmm2, xmm5);
+ //real vector from taps
+ xmm2 = _mm_unpacklo_ps(xmm2, xmm5);
+
+ xmm4 = _mm_dp_ps(xmm3, xmm2, 0xf1);
+ xmm5 = _mm_dp_ps(xmm1, xmm0, 0xf1);
+
+ xmm6 = _mm_dp_ps(xmm3, xmm0, 0xf2);
+ xmm7 = _mm_dp_ps(xmm1, xmm2, 0xf2);
+
+ real0 = _mm_add_ps(xmm4, real0);
+ real1 = _mm_add_ps(xmm5, real1);
+ im0 = _mm_add_ps(xmm6, im0);
+ im1 = _mm_add_ps(xmm7, im1);
+ }
+
+ real1 = _mm_xor_ps(real1, bit128_p(&neg)->float_vec);
+
+ im0 = _mm_add_ps(im0, im1);
+ real0 = _mm_add_ps(real0, real1);
+
+ im0 = _mm_add_ps(im0, real0);
+
+ _mm_storel_pi(p_result, im0);
+
+ for(i = num_points-isodd; i < num_points; i++) {
+ *result += input[i] * taps[i];
+ }
+}
+
+#endif /*LV_HAVE_SSE4_1*/
+
+
+
+
+#endif /*INCLUDED_volk_gnsssdr_32fc_x2_dot_prod_32fc_u_H*/
+#ifndef INCLUDED_volk_gnsssdr_32fc_x2_dot_prod_32fc_a_H
+#define INCLUDED_volk_gnsssdr_32fc_x2_dot_prod_32fc_a_H
+
+#include
+#include
+#include
+#include
+
+
+#ifdef LV_HAVE_GENERIC
+
+
+static inline void volk_gnsssdr_32fc_x2_dot_prod_32fc_a_generic(lv_32fc_t* result, const lv_32fc_t* input, const lv_32fc_t* taps, unsigned int num_points) {
+
+ const unsigned int num_bytes = num_points*8;
+
+ float * res = (float*) result;
+ float * in = (float*) input;
+ float * tp = (float*) taps;
+ unsigned int n_2_ccomplex_blocks = num_bytes >> 4;
+ unsigned int isodd = num_points & 1;
+
+ float sum0[2] = {0,0};
+ float sum1[2] = {0,0};
+ unsigned int i = 0;
+
+ for(i = 0; i < n_2_ccomplex_blocks; ++i) {
+ sum0[0] += in[0] * tp[0] - in[1] * tp[1];
+ sum0[1] += in[0] * tp[1] + in[1] * tp[0];
+ sum1[0] += in[2] * tp[2] - in[3] * tp[3];
+ sum1[1] += in[2] * tp[3] + in[3] * tp[2];
+
+ in += 4;
+ tp += 4;
+ }
+
+ res[0] = sum0[0] + sum1[0];
+ res[1] = sum0[1] + sum1[1];
+
+ for(i = 0; i < isodd; ++i) {
+ *result += input[num_points - 1] * taps[num_points - 1];
+ }
+}
+
+#endif /*LV_HAVE_GENERIC*/
+
+
+#if LV_HAVE_SSE && LV_HAVE_64
+
+
+static inline void volk_gnsssdr_32fc_x2_dot_prod_32fc_a_sse_64(lv_32fc_t* result, const lv_32fc_t* input, const lv_32fc_t* taps, unsigned int num_points) {
+
+ const unsigned int num_bytes = num_points*8;
+ unsigned int isodd = num_points & 1;
+
+ asm
+ (
+ "# ccomplex_dotprod_generic (float* result, const float *input,\n\t"
+ "# const float *taps, unsigned num_bytes)\n\t"
+ "# float sum0 = 0;\n\t"
+ "# float sum1 = 0;\n\t"
+ "# float sum2 = 0;\n\t"
+ "# float sum3 = 0;\n\t"
+ "# do {\n\t"
+ "# sum0 += input[0] * taps[0] - input[1] * taps[1];\n\t"
+ "# sum1 += input[0] * taps[1] + input[1] * taps[0];\n\t"
+ "# sum2 += input[2] * taps[2] - input[3] * taps[3];\n\t"
+ "# sum3 += input[2] * taps[3] + input[3] * taps[2];\n\t"
+ "# input += 4;\n\t"
+ "# taps += 4; \n\t"
+ "# } while (--n_2_ccomplex_blocks != 0);\n\t"
+ "# result[0] = sum0 + sum2;\n\t"
+ "# result[1] = sum1 + sum3;\n\t"
+ "# TODO: prefetch and better scheduling\n\t"
+ " xor %%r9, %%r9\n\t"
+ " xor %%r10, %%r10\n\t"
+ " movq %%rcx, %%rax\n\t"
+ " movq %%rcx, %%r8\n\t"
+ " movq %[rsi], %%r9\n\t"
+ " movq %[rdx], %%r10\n\t"
+ " xorps %%xmm6, %%xmm6 # zero accumulators\n\t"
+ " movaps 0(%%r9), %%xmm0\n\t"
+ " xorps %%xmm7, %%xmm7 # zero accumulators\n\t"
+ " movaps 0(%%r10), %%xmm2\n\t"
+ " shr $5, %%rax # rax = n_2_ccomplex_blocks / 2\n\t"
+ " shr $4, %%r8\n\t"
+ " jmp .%=L1_test\n\t"
+ " # 4 taps / loop\n\t"
+ " # something like ?? cycles / loop\n\t"
+ ".%=Loop1: \n\t"
+ "# complex prod: C += A * B, w/ temp Z & Y (or B), xmmPN=$0x8000000080000000\n\t"
+ "# movaps (%%r9), %%xmmA\n\t"
+ "# movaps (%%r10), %%xmmB\n\t"
+ "# movaps %%xmmA, %%xmmZ\n\t"
+ "# shufps $0xb1, %%xmmZ, %%xmmZ # swap internals\n\t"
+ "# mulps %%xmmB, %%xmmA\n\t"
+ "# mulps %%xmmZ, %%xmmB\n\t"
+ "# # SSE replacement for: pfpnacc %%xmmB, %%xmmA\n\t"
+ "# xorps %%xmmPN, %%xmmA\n\t"
+ "# movaps %%xmmA, %%xmmZ\n\t"
+ "# unpcklps %%xmmB, %%xmmA\n\t"
+ "# unpckhps %%xmmB, %%xmmZ\n\t"
+ "# movaps %%xmmZ, %%xmmY\n\t"
+ "# shufps $0x44, %%xmmA, %%xmmZ # b01000100\n\t"
+ "# shufps $0xee, %%xmmY, %%xmmA # b11101110\n\t"
+ "# addps %%xmmZ, %%xmmA\n\t"
+ "# addps %%xmmA, %%xmmC\n\t"
+ "# A=xmm0, B=xmm2, Z=xmm4\n\t"
+ "# A'=xmm1, B'=xmm3, Z'=xmm5\n\t"
+ " movaps 16(%%r9), %%xmm1\n\t"
+ " movaps %%xmm0, %%xmm4\n\t"
+ " mulps %%xmm2, %%xmm0\n\t"
+ " shufps $0xb1, %%xmm4, %%xmm4 # swap internals\n\t"
+ " movaps 16(%%r10), %%xmm3\n\t"
+ " movaps %%xmm1, %%xmm5\n\t"
+ " addps %%xmm0, %%xmm6\n\t"
+ " mulps %%xmm3, %%xmm1\n\t"
+ " shufps $0xb1, %%xmm5, %%xmm5 # swap internals\n\t"
+ " addps %%xmm1, %%xmm6\n\t"
+ " mulps %%xmm4, %%xmm2\n\t"
+ " movaps 32(%%r9), %%xmm0\n\t"
+ " addps %%xmm2, %%xmm7\n\t"
+ " mulps %%xmm5, %%xmm3\n\t"
+ " add $32, %%r9\n\t"
+ " movaps 32(%%r10), %%xmm2\n\t"
+ " addps %%xmm3, %%xmm7\n\t"
+ " add $32, %%r10\n\t"
+ ".%=L1_test:\n\t"
+ " dec %%rax\n\t"
+ " jge .%=Loop1\n\t"
+ " # We've handled the bulk of multiplies up to here.\n\t"
+ " # Let's sse if original n_2_ccomplex_blocks was odd.\n\t"
+ " # If so, we've got 2 more taps to do.\n\t"
+ " and $1, %%r8\n\t"
+ " je .%=Leven\n\t"
+ " # The count was odd, do 2 more taps.\n\t"
+ " # Note that we've already got mm0/mm2 preloaded\n\t"
+ " # from the main loop.\n\t"
+ " movaps %%xmm0, %%xmm4\n\t"
+ " mulps %%xmm2, %%xmm0\n\t"
+ " shufps $0xb1, %%xmm4, %%xmm4 # swap internals\n\t"
+ " addps %%xmm0, %%xmm6\n\t"
+ " mulps %%xmm4, %%xmm2\n\t"
+ " addps %%xmm2, %%xmm7\n\t"
+ ".%=Leven:\n\t"
+ " # neg inversor\n\t"
+ " xorps %%xmm1, %%xmm1\n\t"
+ " mov $0x80000000, %%r9\n\t"
+ " movd %%r9, %%xmm1\n\t"
+ " shufps $0x11, %%xmm1, %%xmm1 # b00010001 # 0 -0 0 -0\n\t"
+ " # pfpnacc\n\t"
+ " xorps %%xmm1, %%xmm6\n\t"
+ " movaps %%xmm6, %%xmm2\n\t"
+ " unpcklps %%xmm7, %%xmm6\n\t"
+ " unpckhps %%xmm7, %%xmm2\n\t"
+ " movaps %%xmm2, %%xmm3\n\t"
+ " shufps $0x44, %%xmm6, %%xmm2 # b01000100\n\t"
+ " shufps $0xee, %%xmm3, %%xmm6 # b11101110\n\t"
+ " addps %%xmm2, %%xmm6\n\t"
+ " # xmm6 = r1 i2 r3 i4\n\t"
+ " movhlps %%xmm6, %%xmm4 # xmm4 = r3 i4 ?? ??\n\t"
+ " addps %%xmm4, %%xmm6 # xmm6 = r1+r3 i2+i4 ?? ??\n\t"
+ " movlps %%xmm6, (%[rdi]) # store low 2x32 bits (complex) to memory\n\t"
+ :
+ :[rsi] "r" (input), [rdx] "r" (taps), "c" (num_bytes), [rdi] "r" (result)
+ :"rax", "r8", "r9", "r10"
+ );
+
+
+ if(isodd) {
+ *result += input[num_points - 1] * taps[num_points - 1];
+ }
+
+ return;
+
+}
+
+#endif
+
+#if LV_HAVE_SSE && LV_HAVE_32
+
+static inline void volk_gnsssdr_32fc_x2_dot_prod_32fc_a_sse_32(lv_32fc_t* result, const lv_32fc_t* input, const lv_32fc_t* taps, unsigned int num_points) {
+
+ volk_gnsssdr_32fc_x2_dot_prod_32fc_a_generic(result, input, taps, num_points);
+
+#if 0
+ const unsigned int num_bytes = num_points*8;
+ unsigned int isodd = num_points & 1;
+
+ asm volatile
+ (
+ " #pushl %%ebp\n\t"
+ " #movl %%esp, %%ebp\n\t"
+ " movl 12(%%ebp), %%eax # input\n\t"
+ " movl 16(%%ebp), %%edx # taps\n\t"
+ " movl 20(%%ebp), %%ecx # n_bytes\n\t"
+ " xorps %%xmm6, %%xmm6 # zero accumulators\n\t"
+ " movaps 0(%%eax), %%xmm0\n\t"
+ " xorps %%xmm7, %%xmm7 # zero accumulators\n\t"
+ " movaps 0(%%edx), %%xmm2\n\t"
+ " shrl $5, %%ecx # ecx = n_2_ccomplex_blocks / 2\n\t"
+ " jmp .%=L1_test\n\t"
+ " # 4 taps / loop\n\t"
+ " # something like ?? cycles / loop\n\t"
+ ".%=Loop1: \n\t"
+ "# complex prod: C += A * B, w/ temp Z & Y (or B), xmmPN=$0x8000000080000000\n\t"
+ "# movaps (%%eax), %%xmmA\n\t"
+ "# movaps (%%edx), %%xmmB\n\t"
+ "# movaps %%xmmA, %%xmmZ\n\t"
+ "# shufps $0xb1, %%xmmZ, %%xmmZ # swap internals\n\t"
+ "# mulps %%xmmB, %%xmmA\n\t"
+ "# mulps %%xmmZ, %%xmmB\n\t"
+ "# # SSE replacement for: pfpnacc %%xmmB, %%xmmA\n\t"
+ "# xorps %%xmmPN, %%xmmA\n\t"
+ "# movaps %%xmmA, %%xmmZ\n\t"
+ "# unpcklps %%xmmB, %%xmmA\n\t"
+ "# unpckhps %%xmmB, %%xmmZ\n\t"
+ "# movaps %%xmmZ, %%xmmY\n\t"
+ "# shufps $0x44, %%xmmA, %%xmmZ # b01000100\n\t"
+ "# shufps $0xee, %%xmmY, %%xmmA # b11101110\n\t"
+ "# addps %%xmmZ, %%xmmA\n\t"
+ "# addps %%xmmA, %%xmmC\n\t"
+ "# A=xmm0, B=xmm2, Z=xmm4\n\t"
+ "# A'=xmm1, B'=xmm3, Z'=xmm5\n\t"
+ " movaps 16(%%eax), %%xmm1\n\t"
+ " movaps %%xmm0, %%xmm4\n\t"
+ " mulps %%xmm2, %%xmm0\n\t"
+ " shufps $0xb1, %%xmm4, %%xmm4 # swap internals\n\t"
+ " movaps 16(%%edx), %%xmm3\n\t"
+ " movaps %%xmm1, %%xmm5\n\t"
+ " addps %%xmm0, %%xmm6\n\t"
+ " mulps %%xmm3, %%xmm1\n\t"
+ " shufps $0xb1, %%xmm5, %%xmm5 # swap internals\n\t"
+ " addps %%xmm1, %%xmm6\n\t"
+ " mulps %%xmm4, %%xmm2\n\t"
+ " movaps 32(%%eax), %%xmm0\n\t"
+ " addps %%xmm2, %%xmm7\n\t"
+ " mulps %%xmm5, %%xmm3\n\t"
+ " addl $32, %%eax\n\t"
+ " movaps 32(%%edx), %%xmm2\n\t"
+ " addps %%xmm3, %%xmm7\n\t"
+ " addl $32, %%edx\n\t"
+ ".%=L1_test:\n\t"
+ " decl %%ecx\n\t"
+ " jge .%=Loop1\n\t"
+ " # We've handled the bulk of multiplies up to here.\n\t"
+ " # Let's sse if original n_2_ccomplex_blocks was odd.\n\t"
+ " # If so, we've got 2 more taps to do.\n\t"
+ " movl 20(%%ebp), %%ecx # n_2_ccomplex_blocks\n\t"
+ " shrl $4, %%ecx\n\t"
+ " andl $1, %%ecx\n\t"
+ " je .%=Leven\n\t"
+ " # The count was odd, do 2 more taps.\n\t"
+ " # Note that we've already got mm0/mm2 preloaded\n\t"
+ " # from the main loop.\n\t"
+ " movaps %%xmm0, %%xmm4\n\t"
+ " mulps %%xmm2, %%xmm0\n\t"
+ " shufps $0xb1, %%xmm4, %%xmm4 # swap internals\n\t"
+ " addps %%xmm0, %%xmm6\n\t"
+ " mulps %%xmm4, %%xmm2\n\t"
+ " addps %%xmm2, %%xmm7\n\t"
+ ".%=Leven:\n\t"
+ " # neg inversor\n\t"
+ " movl 8(%%ebp), %%eax \n\t"
+ " xorps %%xmm1, %%xmm1\n\t"
+ " movl $0x80000000, (%%eax)\n\t"
+ " movss (%%eax), %%xmm1\n\t"
+ " shufps $0x11, %%xmm1, %%xmm1 # b00010001 # 0 -0 0 -0\n\t"
+ " # pfpnacc\n\t"
+ " xorps %%xmm1, %%xmm6\n\t"
+ " movaps %%xmm6, %%xmm2\n\t"
+ " unpcklps %%xmm7, %%xmm6\n\t"
+ " unpckhps %%xmm7, %%xmm2\n\t"
+ " movaps %%xmm2, %%xmm3\n\t"
+ " shufps $0x44, %%xmm6, %%xmm2 # b01000100\n\t"
+ " shufps $0xee, %%xmm3, %%xmm6 # b11101110\n\t"
+ " addps %%xmm2, %%xmm6\n\t"
+ " # xmm6 = r1 i2 r3 i4\n\t"
+ " #movl 8(%%ebp), %%eax # @result\n\t"
+ " movhlps %%xmm6, %%xmm4 # xmm4 = r3 i4 ?? ??\n\t"
+ " addps %%xmm4, %%xmm6 # xmm6 = r1+r3 i2+i4 ?? ??\n\t"
+ " movlps %%xmm6, (%%eax) # store low 2x32 bits (complex) to memory\n\t"
+ " #popl %%ebp\n\t"
+ :
+ :
+ : "eax", "ecx", "edx"
+ );
+
+
+ int getem = num_bytes % 16;
+
+ if(isodd) {
+ *result += (input[num_points - 1] * taps[num_points - 1]);
+ }
+
+ return;
+#endif
+}
+
+#endif /*LV_HAVE_SSE*/
+
+#ifdef LV_HAVE_SSE3
+
+#include
+
+static inline void volk_gnsssdr_32fc_x2_dot_prod_32fc_a_sse3(lv_32fc_t* result, const lv_32fc_t* input, const lv_32fc_t* taps, unsigned int num_points) {
+
+ const unsigned int num_bytes = num_points*8;
+ unsigned int isodd = num_points & 1;
+
+ lv_32fc_t dotProduct;
+ memset(&dotProduct, 0x0, 2*sizeof(float));
+
+ unsigned int number = 0;
+ const unsigned int halfPoints = num_bytes >> 4;
+
+ __m128 x, y, yl, yh, z, tmp1, tmp2, dotProdVal;
+
+ const lv_32fc_t* a = input;
+ const lv_32fc_t* b = taps;
+
+ dotProdVal = _mm_setzero_ps();
+
+ for(;number < halfPoints; number++){
+
+ x = _mm_load_ps((float*)a); // Load the ar + ai, br + bi as ar,ai,br,bi
+ y = _mm_load_ps((float*)b); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+
+ x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+
+ dotProdVal = _mm_add_ps(dotProdVal, z); // Add the complex multiplication results together
+
+ a += 2;
+ b += 2;
+ }
+
+ __VOLK_ATTR_ALIGNED(16) lv_32fc_t dotProductVector[2];
+
+ _mm_store_ps((float*)dotProductVector,dotProdVal); // Store the results back into the dot product vector
+
+ dotProduct += ( dotProductVector[0] + dotProductVector[1] );
+
+ if(isodd) {
+ dotProduct += input[num_points - 1] * taps[num_points - 1];
+ }
+
+ *result = dotProduct;
+}
+
+#endif /*LV_HAVE_SSE3*/
+
+#ifdef LV_HAVE_SSE4_1
+
+#include
+
+static inline void volk_gnsssdr_32fc_x2_dot_prod_32fc_a_sse4_1(lv_32fc_t* result, const lv_32fc_t* input, const lv_32fc_t* taps, unsigned int num_points) {
+
+ unsigned int i = 0;
+ const unsigned int qtr_points = num_points/4;
+ const unsigned int isodd = num_points & 3;
+
+ __m128 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, real0, real1, im0, im1;
+ float *p_input, *p_taps;
+ __m64 *p_result;
+
+ static const __m128i neg = {0x000000000000000080000000};
+
+ p_result = (__m64*)result;
+ p_input = (float*)input;
+ p_taps = (float*)taps;
+
+ real0 = _mm_setzero_ps();
+ real1 = _mm_setzero_ps();
+ im0 = _mm_setzero_ps();
+ im1 = _mm_setzero_ps();
+
+ for(; i < qtr_points; ++i) {
+ xmm0 = _mm_load_ps(p_input);
+ xmm1 = _mm_load_ps(p_taps);
+
+ p_input += 4;
+ p_taps += 4;
+
+ xmm2 = _mm_load_ps(p_input);
+ xmm3 = _mm_load_ps(p_taps);
+
+ p_input += 4;
+ p_taps += 4;
+
+ xmm4 = _mm_unpackhi_ps(xmm0, xmm2);
+ xmm5 = _mm_unpackhi_ps(xmm1, xmm3);
+ xmm0 = _mm_unpacklo_ps(xmm0, xmm2);
+ xmm2 = _mm_unpacklo_ps(xmm1, xmm3);
+
+ //imaginary vector from input
+ xmm1 = _mm_unpackhi_ps(xmm0, xmm4);
+ //real vector from input
+ xmm3 = _mm_unpacklo_ps(xmm0, xmm4);
+ //imaginary vector from taps
+ xmm0 = _mm_unpackhi_ps(xmm2, xmm5);
+ //real vector from taps
+ xmm2 = _mm_unpacklo_ps(xmm2, xmm5);
+
+ xmm4 = _mm_dp_ps(xmm3, xmm2, 0xf1);
+ xmm5 = _mm_dp_ps(xmm1, xmm0, 0xf1);
+
+ xmm6 = _mm_dp_ps(xmm3, xmm0, 0xf2);
+ xmm7 = _mm_dp_ps(xmm1, xmm2, 0xf2);
+
+ real0 = _mm_add_ps(xmm4, real0);
+ real1 = _mm_add_ps(xmm5, real1);
+ im0 = _mm_add_ps(xmm6, im0);
+ im1 = _mm_add_ps(xmm7, im1);
+ }
+
+ real1 = _mm_xor_ps(real1, bit128_p(&neg)->float_vec);
+
+ im0 = _mm_add_ps(im0, im1);
+ real0 = _mm_add_ps(real0, real1);
+
+ im0 = _mm_add_ps(im0, real0);
+
+ _mm_storel_pi(p_result, im0);
+
+ for(i = num_points-isodd; i < num_points; i++) {
+ *result += input[i] * taps[i];
+ }
+}
+
+#endif /*LV_HAVE_SSE4_1*/
+
+#endif /*INCLUDED_volk_gnsssdr_32fc_x2_dot_prod_32fc_a_H*/
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_x2_multiply_32fc.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_x2_multiply_32fc.h
new file mode 100644
index 000000000..e2b17c401
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_x2_multiply_32fc.h
@@ -0,0 +1,170 @@
+#ifndef INCLUDED_volk_gnsssdr_32fc_x2_multiply_32fc_u_H
+#define INCLUDED_volk_gnsssdr_32fc_x2_multiply_32fc_u_H
+
+#include
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE3
+#include
+ /*!
+ \brief Multiplies the two input complex vectors and stores their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be multiplied
+ \param bVector One of the vectors to be multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+static inline void volk_gnsssdr_32fc_x2_multiply_32fc_u_sse3(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t* bVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int halfPoints = num_points / 2;
+
+ __m128 x, y, yl, yh, z, tmp1, tmp2;
+ lv_32fc_t* c = cVector;
+ const lv_32fc_t* a = aVector;
+ const lv_32fc_t* b = bVector;
+
+ for(;number < halfPoints; number++){
+
+ x = _mm_loadu_ps((float*)a); // Load the ar + ai, br + bi as ar,ai,br,bi
+ y = _mm_loadu_ps((float*)b); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+
+ x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+
+ _mm_storeu_ps((float*)c,z); // Store the results back into the C container
+
+ a += 2;
+ b += 2;
+ c += 2;
+ }
+
+ if((num_points % 2) != 0) {
+ *c = (*a) * (*b);
+ }
+}
+#endif /* LV_HAVE_SSE */
+
+#ifdef LV_HAVE_GENERIC
+ /*!
+ \brief Multiplies the two input complex vectors and stores their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be multiplied
+ \param bVector One of the vectors to be multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+static inline void volk_gnsssdr_32fc_x2_multiply_32fc_generic(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t* bVector, unsigned int num_points){
+ lv_32fc_t* cPtr = cVector;
+ const lv_32fc_t* aPtr = aVector;
+ const lv_32fc_t* bPtr= bVector;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ *cPtr++ = (*aPtr++) * (*bPtr++);
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+
+#endif /* INCLUDED_volk_gnsssdr_32fc_x2_multiply_32fc_u_H */
+#ifndef INCLUDED_volk_gnsssdr_32fc_x2_multiply_32fc_a_H
+#define INCLUDED_volk_gnsssdr_32fc_x2_multiply_32fc_a_H
+
+#include
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE3
+#include
+ /*!
+ \brief Multiplies the two input complex vectors and stores their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be multiplied
+ \param bVector One of the vectors to be multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+static inline void volk_gnsssdr_32fc_x2_multiply_32fc_a_sse3(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t* bVector, unsigned int num_points){
+ unsigned int number = 0;
+ const unsigned int halfPoints = num_points / 2;
+
+ __m128 x, y, yl, yh, z, tmp1, tmp2;
+ lv_32fc_t* c = cVector;
+ const lv_32fc_t* a = aVector;
+ const lv_32fc_t* b = bVector;
+ for(;number < halfPoints; number++){
+
+ x = _mm_load_ps((float*)a); // Load the ar + ai, br + bi as ar,ai,br,bi
+ y = _mm_load_ps((float*)b); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+
+ x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+
+ _mm_store_ps((float*)c,z); // Store the results back into the C container
+
+ a += 2;
+ b += 2;
+ c += 2;
+ }
+
+ if((num_points % 2) != 0) {
+ *c = (*a) * (*b);
+ }
+}
+#endif /* LV_HAVE_SSE */
+
+#ifdef LV_HAVE_GENERIC
+ /*!
+ \brief Multiplies the two input complex vectors and stores their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be multiplied
+ \param bVector One of the vectors to be multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+static inline void volk_gnsssdr_32fc_x2_multiply_32fc_a_generic(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t* bVector, unsigned int num_points){
+ lv_32fc_t* cPtr = cVector;
+ const lv_32fc_t* aPtr = aVector;
+ const lv_32fc_t* bPtr= bVector;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ *cPtr++ = (*aPtr++) * (*bPtr++);
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+#ifdef LV_HAVE_ORC
+ /*!
+ \brief Multiplies the two input complex vectors and stores their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be multiplied
+ \param bVector One of the vectors to be multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+extern void volk_gnsssdr_32fc_x2_multiply_32fc_a_orc_impl(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t* bVector, unsigned int num_points);
+static inline void volk_gnsssdr_32fc_x2_multiply_32fc_u_orc(lv_32fc_t* cVector, const lv_32fc_t* aVector, const lv_32fc_t* bVector, unsigned int num_points){
+ volk_gnsssdr_32fc_x2_multiply_32fc_a_orc_impl(cVector, aVector, bVector, num_points);
+}
+#endif /* LV_HAVE_ORC */
+
+
+
+
+
+#endif /* INCLUDED_volk_gnsssdr_32fc_x2_multiply_32fc_a_H */
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_x5_cw_epl_corr_32fc_x3.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_x5_cw_epl_corr_32fc_x3.h
new file mode 100644
index 000000000..7e05be9cf
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_x5_cw_epl_corr_32fc_x3.h
@@ -0,0 +1,409 @@
+#ifndef INCLUDED_gnsssdr_volk_gnsssdr_32fc_x5_cw_epl_corr_32fc_x3_u_H
+#define INCLUDED_gnsssdr_volk_gnsssdr_32fc_x5_cw_epl_corr_32fc_x3_u_H
+
+#include
+#include
+#include
+#include
+#include
+
+/*!
+ * TODO: Code the SSE4 version and benchmark it
+ */
+#ifdef LV_HAVE_SSE3
+#include
+
+
+ /*!
+ \brief Performs the carrier wipe-off mixing and the Early, Prompt, and Late correlation
+ \param input The input signal input
+ \param carrier The carrier signal input
+ \param E_code Early PRN code replica input
+ \param P_code Early PRN code replica input
+ \param L_code Early PRN code replica input
+ \param E_out Early correlation output
+ \param P_out Early correlation output
+ \param L_out Early correlation output
+ \param num_points The number of complex values in vectors
+ */
+static inline void volk_gnsssdr_32fc_x5_cw_epl_corr_32fc_x3_u_sse3(lv_32fc_t* E_out, lv_32fc_t* P_out, lv_32fc_t* L_out, const lv_32fc_t* input, const lv_32fc_t* carrier, const lv_32fc_t* E_code, const lv_32fc_t* P_code, const lv_32fc_t* L_code, unsigned int num_points)
+{
+ unsigned int number = 0;
+ const unsigned int halfPoints = num_points / 2;
+
+ lv_32fc_t dotProduct_E;
+ memset(&dotProduct_E, 0x0, 2*sizeof(float));
+ lv_32fc_t dotProduct_P;
+ memset(&dotProduct_P, 0x0, 2*sizeof(float));
+ lv_32fc_t dotProduct_L;
+ memset(&dotProduct_L, 0x0, 2*sizeof(float));
+
+ // Aux vars
+ __m128 x, y, yl, yh, z, tmp1, tmp2, z_E, z_P, z_L;
+
+ z_E = _mm_setzero_ps();
+ z_P = _mm_setzero_ps();
+ z_L = _mm_setzero_ps();
+
+ //input and output vectors
+ //lv_32fc_t* _input_BB = input_BB;
+ const lv_32fc_t* _input = input;
+ const lv_32fc_t* _carrier = carrier;
+ const lv_32fc_t* _E_code = E_code;
+ const lv_32fc_t* _P_code = P_code;
+ const lv_32fc_t* _L_code = L_code;
+
+ for(;number < halfPoints; number++)
+ {
+ // carrier wipe-off (vector point-to-point product)
+ x = _mm_loadu_ps((float*)_input); // Load the ar + ai, br + bi as ar,ai,br,bi
+ y = _mm_loadu_ps((float*)_carrier); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+
+ x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+
+ //_mm_storeu_ps((float*)_input_BB,z); // Store the results back into the _input_BB container
+
+ // correlation E,P,L (3x vector scalar product)
+ // Early
+ //x = _mm_load_ps((float*)_input_BB); // Load the ar + ai, br + bi as ar,ai,br,bi
+ x = z;
+
+ y = _mm_load_ps((float*)_E_code); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+
+ x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+
+ z_E = _mm_add_ps(z_E, z); // Add the complex multiplication results together
+
+ // Prompt
+ //x = _mm_load_ps((float*)_input_BB); // Load the ar + ai, br + bi as ar,ai,br,bi
+ y = _mm_load_ps((float*)_P_code); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+
+ x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+
+ z_P = _mm_add_ps(z_P, z); // Add the complex multiplication results together
+
+ // Late
+ //x = _mm_load_ps((float*)_input_BB); // Load the ar + ai, br + bi as ar,ai,br,bi
+ y = _mm_load_ps((float*)_L_code); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+
+ x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+
+ z_L = _mm_add_ps(z_L, z); // Add the complex multiplication results together
+
+ /*pointer increment*/
+ _carrier += 2;
+ _input += 2;
+ //_input_BB += 2;
+ _E_code += 2;
+ _P_code += 2;
+ _L_code +=2;
+ }
+
+ __VOLK_ATTR_ALIGNED(16) lv_32fc_t dotProductVector_E[2];
+ __VOLK_ATTR_ALIGNED(16) lv_32fc_t dotProductVector_P[2];
+ __VOLK_ATTR_ALIGNED(16) lv_32fc_t dotProductVector_L[2];
+ //__VOLK_ATTR_ALIGNED(16) lv_32fc_t _input_BB;
+
+ _mm_store_ps((float*)dotProductVector_E,z_E); // Store the results back into the dot product vector
+ _mm_store_ps((float*)dotProductVector_P,z_P); // Store the results back into the dot product vector
+ _mm_store_ps((float*)dotProductVector_L,z_L); // Store the results back into the dot product vector
+
+ dotProduct_E += ( dotProductVector_E[0] + dotProductVector_E[1] );
+ dotProduct_P += ( dotProductVector_P[0] + dotProductVector_P[1] );
+ dotProduct_L += ( dotProductVector_L[0] + dotProductVector_L[1] );
+
+ if((num_points % 2) != 0)
+ {
+ //_input_BB = (*_input) * (*_carrier);
+ dotProduct_E += (*_input) * (*_E_code)*(*_carrier);
+ dotProduct_P += (*_input) * (*_P_code)*(*_carrier);
+ dotProduct_L += (*_input) * (*_L_code)*(*_carrier);
+ }
+
+ *E_out = dotProduct_E;
+ *P_out = dotProduct_P;
+ *L_out = dotProduct_L;
+}
+
+#endif /* LV_HAVE_SSE3 */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Performs the carrier wipe-off mixing and the Early, Prompt, and Late correlation
+ \param input The input signal input
+ \param carrier The carrier signal input
+ \param E_code Early PRN code replica input
+ \param P_code Early PRN code replica input
+ \param L_code Early PRN code replica input
+ \param E_out Early correlation output
+ \param P_out Early correlation output
+ \param L_out Early correlation output
+ \param num_points The number of complex values in vectors
+ */
+static inline void volk_gnsssdr_32fc_x5_cw_epl_corr_32fc_x3_generic(lv_32fc_t* E_out, lv_32fc_t* P_out, lv_32fc_t* L_out, const lv_32fc_t* input, const lv_32fc_t* carrier, const lv_32fc_t* E_code, const lv_32fc_t* P_code, const lv_32fc_t* L_code, unsigned int num_points)
+{
+ lv_32fc_t bb_signal_sample;
+
+ bb_signal_sample = lv_cmake(0, 0);
+
+ *E_out = 0;
+ *P_out = 0;
+ *L_out = 0;
+ // perform Early, Prompt and Late correlation
+ for(int i=0; i < num_points; ++i)
+ {
+ //Perform the carrier wipe-off
+ bb_signal_sample = input[i] * carrier[i];
+ // Now get early, late, and prompt values for each
+ *E_out += bb_signal_sample * E_code[i];
+ *P_out += bb_signal_sample * P_code[i];
+ *L_out += bb_signal_sample * L_code[i];
+ }
+}
+
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_gnsssdr_volk_gnsssdr_32fc_x5_cw_epl_corr_32fc_x3_u_H */
+
+
+#ifndef INCLUDED_gnsssdr_volk_gnsssdr_32fc_x5_cw_epl_corr_32fc_x3_a_H
+#define INCLUDED_gnsssdr_volk_gnsssdr_32fc_x5_cw_epl_corr_32fc_x3_a_H
+
+#include
+#include
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE3
+#include
+/*!
+ \brief Performs the carrier wipe-off mixing and the Early, Prompt, and Late correlation
+ \param input The input signal input
+ \param carrier The carrier signal input
+ \param E_code Early PRN code replica input
+ \param P_code Early PRN code replica input
+ \param L_code Early PRN code replica input
+ \param E_out Early correlation output
+ \param P_out Early correlation output
+ \param L_out Early correlation output
+ \param num_points The number of complex values in vectors
+ */
+static inline void volk_gnsssdr_32fc_x5_cw_epl_corr_32fc_x3_a_sse3(lv_32fc_t* E_out, lv_32fc_t* P_out, lv_32fc_t* L_out, const lv_32fc_t* input, const lv_32fc_t* carrier, const lv_32fc_t* E_code, const lv_32fc_t* P_code, const lv_32fc_t* L_code, unsigned int num_points)
+{
+ unsigned int number = 0;
+ const unsigned int halfPoints = num_points / 2;
+
+ lv_32fc_t dotProduct_E;
+ memset(&dotProduct_E, 0x0, 2*sizeof(float));
+ lv_32fc_t dotProduct_P;
+ memset(&dotProduct_P, 0x0, 2*sizeof(float));
+ lv_32fc_t dotProduct_L;
+ memset(&dotProduct_L, 0x0, 2*sizeof(float));
+
+ // Aux vars
+ __m128 x, y, yl, yh, z, tmp1, tmp2, z_E, z_P, z_L;
+
+ z_E = _mm_setzero_ps();
+ z_P = _mm_setzero_ps();
+ z_L = _mm_setzero_ps();
+
+ //input and output vectors
+ //lv_32fc_t* _input_BB = input_BB;
+ const lv_32fc_t* _input = input;
+ const lv_32fc_t* _carrier = carrier;
+ const lv_32fc_t* _E_code = E_code;
+ const lv_32fc_t* _P_code = P_code;
+ const lv_32fc_t* _L_code = L_code;
+
+ for(;number < halfPoints; number++)
+ {
+ // carrier wipe-off (vector point-to-point product)
+ x = _mm_load_ps((float*)_input); // Load the ar + ai, br + bi as ar,ai,br,bi
+ y = _mm_load_ps((float*)_carrier); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+
+ x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+
+ //_mm_storeu_ps((float*)_input_BB,z); // Store the results back into the _input_BB container
+
+ // correlation E,P,L (3x vector scalar product)
+ // Early
+ //x = _mm_load_ps((float*)_input_BB); // Load the ar + ai, br + bi as ar,ai,br,bi
+ x = z;
+
+ y = _mm_load_ps((float*)_E_code); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+
+ x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+
+ z_E = _mm_add_ps(z_E, z); // Add the complex multiplication results together
+
+ // Prompt
+ //x = _mm_load_ps((float*)_input_BB); // Load the ar + ai, br + bi as ar,ai,br,bi
+ y = _mm_load_ps((float*)_P_code); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+
+ x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+
+ z_P = _mm_add_ps(z_P, z); // Add the complex multiplication results together
+
+ // Late
+ //x = _mm_load_ps((float*)_input_BB); // Load the ar + ai, br + bi as ar,ai,br,bi
+ y = _mm_load_ps((float*)_L_code); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+
+ x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+
+ z_L = _mm_add_ps(z_L, z); // Add the complex multiplication results together
+
+ /*pointer increment*/
+ _carrier += 2;
+ _input += 2;
+ //_input_BB += 2;
+ _E_code += 2;
+ _P_code += 2;
+ _L_code +=2;
+ }
+
+ __VOLK_ATTR_ALIGNED(16) lv_32fc_t dotProductVector_E[2];
+ __VOLK_ATTR_ALIGNED(16) lv_32fc_t dotProductVector_P[2];
+ __VOLK_ATTR_ALIGNED(16) lv_32fc_t dotProductVector_L[2];
+ //__VOLK_ATTR_ALIGNED(16) lv_32fc_t _input_BB;
+
+ _mm_store_ps((float*)dotProductVector_E,z_E); // Store the results back into the dot product vector
+ _mm_store_ps((float*)dotProductVector_P,z_P); // Store the results back into the dot product vector
+ _mm_store_ps((float*)dotProductVector_L,z_L); // Store the results back into the dot product vector
+
+ dotProduct_E += ( dotProductVector_E[0] + dotProductVector_E[1] );
+ dotProduct_P += ( dotProductVector_P[0] + dotProductVector_P[1] );
+ dotProduct_L += ( dotProductVector_L[0] + dotProductVector_L[1] );
+
+ if((num_points % 2) != 0)
+ {
+ //_input_BB = (*_input) * (*_carrier);
+ dotProduct_E += (*_input) * (*_E_code)*(*_carrier);
+ dotProduct_P += (*_input) * (*_P_code)*(*_carrier);
+ dotProduct_L += (*_input) * (*_L_code)*(*_carrier);
+ }
+
+ *E_out = dotProduct_E;
+ *P_out = dotProduct_P;
+ *L_out = dotProduct_L;
+}
+
+#endif /* LV_HAVE_SSE3 */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Performs the carrier wipe-off mixing and the Early, Prompt, and Late correlation
+ \param input The input signal input
+ \param carrier The carrier signal input
+ \param E_code Early PRN code replica input
+ \param P_code Early PRN code replica input
+ \param L_code Early PRN code replica input
+ \param E_out Early correlation output
+ \param P_out Early correlation output
+ \param L_out Early correlation output
+ \param num_points The number of complex values in vectors
+ */
+static inline void volk_gnsssdr_32fc_x5_cw_epl_corr_32fc_x3_a_generic(lv_32fc_t* E_out, lv_32fc_t* P_out, lv_32fc_t* L_out, const lv_32fc_t* input, const lv_32fc_t* carrier, const lv_32fc_t* E_code, const lv_32fc_t* P_code, const lv_32fc_t* L_code, unsigned int num_points)
+{
+ lv_32fc_t bb_signal_sample;
+
+ bb_signal_sample = lv_cmake(0, 0);
+
+ *E_out = 0;
+ *P_out = 0;
+ *L_out = 0;
+ // perform Early, Prompt and Late correlation
+ for(int i=0; i < num_points; ++i)
+ {
+ //Perform the carrier wipe-off
+ bb_signal_sample = input[i] * carrier[i];
+ // Now get early, late, and prompt values for each
+ *E_out += bb_signal_sample * E_code[i];
+ *P_out += bb_signal_sample * P_code[i];
+ *L_out += bb_signal_sample * L_code[i];
+ }
+}
+
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_gnsssdr_volk_gnsssdr_32fc_x5_cw_epl_corr_32fc_x3_a_H */
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_x7_cw_vepl_corr_32fc_x5.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_x7_cw_vepl_corr_32fc_x5.h
new file mode 100644
index 000000000..378cea204
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_32fc_x7_cw_vepl_corr_32fc_x5.h
@@ -0,0 +1,524 @@
+/*!
+ * \file volk_gnsssdr_32fc_x7_cw_vepl_corr_32fc_x5
+ * \brief Volk protokernel: performs the carrier wipe-off mixing and the VE, Early, Prompt, Late and VL correlation with 64 bits vectors
+ * \authors
+ * - Javier Arribas, 2011. jarribas(at)cttc.es
+ *
- Andrés Cecilia, 2014. a.cecilia.luque(at)gmail.com
+ *
+ *
+ * Volk protokernel that performs the carrier wipe-off mixing and the
+ * VE, Early, Prompt, Late and VL correlation with 64 bits vectors (32 bits the
+ * real part and 32 bits the imaginary part):
+ * - The carrier wipe-off is done by multiplying the input signal by the
+ * carrier (multiplication of 64 bits vectors) It returns the input
+ * signal in base band (BB)
+ * - VE values are calculated by multiplying the input signal in BB by the
+ * VE code (multiplication of 64 bits vectors), accumulating the results
+ * - Early values are calculated by multiplying the input signal in BB by the
+ * early code (multiplication of 64 bits vectors), accumulating the results
+ * - Prompt values are calculated by multiplying the input signal in BB by the
+ * prompt code (multiplication of 64 bits vectors), accumulating the results
+ * - Late values are calculated by multiplying the input signal in BB by the
+ * late code (multiplication of 64 bits vectors), accumulating the results
+ * - VL values are calculated by multiplying the input signal in BB by the
+ * VL code (multiplication of 64 bits vectors), accumulating the results
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#ifndef INCLUDED_gnsssdr_volk_gnsssdr_32fc_x7_cw_vepl_corr_32fc_x5_u_H
+#define INCLUDED_gnsssdr_volk_gnsssdr_32fc_x7_cw_vepl_corr_32fc_x5_u_H
+
+#include
+#include
+#include
+#include
+#include
+
+/*!
+ * TODO: Code the SSE4 version and benchmark it
+ */
+#ifdef LV_HAVE_SSE3
+#include
+
+
+ /*!
+ \brief Performs the carrier wipe-off mixing and the VE, Early, Prompt, Late and VL correlation
+ \param input The input signal input
+ \param carrier The carrier signal input
+ \param VE_code VE PRN code replica input
+ \param E_code Early PRN code replica input
+ \param P_code Early PRN code replica input
+ \param L_code Early PRN code replica input
+ \param VL_code VL PRN code replica input
+ \param VE_out VE correlation output
+ \param E_out Early correlation output
+ \param P_out Early correlation output
+ \param L_out Early correlation output
+ \param VL_out VL correlation output
+ \param num_points The number of complex values in vectors
+ */
+static inline void volk_gnsssdr_32fc_x7_cw_vepl_corr_32fc_x5_u_sse3(lv_32fc_t* VE_out, lv_32fc_t* E_out, lv_32fc_t* P_out, lv_32fc_t* L_out, lv_32fc_t* VL_out, const lv_32fc_t* input, const lv_32fc_t* carrier, const lv_32fc_t* VE_code, const lv_32fc_t* E_code, const lv_32fc_t* P_code, const lv_32fc_t* L_code, const lv_32fc_t* VL_code, unsigned int num_points)
+{
+ unsigned int number = 0;
+ const unsigned int halfPoints = num_points / 2;
+
+ lv_32fc_t dotProduct_VE;
+ memset(&dotProduct_VE, 0x0, 2*sizeof(float));
+ lv_32fc_t dotProduct_E;
+ memset(&dotProduct_E, 0x0, 2*sizeof(float));
+ lv_32fc_t dotProduct_P;
+ memset(&dotProduct_P, 0x0, 2*sizeof(float));
+ lv_32fc_t dotProduct_L;
+ memset(&dotProduct_L, 0x0, 2*sizeof(float));
+ lv_32fc_t dotProduct_VL;
+ memset(&dotProduct_VL, 0x0, 2*sizeof(float));
+
+ // Aux vars
+ __m128 x, y, yl, yh, z, tmp1, tmp2, z_VE, z_E, z_P, z_L, z_VL;
+ __m128 bb_signal_sample, bb_signal_sample_shuffled;
+
+ z_VE = _mm_setzero_ps();
+ z_E = _mm_setzero_ps();
+ z_P = _mm_setzero_ps();
+ z_L = _mm_setzero_ps();
+ z_VL = _mm_setzero_ps();
+
+ //input and output vectors
+ const lv_32fc_t* _input = input;
+ const lv_32fc_t* _carrier = carrier;
+ const lv_32fc_t* _VE_code = VE_code;
+ const lv_32fc_t* _E_code = E_code;
+ const lv_32fc_t* _P_code = P_code;
+ const lv_32fc_t* _L_code = L_code;
+ const lv_32fc_t* _VL_code = VL_code;
+
+ for(;number < halfPoints; number++)
+ {
+ // carrier wipe-off (vector point-to-point product)
+ x = _mm_loadu_ps((float*)_input); // Load the ar + ai, br + bi as ar,ai,br,bi
+ y = _mm_loadu_ps((float*)_carrier); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+
+ x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ bb_signal_sample = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+ bb_signal_sample_shuffled = _mm_shuffle_ps(bb_signal_sample,bb_signal_sample,0xB1); // Re-arrange bb_signal_sample to be ai,ar,bi,br
+
+ // correlation VE,E,P,L,VL (5x vector scalar product)
+ // VE
+ y = _mm_loadu_ps((float*)_VE_code); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ tmp1 = _mm_mul_ps(bb_signal_sample,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+ tmp2 = _mm_mul_ps(bb_signal_sample_shuffled,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+ z_VE = _mm_add_ps(z_VE, z); // Add the complex multiplication results together
+
+ // Early
+ y = _mm_loadu_ps((float*)_E_code); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ tmp1 = _mm_mul_ps(bb_signal_sample,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+ tmp2 = _mm_mul_ps(bb_signal_sample_shuffled,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+ z_E = _mm_add_ps(z_E, z); // Add the complex multiplication results together
+
+ // Prompt
+ y = _mm_loadu_ps((float*)_P_code); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ tmp1 = _mm_mul_ps(bb_signal_sample,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+ tmp2 = _mm_mul_ps(bb_signal_sample_shuffled,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+ z_P = _mm_add_ps(z_P, z); // Add the complex multiplication results together
+
+ // Late
+ y = _mm_loadu_ps((float*)_L_code); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ tmp1 = _mm_mul_ps(bb_signal_sample,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+ tmp2 = _mm_mul_ps(bb_signal_sample_shuffled,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+ z_L = _mm_add_ps(z_L, z); // Add the complex multiplication results together
+
+ // VL
+ //x = _mm_load_ps((float*)_input_BB); // Load the ar + ai, br + bi as ar,ai,br,bi
+ y = _mm_loadu_ps((float*)_VL_code); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ tmp1 = _mm_mul_ps(bb_signal_sample,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+ tmp2 = _mm_mul_ps(bb_signal_sample_shuffled,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+ z_VL = _mm_add_ps(z_VL, z); // Add the complex multiplication results together
+
+ /*pointer increment*/
+ _carrier += 2;
+ _input += 2;
+ _VE_code += 2;
+ _E_code += 2;
+ _P_code += 2;
+ _L_code +=2;
+ _VL_code +=2;
+ }
+
+ __VOLK_ATTR_ALIGNED(16) lv_32fc_t dotProductVector_VE[2];
+ __VOLK_ATTR_ALIGNED(16) lv_32fc_t dotProductVector_E[2];
+ __VOLK_ATTR_ALIGNED(16) lv_32fc_t dotProductVector_P[2];
+ __VOLK_ATTR_ALIGNED(16) lv_32fc_t dotProductVector_L[2];
+ __VOLK_ATTR_ALIGNED(16) lv_32fc_t dotProductVector_VL[2];
+
+ _mm_storeu_ps((float*)dotProductVector_VE,z_VE); // Store the results back into the dot product vector
+ _mm_storeu_ps((float*)dotProductVector_E,z_E); // Store the results back into the dot product vector
+ _mm_storeu_ps((float*)dotProductVector_P,z_P); // Store the results back into the dot product vector
+ _mm_storeu_ps((float*)dotProductVector_L,z_L); // Store the results back into the dot product vector
+ _mm_storeu_ps((float*)dotProductVector_VL,z_VL); // Store the results back into the dot product vector
+
+ dotProduct_VE += ( dotProductVector_VE[0] + dotProductVector_VE[1] );
+ dotProduct_E += ( dotProductVector_E[0] + dotProductVector_E[1] );
+ dotProduct_P += ( dotProductVector_P[0] + dotProductVector_P[1] );
+ dotProduct_L += ( dotProductVector_L[0] + dotProductVector_L[1] );
+ dotProduct_VL += ( dotProductVector_VL[0] + dotProductVector_VL[1] );
+
+ if((num_points % 2) != 0)
+ {
+ dotProduct_VE += (*_input) * (*_VE_code)*(*_carrier);
+ dotProduct_E += (*_input) * (*_E_code)*(*_carrier);
+ dotProduct_P += (*_input) * (*_P_code)*(*_carrier);
+ dotProduct_L += (*_input) * (*_L_code)*(*_carrier);
+ dotProduct_VL += (*_input) * (*_VL_code)*(*_carrier);
+ }
+
+ *VE_out = dotProduct_VE;
+ *E_out = dotProduct_E;
+ *P_out = dotProduct_P;
+ *L_out = dotProduct_L;
+ *VL_out = dotProduct_VL;
+}
+
+#endif /* LV_HAVE_SSE3 */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Performs the carrier wipe-off mixing and the VE, Early, Prompt, Late and VL correlation
+ \param input The input signal input
+ \param carrier The carrier signal input
+ \param VE_code VE PRN code replica input
+ \param E_code Early PRN code replica input
+ \param P_code Early PRN code replica input
+ \param L_code Early PRN code replica input
+ \param VL_code VL PRN code replica input
+ \param VE_out VE correlation output
+ \param E_out Early correlation output
+ \param P_out Early correlation output
+ \param L_out Early correlation output
+ \param VL_out VL correlation output
+ \param num_points The number of complex values in vectors
+ */
+static inline void volk_gnsssdr_32fc_x7_cw_vepl_corr_32fc_x5_generic(lv_32fc_t* VE_out, lv_32fc_t* E_out, lv_32fc_t* P_out, lv_32fc_t* L_out, lv_32fc_t* VL_out, const lv_32fc_t* input, const lv_32fc_t* carrier, const lv_32fc_t* VE_code, const lv_32fc_t* E_code, const lv_32fc_t* P_code, const lv_32fc_t* L_code, const lv_32fc_t* VL_code, unsigned int num_points)
+{
+ lv_32fc_t bb_signal_sample;
+
+ bb_signal_sample = lv_cmake(0, 0);
+
+ *VE_out = 0;
+ *E_out = 0;
+ *P_out = 0;
+ *L_out = 0;
+ *VL_out = 0;
+ // perform Early, Prompt and Late correlation
+ for(int i=0; i < num_points; ++i)
+ {
+ //Perform the carrier wipe-off
+ bb_signal_sample = input[i] * carrier[i];
+ // Now get early, late, and prompt values for each
+ *VE_out += bb_signal_sample * VE_code[i];
+ *E_out += bb_signal_sample * E_code[i];
+ *P_out += bb_signal_sample * P_code[i];
+ *L_out += bb_signal_sample * L_code[i];
+ *VL_out += bb_signal_sample * VL_code[i];
+ }
+}
+
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_gnsssdr_volk_gnsssdr_32fc_x7_cw_vepl_corr_32fc_x5_u_H */
+
+
+#ifndef INCLUDED_gnsssdr_volk_gnsssdr_32fc_x7_cw_vepl_corr_32fc_x5_a_H
+#define INCLUDED_gnsssdr_volk_gnsssdr_32fc_x7_cw_vepl_corr_32fc_x5_a_H
+
+#include
+#include
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE3
+#include
+/*!
+ \brief Performs the carrier wipe-off mixing and the VE, Early, Prompt, Late and VL correlation
+ \param input The input signal input
+ \param carrier The carrier signal input
+ \param VE_code VE PRN code replica input
+ \param E_code Early PRN code replica input
+ \param P_code Early PRN code replica input
+ \param L_code Early PRN code replica input
+ \param VL_code VL PRN code replica input
+ \param VE_out VE correlation output
+ \param E_out Early correlation output
+ \param P_out Early correlation output
+ \param L_out Early correlation output
+ \param VL_out VL correlation output
+ \param num_points The number of complex values in vectors
+ */
+static inline void volk_gnsssdr_32fc_x7_cw_vepl_corr_32fc_x5_a_sse3(lv_32fc_t* VE_out, lv_32fc_t* E_out, lv_32fc_t* P_out, lv_32fc_t* L_out, lv_32fc_t* VL_out, const lv_32fc_t* input, const lv_32fc_t* carrier, const lv_32fc_t* VE_code, const lv_32fc_t* E_code, const lv_32fc_t* P_code, const lv_32fc_t* L_code, const lv_32fc_t* VL_code, unsigned int num_points)
+{
+ unsigned int number = 0;
+ const unsigned int halfPoints = num_points / 2;
+
+ lv_32fc_t dotProduct_VE;
+ memset(&dotProduct_VE, 0x0, 2*sizeof(float));
+ lv_32fc_t dotProduct_E;
+ memset(&dotProduct_E, 0x0, 2*sizeof(float));
+ lv_32fc_t dotProduct_P;
+ memset(&dotProduct_P, 0x0, 2*sizeof(float));
+ lv_32fc_t dotProduct_L;
+ memset(&dotProduct_L, 0x0, 2*sizeof(float));
+ lv_32fc_t dotProduct_VL;
+ memset(&dotProduct_VL, 0x0, 2*sizeof(float));
+
+ // Aux vars
+ __m128 x, y, yl, yh, z, tmp1, tmp2, z_VE, z_E, z_P, z_L, z_VL;
+ __m128 bb_signal_sample, bb_signal_sample_shuffled;
+
+ z_VE = _mm_setzero_ps();
+ z_E = _mm_setzero_ps();
+ z_P = _mm_setzero_ps();
+ z_L = _mm_setzero_ps();
+ z_VL = _mm_setzero_ps();
+
+ //input and output vectors
+ const lv_32fc_t* _input = input;
+ const lv_32fc_t* _carrier = carrier;
+ const lv_32fc_t* _VE_code = VE_code;
+ const lv_32fc_t* _E_code = E_code;
+ const lv_32fc_t* _P_code = P_code;
+ const lv_32fc_t* _L_code = L_code;
+ const lv_32fc_t* _VL_code = VL_code;
+
+ for(;number < halfPoints; number++)
+ {
+ // carrier wipe-off (vector point-to-point product)
+ x = _mm_load_ps((float*)_input); // Load the ar + ai, br + bi as ar,ai,br,bi
+ y = _mm_load_ps((float*)_carrier); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ tmp1 = _mm_mul_ps(x,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+
+ x = _mm_shuffle_ps(x,x,0xB1); // Re-arrange x to be ai,ar,bi,br
+
+ tmp2 = _mm_mul_ps(x,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ bb_signal_sample = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+ bb_signal_sample_shuffled = _mm_shuffle_ps(bb_signal_sample,bb_signal_sample,0xB1); // Re-arrange bb_signal_sample to be ai,ar,bi,br
+
+ // correlation VE,E,P,L,VL (5x vector scalar product)
+ // VE
+ y = _mm_load_ps((float*)_VE_code); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ tmp1 = _mm_mul_ps(bb_signal_sample,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+ tmp2 = _mm_mul_ps(bb_signal_sample_shuffled,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+ z_VE = _mm_add_ps(z_VE, z); // Add the complex multiplication results together
+
+ // Early
+ y = _mm_load_ps((float*)_E_code); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ tmp1 = _mm_mul_ps(bb_signal_sample,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+ tmp2 = _mm_mul_ps(bb_signal_sample_shuffled,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+ z_E = _mm_add_ps(z_E, z); // Add the complex multiplication results together
+
+ // Prompt
+ y = _mm_load_ps((float*)_P_code); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ tmp1 = _mm_mul_ps(bb_signal_sample,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+ tmp2 = _mm_mul_ps(bb_signal_sample_shuffled,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+ z_P = _mm_add_ps(z_P, z); // Add the complex multiplication results together
+
+ // Late
+ y = _mm_load_ps((float*)_L_code); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ tmp1 = _mm_mul_ps(bb_signal_sample,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+ tmp2 = _mm_mul_ps(bb_signal_sample_shuffled,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+ z_L = _mm_add_ps(z_L, z); // Add the complex multiplication results together
+
+ // VL
+ //x = _mm_load_ps((float*)_input_BB); // Load the ar + ai, br + bi as ar,ai,br,bi
+ y = _mm_load_ps((float*)_VL_code); // Load the cr + ci, dr + di as cr,ci,dr,di
+
+ yl = _mm_moveldup_ps(y); // Load yl with cr,cr,dr,dr
+ yh = _mm_movehdup_ps(y); // Load yh with ci,ci,di,di
+
+ tmp1 = _mm_mul_ps(bb_signal_sample,yl); // tmp1 = ar*cr,ai*cr,br*dr,bi*dr
+ tmp2 = _mm_mul_ps(bb_signal_sample_shuffled,yh); // tmp2 = ai*ci,ar*ci,bi*di,br*di
+
+ z = _mm_addsub_ps(tmp1,tmp2); // ar*cr-ai*ci, ai*cr+ar*ci, br*dr-bi*di, bi*dr+br*di
+ z_VL = _mm_add_ps(z_VL, z); // Add the complex multiplication results together
+
+ /*pointer increment*/
+ _carrier += 2;
+ _input += 2;
+ _VE_code += 2;
+ _E_code += 2;
+ _P_code += 2;
+ _L_code +=2;
+ _VL_code +=2;
+ }
+
+ __VOLK_ATTR_ALIGNED(16) lv_32fc_t dotProductVector_VE[2];
+ __VOLK_ATTR_ALIGNED(16) lv_32fc_t dotProductVector_E[2];
+ __VOLK_ATTR_ALIGNED(16) lv_32fc_t dotProductVector_P[2];
+ __VOLK_ATTR_ALIGNED(16) lv_32fc_t dotProductVector_L[2];
+ __VOLK_ATTR_ALIGNED(16) lv_32fc_t dotProductVector_VL[2];
+
+ _mm_store_ps((float*)dotProductVector_VE,z_VE); // Store the results back into the dot product vector
+ _mm_store_ps((float*)dotProductVector_E,z_E); // Store the results back into the dot product vector
+ _mm_store_ps((float*)dotProductVector_P,z_P); // Store the results back into the dot product vector
+ _mm_store_ps((float*)dotProductVector_L,z_L); // Store the results back into the dot product vector
+ _mm_store_ps((float*)dotProductVector_VL,z_VL); // Store the results back into the dot product vector
+
+ dotProduct_VE += ( dotProductVector_VE[0] + dotProductVector_VE[1] );
+ dotProduct_E += ( dotProductVector_E[0] + dotProductVector_E[1] );
+ dotProduct_P += ( dotProductVector_P[0] + dotProductVector_P[1] );
+ dotProduct_L += ( dotProductVector_L[0] + dotProductVector_L[1] );
+ dotProduct_VL += ( dotProductVector_VL[0] + dotProductVector_VL[1] );
+
+ if((num_points % 2) != 0)
+ {
+ dotProduct_VE += (*_input) * (*_VE_code)*(*_carrier);
+ dotProduct_E += (*_input) * (*_E_code)*(*_carrier);
+ dotProduct_P += (*_input) * (*_P_code)*(*_carrier);
+ dotProduct_L += (*_input) * (*_L_code)*(*_carrier);
+ dotProduct_VL += (*_input) * (*_VL_code)*(*_carrier);
+ }
+
+ *VE_out = dotProduct_VE;
+ *E_out = dotProduct_E;
+ *P_out = dotProduct_P;
+ *L_out = dotProduct_L;
+ *VL_out = dotProduct_VL;
+
+}
+
+#endif /* LV_HAVE_SSE3 */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Performs the carrier wipe-off mixing and the VE, Early, Prompt, Late and VL correlation
+ \param input The input signal input
+ \param carrier The carrier signal input
+ \param VE_code VE PRN code replica input
+ \param E_code Early PRN code replica input
+ \param P_code Early PRN code replica input
+ \param L_code Early PRN code replica input
+ \param VL_code VL PRN code replica input
+ \param VE_out VE correlation output
+ \param E_out Early correlation output
+ \param P_out Early correlation output
+ \param L_out Early correlation output
+ \param VL_out VL correlation output
+ \param num_points The number of complex values in vectors
+ */
+static inline void volk_gnsssdr_32fc_x7_cw_vepl_corr_32fc_x5_a_generic(lv_32fc_t* VE_out, lv_32fc_t* E_out, lv_32fc_t* P_out, lv_32fc_t* L_out, lv_32fc_t* VL_out, const lv_32fc_t* input, const lv_32fc_t* carrier, const lv_32fc_t* VE_code, const lv_32fc_t* E_code, const lv_32fc_t* P_code, const lv_32fc_t* L_code, const lv_32fc_t* VL_code, unsigned int num_points)
+{
+ lv_32fc_t bb_signal_sample;
+
+ bb_signal_sample = lv_cmake(0, 0);
+
+ *VE_out = 0;
+ *E_out = 0;
+ *P_out = 0;
+ *L_out = 0;
+ *VL_out = 0;
+ // perform Early, Prompt and Late correlation
+ for(int i=0; i < num_points; ++i)
+ {
+ //Perform the carrier wipe-off
+ bb_signal_sample = input[i] * carrier[i];
+ // Now get early, late, and prompt values for each
+ *VE_out += bb_signal_sample * VE_code[i];
+ *E_out += bb_signal_sample * E_code[i];
+ *P_out += bb_signal_sample * P_code[i];
+ *L_out += bb_signal_sample * L_code[i];
+ *VL_out += bb_signal_sample * VL_code[i];
+ }
+}
+
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_gnsssdr_volk_gnsssdr_32fc_x7_cw_vepl_corr_32fc_x5_a_H */
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8i_accumulator_s8i.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8i_accumulator_s8i.h
new file mode 100644
index 000000000..c9079b652
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8i_accumulator_s8i.h
@@ -0,0 +1,183 @@
+/*!
+ * \file volk_gnsssdr_8i_accumulator_s8i.h
+ * \brief Volk protokernel: 8 bits (char) scalar accumulator
+ * \authors
+ * - Andrés Cecilia, 2014. a.cecilia.luque(at)gmail.com
+ *
+ *
+ * Volk protokernel that implements an accumulator of char values
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#ifndef INCLUDED_volk_gnsssdr_8i_accumulator_s8i_u_H
+#define INCLUDED_volk_gnsssdr_8i_accumulator_s8i_u_H
+
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE3
+#include
+/*!
+ \brief Accumulates the values in the input buffer
+ \param result The accumulated result
+ \param inputBuffer The buffer of data to be accumulated
+ \param num_points The number of values in inputBuffer to be accumulated
+ */
+static inline void volk_gnsssdr_8i_accumulator_s8i_u_sse3(char* result, const char* inputBuffer, unsigned int num_points){
+ char returnValue = 0;
+ const unsigned int sse_iters = num_points / 16;
+
+ const char* aPtr = inputBuffer;
+
+ __VOLK_ATTR_ALIGNED(16) char tempBuffer[16];
+ __m128i accumulator = _mm_setzero_si128();
+ __m128i aVal = _mm_setzero_si128();
+
+ for(unsigned int number = 0; number < sse_iters; number++){
+ aVal = _mm_lddqu_si128((__m128i*)aPtr);
+ accumulator = _mm_add_epi8(accumulator, aVal);
+ aPtr += 16;
+ }
+ _mm_storeu_si128((__m128i*)tempBuffer,accumulator);
+
+ for(int i = 0; i<16; ++i){
+ returnValue += tempBuffer[i];
+ }
+
+ for(int i = 0; i<(num_points % 16); ++i){
+ returnValue += (*aPtr++);
+ }
+
+ *result = returnValue;
+}
+#endif /* LV_HAVE_SSE3 */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Accumulates the values in the input buffer
+ \param result The accumulated result
+ \param inputBuffer The buffer of data to be accumulated
+ \param num_points The number of values in inputBuffer to be accumulated
+ */
+static inline void volk_gnsssdr_8i_accumulator_s8i_generic(char* result, const char* inputBuffer, unsigned int num_points){
+ const char* aPtr = inputBuffer;
+ char returnValue = 0;
+
+ for(unsigned int number = 0;number < num_points; number++){
+ returnValue += (*aPtr++);
+ }
+ *result = returnValue;
+}
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_volk_gnsssdr_8i_accumulator_s8i_u_H */
+
+
+#ifndef INCLUDED_volk_gnsssdr_8i_accumulator_s8i_a_H
+#define INCLUDED_volk_gnsssdr_8i_accumulator_s8i_a_H
+
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE3
+#include
+/*!
+ \brief Accumulates the values in the input buffer
+ \param result The accumulated result
+ \param inputBuffer The buffer of data to be accumulated
+ \param num_points The number of values in inputBuffer to be accumulated
+ */
+static inline void volk_gnsssdr_8i_accumulator_s8i_a_sse3(char* result, const char* inputBuffer, unsigned int num_points){
+ char returnValue = 0;
+ const unsigned int sse_iters = num_points / 16;
+
+ const char* aPtr = inputBuffer;
+
+ __VOLK_ATTR_ALIGNED(16) char tempBuffer[16];
+ __m128i accumulator = _mm_setzero_si128();
+ __m128i aVal = _mm_setzero_si128();
+
+ for(unsigned int number = 0; number < sse_iters; number++){
+ aVal = _mm_load_si128((__m128i*)aPtr);
+ accumulator = _mm_add_epi8(accumulator, aVal);
+ aPtr += 16;
+ }
+ _mm_store_si128((__m128i*)tempBuffer,accumulator);
+
+ for(int i = 0; i<16; ++i){
+ returnValue += tempBuffer[i];
+ }
+
+ for(int i = 0; i<(num_points % 16); ++i){
+ returnValue += (*aPtr++);
+ }
+
+ *result = returnValue;
+}
+#endif /* LV_HAVE_SSE3 */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Accumulates the values in the input buffer
+ \param result The accumulated result
+ \param inputBuffer The buffer of data to be accumulated
+ \param num_points The number of values in inputBuffer to be accumulated
+ */
+static inline void volk_gnsssdr_8i_accumulator_s8i_a_generic(char* result, const char* inputBuffer, unsigned int num_points){
+ const char* aPtr = inputBuffer;
+ char returnValue = 0;
+
+ for(unsigned int number = 0;number < num_points; number++){
+ returnValue += (*aPtr++);
+ }
+ *result = returnValue;
+}
+#endif /* LV_HAVE_GENERIC */
+
+#ifdef LV_HAVE_ORC
+/*!
+ \brief Accumulates the values in the input buffer
+ \param result The accumulated result
+ \param inputBuffer The buffer of data to be accumulated
+ \param num_points The number of values in inputBuffer to be accumulated
+ */
+extern void volk_gnsssdr_8i_accumulator_s8i_a_orc_impl(short* result, const char* inputBuffer, unsigned int num_points);
+static inline void volk_gnsssdr_8i_accumulator_s8i_u_orc(char* result, const char* inputBuffer, unsigned int num_points){
+
+ short res = 0;
+ char* resc = (char*)&res;
+ resc++;
+
+ volk_gnsssdr_8i_accumulator_s8i_a_orc_impl(&res, inputBuffer, num_points);
+
+ *result = *resc;
+}
+#endif /* LV_HAVE_ORC */
+
+#endif /* INCLUDED_volk_gnsssdr_8i_accumulator_s8i_a_H */
+
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8i_index_max_16u.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8i_index_max_16u.h
new file mode 100644
index 000000000..0bb85a1dc
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8i_index_max_16u.h
@@ -0,0 +1,493 @@
+/*!
+ * \file volk_gnsssdr_8i_index_max_16u.h
+ * \brief Volk protokernel: calculates the index of the maximum value in a group of 8 bits (char) scalars
+ * \authors
+ * - Andrés Cecilia, 2014. a.cecilia.luque(at)gmail.com
+ *
+ *
+ * Volk protokernel that returns the index of the maximum value of a group of 8 bits (char) scalars
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#ifndef INCLUDED_volk_gnsssdr_8i_index_max_16u_u_H
+#define INCLUDED_volk_gnsssdr_8i_index_max_16u_u_H
+
+#include
+#include
+#include
+
+#ifdef LV_HAVE_AVX
+#include "immintrin.h"
+/*!
+ \brief Returns the index of the max value in src0
+ \param target The index of the max value in src0
+ \param src0 The buffer of data to be analysed
+ \param num_points The number of values in src0 to be analysed
+ */
+static inline void volk_gnsssdr_8i_index_max_16u_u_avx(unsigned int* target, const char* src0, unsigned int num_points) {
+ if(num_points > 0){
+ const unsigned int sse_iters = num_points / 32;
+
+ char* basePtr = (char*)src0;
+ char* inputPtr = (char*)src0;
+ char max = src0[0];
+ unsigned int index = 0;
+ __VOLK_ATTR_ALIGNED(32) char currentValuesBuffer[32];
+ __m256i ones, compareResults, currentValues;
+ __m128i compareResultslo, compareResultshi, maxValues, lo, hi;
+
+ ones = _mm256_set1_epi8(0xFF);
+ maxValues = _mm_set1_epi8(max);
+
+ for(unsigned int number = 0; number < sse_iters; number++)
+ {
+ currentValues = _mm256_lddqu_si256((__m256i*)inputPtr);
+
+ lo = _mm256_castsi256_si128(currentValues);
+ hi = _mm256_extractf128_si256(currentValues,1);
+
+ compareResultslo = _mm_cmpgt_epi8(maxValues, lo);
+ compareResultshi = _mm_cmpgt_epi8(maxValues, hi);
+
+ //compareResults = _mm256_set_m128i(compareResultshi , compareResultslo); //not defined in some versions of immintrin.h
+ compareResults = _mm256_insertf128_si256(_mm256_castsi128_si256(compareResultslo),(compareResultshi),1);
+
+ if (!_mm256_testc_si256(compareResults, ones))
+ {
+ _mm256_storeu_si256((__m256i*)¤tValuesBuffer, currentValues);
+
+ for(int i = 0; i < 32; i++)
+ {
+ if(currentValuesBuffer[i] > max)
+ {
+ index = inputPtr - basePtr + i;
+ max = currentValuesBuffer[i];
+ }
+ }
+ maxValues = _mm_set1_epi8(max);
+ }
+
+ inputPtr += 32;
+ }
+
+ for(int i = 0; i<(num_points % 32); ++i)
+ {
+ if(src0[i] > max)
+ {
+ index = i;
+ max = src0[i];
+ }
+ }
+ target[0] = index;
+ }
+}
+
+#endif /*LV_HAVE_AVX*/
+
+#ifdef LV_HAVE_SSE4_1
+#include
+/*!
+ \brief Returns the index of the max value in src0
+ \param target The index of the max value in src0
+ \param src0 The buffer of data to be analysed
+ \param num_points The number of values in src0 to be analysed
+ */
+static inline void volk_gnsssdr_8i_index_max_16u_u_sse4_1(unsigned int* target, const char* src0, unsigned int num_points) {
+ if(num_points > 0){
+ const unsigned int sse_iters = num_points / 16;
+
+ char* basePtr = (char*)src0;
+ char* inputPtr = (char*)src0;
+ char max = src0[0];
+ unsigned int index = 0;
+ __VOLK_ATTR_ALIGNED(16) char currentValuesBuffer[16];
+ __m128i maxValues, compareResults, currentValues;
+
+ maxValues = _mm_set1_epi8(max);
+
+ for(unsigned int number = 0; number < sse_iters; number++)
+ {
+ currentValues = _mm_lddqu_si128((__m128i*)inputPtr);
+
+ compareResults = _mm_cmpgt_epi8(maxValues, currentValues);
+
+ if (!_mm_test_all_ones(compareResults))
+ {
+ _mm_storeu_si128((__m128i*)¤tValuesBuffer, currentValues);
+
+ for(int i = 0; i < 16; i++)
+ {
+ if(currentValuesBuffer[i] > max)
+ {
+ index = inputPtr - basePtr + i;
+ max = currentValuesBuffer[i];
+ }
+ }
+ maxValues = _mm_set1_epi8(max);
+ }
+
+ inputPtr += 16;
+ }
+
+ for(int i = 0; i<(num_points % 16); ++i)
+ {
+ if(src0[i] > max)
+ {
+ index = i;
+ max = src0[i];
+ }
+ }
+ target[0] = index;
+ }
+}
+
+#endif /*LV_HAVE_SSE4_1*/
+
+#ifdef LV_HAVE_SSE2
+#include
+/*!
+ \brief Returns the index of the max value in src0
+ \param target The index of the max value in src0
+ \param src0 The buffer of data to be analysed
+ \param num_points The number of values in src0 to be analysed
+ */
+static inline void volk_gnsssdr_8i_index_max_16u_u_sse2(unsigned int* target, const char* src0, unsigned int num_points) {
+ if(num_points > 0){
+ const unsigned int sse_iters = num_points / 16;
+
+ char* basePtr = (char*)src0;
+ char* inputPtr = (char*)src0;
+ char max = src0[0];
+ unsigned int index = 0;
+ unsigned short mask;
+ __VOLK_ATTR_ALIGNED(16) char currentValuesBuffer[16];
+ __m128i maxValues, compareResults, currentValues;
+
+ maxValues = _mm_set1_epi8(max);
+
+ for(unsigned int number = 0; number < sse_iters; number++)
+ {
+ currentValues = _mm_loadu_si128((__m128i*)inputPtr);
+ compareResults = _mm_cmpgt_epi8(maxValues, currentValues);
+ mask = _mm_movemask_epi8(compareResults);
+
+ if (mask != 0xFFFF)
+ {
+ _mm_storeu_si128((__m128i*)¤tValuesBuffer, currentValues);
+ mask = ~mask;
+ int i = 0;
+ while (mask > 0)
+ {
+ if ((mask & 1) == 1)
+ {
+ if(currentValuesBuffer[i] > max)
+ {
+ index = inputPtr - basePtr + i;
+ max = currentValuesBuffer[i];
+ }
+ }
+ i++;
+ mask >>= 1;
+ }
+ maxValues = _mm_set1_epi8(max);
+ }
+ inputPtr += 16;
+ }
+
+ for(int i = 0; i<(num_points % 16); ++i)
+ {
+ if(src0[i] > max)
+ {
+ index = i;
+ max = src0[i];
+ }
+ }
+ target[0] = index;
+ }
+}
+
+#endif /*LV_HAVE_SSE2*/
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Returns the index of the max value in src0
+ \param target The index of the max value in src0
+ \param src0 The buffer of data to be analysed
+ \param num_points The number of values in src0 to be analysed
+ */
+static inline void volk_gnsssdr_8i_index_max_16u_generic(unsigned int* target, const char* src0, unsigned int num_points) {
+
+ if(num_points > 0)
+ {
+ char max = src0[0];
+ unsigned int index = 0;
+
+ for(unsigned int i = 1; i < num_points; ++i)
+ {
+ if(src0[i] > max)
+ {
+ index = i;
+ max = src0[i];
+ }
+ }
+ target[0] = index;
+ }
+}
+
+#endif /*LV_HAVE_GENERIC*/
+
+#endif /*INCLUDED_volk_gnsssdr_8i_index_max_16u_u_H*/
+
+
+#ifndef INCLUDED_volk_gnsssdr_8i_index_max_16u_a_H
+#define INCLUDED_volk_gnsssdr_8i_index_max_16u_a_H
+
+#include
+#include
+#include
+
+#ifdef LV_HAVE_AVX
+#include "immintrin.h"
+/*!
+ \brief Returns the index of the max value in src0
+ \param target The index of the max value in src0
+ \param src0 The buffer of data to be analysed
+ \param num_points The number of values in src0 to be analysed
+ */
+static inline void volk_gnsssdr_8i_index_max_16u_a_avx(unsigned int* target, const char* src0, unsigned int num_points) {
+ if(num_points > 0){
+ const unsigned int sse_iters = num_points / 32;
+
+ char* basePtr = (char*)src0;
+ char* inputPtr = (char*)src0;
+ char max = src0[0];
+ unsigned int index = 0;
+ __VOLK_ATTR_ALIGNED(32) char currentValuesBuffer[32];
+ __m256i ones, compareResults, currentValues;
+ __m128i compareResultslo, compareResultshi, maxValues, lo, hi;
+
+ ones = _mm256_set1_epi8(0xFF);
+ maxValues = _mm_set1_epi8(max);
+
+ for(unsigned int number = 0; number < sse_iters; number++)
+ {
+ currentValues = _mm256_load_si256((__m256i*)inputPtr);
+
+ lo = _mm256_castsi256_si128(currentValues);
+ hi = _mm256_extractf128_si256(currentValues,1);
+
+ compareResultslo = _mm_cmpgt_epi8(maxValues, lo);
+ compareResultshi = _mm_cmpgt_epi8(maxValues, hi);
+
+ //compareResults = _mm256_set_m128i(compareResultshi , compareResultslo); //not defined in some versions of immintrin.h
+ compareResults = _mm256_insertf128_si256(_mm256_castsi128_si256(compareResultslo),(compareResultshi),1);
+
+ if (!_mm256_testc_si256(compareResults, ones))
+ {
+ _mm256_store_si256((__m256i*)¤tValuesBuffer, currentValues);
+
+ for(int i = 0; i < 32; i++)
+ {
+ if(currentValuesBuffer[i] > max)
+ {
+ index = inputPtr - basePtr + i;
+ max = currentValuesBuffer[i];
+ }
+ }
+ maxValues = _mm_set1_epi8(max);
+ }
+
+ inputPtr += 32;
+ }
+
+ for(int i = 0; i<(num_points % 32); ++i)
+ {
+ if(src0[i] > max)
+ {
+ index = i;
+ max = src0[i];
+ }
+ }
+ target[0] = index;
+ }
+}
+
+#endif /*LV_HAVE_AVX*/
+
+#ifdef LV_HAVE_SSE4_1
+#include "smmintrin.h"
+#include "emmintrin.h"
+/*!
+ \brief Returns the index of the max value in src0
+ \param target The index of the max value in src0
+ \param src0 The buffer of data to be analysed
+ \param num_points The number of values in src0 to be analysed
+ */
+static inline void volk_gnsssdr_8i_index_max_16u_a_sse4_1(unsigned int* target, const char* src0, unsigned int num_points) {
+ if(num_points > 0){
+ const unsigned int sse_iters = num_points / 16;
+
+ char* basePtr = (char*)src0;
+ char* inputPtr = (char*)src0;
+ char max = src0[0];
+ unsigned int index = 0;
+ __VOLK_ATTR_ALIGNED(16) char currentValuesBuffer[16];
+ __m128i maxValues, compareResults, currentValues;
+
+ maxValues = _mm_set1_epi8(max);
+
+ for(unsigned int number = 0; number < sse_iters; number++)
+ {
+ currentValues = _mm_load_si128((__m128i*)inputPtr);
+
+ compareResults = _mm_cmpgt_epi8(maxValues, currentValues);
+
+ if (!_mm_test_all_ones(compareResults))
+ {
+ _mm_store_si128((__m128i*)¤tValuesBuffer, currentValues);
+
+ for(int i = 0; i < 16; i++)
+ {
+ if(currentValuesBuffer[i] > max)
+ {
+ index = inputPtr - basePtr + i;
+ max = currentValuesBuffer[i];
+ }
+ }
+ maxValues = _mm_set1_epi8(max);
+ }
+
+ inputPtr += 16;
+ }
+
+ for(int i = 0; i<(num_points % 16); ++i)
+ {
+ if(src0[i] > max)
+ {
+ index = i;
+ max = src0[i];
+ }
+ }
+ target[0] = index;
+ }
+}
+
+#endif /*LV_HAVE_SSE4_1*/
+
+#ifdef LV_HAVE_SSE2
+#include "emmintrin.h"
+/*!
+ \brief Returns the index of the max value in src0
+ \param target The index of the max value in src0
+ \param src0 The buffer of data to be analysed
+ \param num_points The number of values in src0 to be analysed
+ */
+static inline void volk_gnsssdr_8i_index_max_16u_a_sse2(unsigned int* target, const char* src0, unsigned int num_points) {
+ if(num_points > 0){
+ const unsigned int sse_iters = num_points / 16;
+
+ char* basePtr = (char*)src0;
+ char* inputPtr = (char*)src0;
+ char max = src0[0];
+ unsigned int index = 0;
+ unsigned short mask;
+ __VOLK_ATTR_ALIGNED(16) char currentValuesBuffer[16];
+ __m128i maxValues, compareResults, currentValues;
+
+ maxValues = _mm_set1_epi8(max);
+
+ for(unsigned int number = 0; number < sse_iters; number++)
+ {
+ currentValues = _mm_load_si128((__m128i*)inputPtr);
+ compareResults = _mm_cmpgt_epi8(maxValues, currentValues);
+ mask = _mm_movemask_epi8(compareResults);
+
+ if (mask != 0xFFFF)
+ {
+ _mm_store_si128((__m128i*)¤tValuesBuffer, currentValues);
+ mask = ~mask;
+ int i = 0;
+ while (mask > 0)
+ {
+ if ((mask & 1) == 1)
+ {
+ if(currentValuesBuffer[i] > max)
+ {
+ index = inputPtr - basePtr + i;
+ max = currentValuesBuffer[i];
+ }
+ }
+ i++;
+ mask >>= 1;
+ }
+ maxValues = _mm_set1_epi8(max);
+ }
+ inputPtr += 16;
+ }
+
+ for(int i = 0; i<(num_points % 16); ++i)
+ {
+ if(src0[i] > max)
+ {
+ index = i;
+ max = src0[i];
+ }
+ }
+ target[0] = index;
+ }
+}
+
+#endif /*LV_HAVE_SSE2*/
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Returns the index of the max value in src0
+ \param target The index of the max value in src0
+ \param src0 The buffer of data to be analysed
+ \param num_points The number of values in src0 to be analysed
+ */
+static inline void volk_gnsssdr_8i_index_max_16u_a_generic(unsigned int* target, const char* src0, unsigned int num_points) {
+
+ if(num_points > 0)
+ {
+ char max = src0[0];
+ unsigned int index = 0;
+
+ for(unsigned int i = 1; i < num_points; ++i)
+ {
+ if(src0[i] > max)
+ {
+ index = i;
+ max = src0[i];
+ }
+ }
+ target[0] = index;
+ }
+}
+
+#endif /*LV_HAVE_GENERIC*/
+
+#endif /*INCLUDED_volk_gnsssdr_8i_index_max_16u_a_H*/
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8i_max_s8i.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8i_max_s8i.h
new file mode 100644
index 000000000..ef362fd57
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8i_max_s8i.h
@@ -0,0 +1,327 @@
+/*!
+ * \file volk_gnsssdr_8i_max_s8i.h
+ * \brief Volk protokernel: calculates the maximum value in a group of 8 bits (char) scalars
+ * \authors
+ * - Andrés Cecilia, 2014. a.cecilia.luque(at)gmail.com
+ *
+ *
+ * Volk protokernel that returns the maximum value of a group of 8 bits (char) scalars
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#ifndef INCLUDED_volk_gnsssdr_8i_max_s8i_u_H
+#define INCLUDED_volk_gnsssdr_8i_max_s8i_u_H
+
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE4_1
+#include
+/*!
+ \brief Returns the max value in src0
+ \param target The max value in src0
+ \param src0 The buffer of data to be analysed
+ \param num_points The number of values in src0 to be analysed
+ */
+static inline void volk_gnsssdr_8i_max_s8i_u_sse4_1(char target, const char* src0, unsigned int num_points) {
+ if(num_points > 0){
+ const unsigned int sse_iters = num_points / 16;
+
+ char* inputPtr = (char*)src0;
+ char max = src0[0];
+ __VOLK_ATTR_ALIGNED(16) char maxValuesBuffer[16];
+ __m128i maxValues, compareResults, currentValues;
+
+ maxValues = _mm_set1_epi8(max);
+
+ for(unsigned int number = 0; number < sse_iters; number++)
+ {
+ currentValues = _mm_loadu_si128((__m128i*)inputPtr);
+ compareResults = _mm_cmpgt_epi8(maxValues, currentValues);
+ maxValues = _mm_blendv_epi8(currentValues, maxValues, compareResults);
+ inputPtr += 16;
+ }
+
+ _mm_storeu_si128((__m128i*)maxValuesBuffer, maxValues);
+
+ for(int i = 0; i<16; ++i)
+ {
+ if(maxValuesBuffer[i] > max)
+ {
+ max = maxValuesBuffer[i];
+ }
+ }
+
+ for(int i = 0; i<(num_points % 16); ++i)
+ {
+ if(src0[i] > max)
+ {
+ max = src0[i];
+ }
+ }
+ target = max;
+ }
+}
+
+#endif /*LV_HAVE_SSE4_1*/
+
+#ifdef LV_HAVE_SSE2
+#include
+/*!
+ \brief Returns the max value in src0
+ \param target The max value in src0
+ \param src0 The buffer of data to be analysed
+ \param num_points The number of values in src0 to be analysed
+ */
+static inline void volk_gnsssdr_8i_max_s8i_u_sse2(char target, const char* src0, unsigned int num_points) {
+ if(num_points > 0){
+ const unsigned int sse_iters = num_points / 16;
+
+ char* inputPtr = (char*)src0;
+ char max = src0[0];
+ unsigned short mask;
+ __VOLK_ATTR_ALIGNED(16) char currentValuesBuffer[16];
+ __m128i maxValues, compareResults, currentValues;
+
+ maxValues = _mm_set1_epi8(max);
+
+ for(unsigned int number = 0; number < sse_iters; number++)
+ {
+ currentValues = _mm_loadu_si128((__m128i*)inputPtr);
+ compareResults = _mm_cmpgt_epi8(maxValues, currentValues);
+ mask = _mm_movemask_epi8(compareResults);
+
+ if (mask != 0xFFFF)
+ {
+ _mm_storeu_si128((__m128i*)¤tValuesBuffer, currentValues);
+ mask = ~mask;
+ int i = 0;
+ while (mask > 0)
+ {
+ if ((mask & 1) == 1)
+ {
+ if(currentValuesBuffer[i] > max)
+ {
+ max = currentValuesBuffer[i];
+ }
+ }
+ i++;
+ mask >>= 1;
+ }
+ maxValues = _mm_set1_epi8(max);
+ }
+ inputPtr += 16;
+ }
+
+ for(int i = 0; i<(num_points % 16); ++i)
+ {
+ if(src0[i] > max)
+ {
+ max = src0[i];
+ }
+ }
+ target = max;
+ }
+}
+
+#endif /*LV_HAVE_SSE2*/
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Returns the max value in src0
+ \param target The max value in src0
+ \param src0 The buffer of data to be analysed
+ \param num_points The number of values in src0 to be analysed
+ */
+static inline void volk_gnsssdr_8i_max_s8i_generic(char target, const char* src0, unsigned int num_points) {
+ if(num_points > 0)
+ {
+ char max = src0[0];
+
+ for(unsigned int i = 1; i < num_points; ++i)
+ {
+ if(src0[i] > max)
+ {
+ max = src0[i];
+ }
+ }
+ target = max;
+ }
+}
+
+#endif /*LV_HAVE_GENERIC*/
+
+#endif /*INCLUDED_volk_gnsssdr_8i_max_s8i_u_H*/
+
+
+#ifndef INCLUDED_volk_gnsssdr_8i_max_s8i_a_H
+#define INCLUDED_volk_gnsssdr_8i_max_s8i_a_H
+
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE4_1
+#include "smmintrin.h"
+/*!
+ \brief Returns the max value in src0
+ \param target The max value in src0
+ \param src0 The buffer of data to be analysed
+ \param num_points The number of values in src0 to be analysed
+ */
+static inline void volk_gnsssdr_8i_max_s8i_a_sse4_1(char target, const char* src0, unsigned int num_points) {
+ if(num_points > 0){
+ const unsigned int sse_iters = num_points / 16;
+
+ char* inputPtr = (char*)src0;
+ char max = src0[0];
+ __VOLK_ATTR_ALIGNED(16) char maxValuesBuffer[16];
+ __m128i maxValues, compareResults, currentValues;
+
+ maxValues = _mm_set1_epi8(max);
+
+ for(unsigned int number = 0; number < sse_iters; number++)
+ {
+ currentValues = _mm_load_si128((__m128i*)inputPtr);
+ compareResults = _mm_cmpgt_epi8(maxValues, currentValues);
+ maxValues = _mm_blendv_epi8(currentValues, maxValues, compareResults);
+ inputPtr += 16;
+ }
+
+ _mm_store_si128((__m128i*)maxValuesBuffer, maxValues);
+
+ for(int i = 0; i<16; ++i)
+ {
+ if(maxValuesBuffer[i] > max)
+ {
+ max = maxValuesBuffer[i];
+ }
+ }
+
+ for(int i = 0; i<(num_points % 16); ++i)
+ {
+ if(src0[i] > max)
+ {
+ max = src0[i];
+ }
+ }
+ target = max;
+ }
+}
+
+#endif /*LV_HAVE_SSE4_1*/
+
+#ifdef LV_HAVE_SSE2
+#include "emmintrin.h"
+/*!
+ \brief Returns the max value in src0
+ \param target The max value in src0
+ \param src0 The buffer of data to be analysed
+ \param num_points The number of values in src0 to be analysed
+ */
+static inline void volk_gnsssdr_8i_max_s8i_a_sse2(char target, const char* src0, unsigned int num_points) {
+ if(num_points > 0){
+ const unsigned int sse_iters = num_points / 16;
+
+ char* inputPtr = (char*)src0;
+ char max = src0[0];
+ unsigned short mask;
+ __VOLK_ATTR_ALIGNED(16) char currentValuesBuffer[16];
+ __m128i maxValues, compareResults, currentValues;
+
+ maxValues = _mm_set1_epi8(max);
+
+ for(unsigned int number = 0; number < sse_iters; number++)
+ {
+ currentValues = _mm_load_si128((__m128i*)inputPtr);
+ compareResults = _mm_cmpgt_epi8(maxValues, currentValues);
+ mask = _mm_movemask_epi8(compareResults);
+
+ if (mask != 0xFFFF)
+ {
+ _mm_store_si128((__m128i*)¤tValuesBuffer, currentValues);
+ mask = ~mask;
+ int i = 0;
+ while (mask > 0)
+ {
+ if ((mask & 1) == 1)
+ {
+ if(currentValuesBuffer[i] > max)
+ {
+ max = currentValuesBuffer[i];
+ }
+ }
+ i++;
+ mask >>= 1;
+ }
+ maxValues = _mm_set1_epi8(max);
+ }
+ inputPtr += 16;
+ }
+
+ for(int i = 0; i<(num_points % 16); ++i)
+ {
+ if(src0[i] > max)
+ {
+ max = src0[i];
+ }
+ }
+ target = max;
+ }
+}
+
+#endif /*LV_HAVE_SSE2*/
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Returns the max value in src0
+ \param target The max value in src0
+ \param src0 The buffer of data to be analysed
+ \param num_points The number of values in src0 to be analysed
+ */
+static inline void volk_gnsssdr_8i_max_s8i_a_generic(char target, const char* src0, unsigned int num_points) {
+ if(num_points > 0)
+ {
+ if(num_points > 0)
+ {
+ char max = src0[0];
+
+ for(unsigned int i = 1; i < num_points; ++i)
+ {
+ if(src0[i] > max)
+ {
+ max = src0[i];
+ }
+ }
+ target = max;
+ }
+ }
+}
+
+#endif /*LV_HAVE_GENERIC*/
+
+#endif /*INCLUDED_volk_gnsssdr_8i_max_s8i_a_H*/
\ No newline at end of file
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8i_x2_add_8i.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8i_x2_add_8i.h
new file mode 100644
index 000000000..4a2bd5ab2
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8i_x2_add_8i.h
@@ -0,0 +1,184 @@
+/*!
+ * \file volk_gnsssdr_8i_x2_add_8i.h
+ * \brief Volk protokernel: adds pairs of 8 bits (char) scalars
+ * \authors
+ * - Andrés Cecilia, 2014. a.cecilia.luque(at)gmail.com
+ *
+ *
+ * Volk protokernel that adds pairs of 8 bits (char) scalars
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#ifndef INCLUDED_volk_gnsssdr_8i_x2_add_8i_u_H
+#define INCLUDED_volk_gnsssdr_8i_x2_add_8i_u_H
+
+#include
+#include
+
+#ifdef LV_HAVE_SSE2
+#include "pmmintrin.h"
+/*!
+ \brief Adds the two input vectors and store their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be added
+ \param bVector One of the vectors to be added
+ \param num_points The number of values in aVector and bVector to be added together and stored into cVector
+ */
+static inline void volk_gnsssdr_8i_x2_add_8i_u_sse2(char* cVector, const char* aVector, const char* bVector, unsigned int num_points){
+
+ const unsigned int sse_iters = num_points / 16;
+
+ char* cPtr = cVector;
+ const char* aPtr = aVector;
+ const char* bPtr= bVector;
+
+ __m128i aVal, bVal, cVal;
+
+ for(int number = 0; number < sse_iters; number++){
+
+ aVal = _mm_lddqu_si128((__m128i*)aPtr);
+ bVal = _mm_lddqu_si128((__m128i*)bPtr);
+
+ cVal = _mm_add_epi8(aVal, bVal);
+
+ _mm_storeu_si128((__m128i*)cPtr,cVal); // Store the results back into the C container
+
+ aPtr += 16;
+ bPtr += 16;
+ cPtr += 16;
+ }
+
+ for(int i = 0; i<(num_points % 16); ++i)
+ {
+ *cPtr++ = (*aPtr++) + (*bPtr++);
+ }
+}
+#endif /* LV_HAVE_SSE2 */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Adds the two input vectors and store their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be added
+ \param bVector One of the vectors to be added
+ \param num_points The number of values in aVector and bVector to be added together and stored into cVector
+ */
+static inline void volk_gnsssdr_8i_x2_add_8i_generic(char* cVector, const char* aVector, const char* bVector, unsigned int num_points){
+ char* cPtr = cVector;
+ const char* aPtr = aVector;
+ const char* bPtr= bVector;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ *cPtr++ = (*aPtr++) + (*bPtr++);
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_volk_gnsssdr_8i_x2_add_8i_u_H */
+
+
+#ifndef INCLUDED_volk_gnsssdr_8i_x2_add_8i_a_H
+#define INCLUDED_volk_gnsssdr_8i_x2_add_8i_a_H
+
+#include
+#include
+
+#ifdef LV_HAVE_SSE2
+#include "pmmintrin.h"
+/*!
+ \brief Adds the two input vectors and store their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be added
+ \param bVector One of the vectors to be added
+ \param num_points The number of values in aVector and bVector to be added together and stored into cVector
+ */
+static inline void volk_gnsssdr_8i_x2_add_8i_a_sse2(char* cVector, const char* aVector, const char* bVector, unsigned int num_points){
+
+ const unsigned int sse_iters = num_points / 16;
+
+ char* cPtr = cVector;
+ const char* aPtr = aVector;
+ const char* bPtr= bVector;
+
+ __m128i aVal, bVal, cVal;
+
+ for(int number = 0; number < sse_iters; number++){
+
+ aVal = _mm_load_si128((__m128i*)aPtr);
+ bVal = _mm_load_si128((__m128i*)bPtr);
+
+ cVal = _mm_add_epi8(aVal, bVal);
+
+ _mm_store_si128((__m128i*)cPtr,cVal); // Store the results back into the C container
+
+ aPtr += 16;
+ bPtr += 16;
+ cPtr += 16;
+ }
+
+ for(int i = 0; i<(num_points % 16); ++i)
+ {
+ *cPtr++ = (*aPtr++) + (*bPtr++);
+ }
+}
+#endif /* LV_HAVE_SSE2 */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Adds the two input vectors and store their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be added
+ \param bVector One of the vectors to be added
+ \param num_points The number of values in aVector and bVector to be added together and stored into cVector
+ */
+static inline void volk_gnsssdr_8i_x2_add_8i_a_generic(char* cVector, const char* aVector, const char* bVector, unsigned int num_points){
+ char* cPtr = cVector;
+ const char* aPtr = aVector;
+ const char* bPtr= bVector;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ *cPtr++ = (*aPtr++) + (*bPtr++);
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+#ifdef LV_HAVE_ORC
+/*!
+ \brief Adds the two input vectors and store their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be added
+ \param bVector One of the vectors to be added
+ \param num_points The number of values in aVector and bVector to be added together and stored into cVector
+ */
+extern void volk_gnsssdr_8i_x2_add_8i_a_orc_impl(char* cVector, const char* aVector, const char* bVector, unsigned int num_points);
+static inline void volk_gnsssdr_8i_x2_add_8i_u_orc(char* cVector, const char* aVector, const char* bVector, unsigned int num_points){
+ volk_gnsssdr_8i_x2_add_8i_a_orc_impl(cVector, aVector, bVector, num_points);
+}
+#endif /* LV_HAVE_ORC */
+
+#endif /* INCLUDED_volk_gnsssdr_8i_x2_add_8i_a_H */
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_conjugate_8ic.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_conjugate_8ic.h
new file mode 100644
index 000000000..231796274
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_conjugate_8ic.h
@@ -0,0 +1,326 @@
+/*!
+ * \file volk_gnsssdr_8ic_conjugate_8ic.h
+ * \brief Volk protokernel: calculates the conjugate of a 16 bits vector
+ * \authors
+ * - Andrés Cecilia, 2014. a.cecilia.luque(at)gmail.com
+ *
+ *
+ * Volk protokernel that calculates the conjugate of a
+ * 16 bits vector (8 bits the real part and 8 bits the imaginary part)
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#ifndef INCLUDED_volk_gnsssdr_8ic_conjugate_8ic_u_H
+#define INCLUDED_volk_gnsssdr_8ic_conjugate_8ic_u_H
+
+#include
+#include
+#include
+
+#ifdef LV_HAVE_AVX
+#include "immintrin.h"
+/*!
+ \brief Takes the conjugate of an unsigned char vector.
+ \param cVector The vector where the results will be stored
+ \param aVector Vector to be conjugated
+ \param num_points The number of unsigned char values in aVector to be conjugated and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_conjugate_8ic_u_avx(lv_8sc_t* cVector, const lv_8sc_t* aVector, unsigned int num_points){
+ const unsigned int sse_iters = num_points / 16;
+
+ lv_8sc_t* c = cVector;
+ const lv_8sc_t* a = aVector;
+
+ __m256 tmp;
+ __m128i tmp128lo, tmp128hi;
+ __m256 conjugator1 = _mm256_castsi256_ps(_mm256_setr_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255));
+ __m128i conjugator2 = _mm_setr_epi8(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1);
+
+ for (int i = 0; i < sse_iters; ++i)
+ {
+ tmp = _mm256_loadu_ps((float*)a);
+ tmp = _mm256_xor_ps(tmp, conjugator1);
+ tmp128lo = _mm256_castsi256_si128(_mm256_castps_si256(tmp));
+ tmp128lo = _mm_add_epi8(tmp128lo, conjugator2);
+ tmp128hi = _mm256_extractf128_si256(_mm256_castps_si256(tmp),1);
+ tmp128hi = _mm_add_epi8(tmp128hi, conjugator2);
+ //tmp = _mm256_set_m128i(tmp128hi , tmp128lo); //not defined in some versions of immintrin.h
+ tmp = _mm256_insertf128_si256(_mm256_castsi128_si256(tmp128lo),(tmp128hi),1);
+ _mm256_storeu_ps((float*)c, tmp);
+
+ a += 16;
+ c += 16;
+ }
+
+ for (int i = 0; i<(num_points % 16); ++i)
+ {
+ *c++ = lv_conj(*a++);
+ }
+}
+#endif /* LV_HAVE_AVX */
+
+#ifdef LV_HAVE_SSSE3
+#include "tmmintrin.h"
+/*!
+ \brief Takes the conjugate of an unsigned char vector.
+ \param cVector The vector where the results will be stored
+ \param aVector Vector to be conjugated
+ \param num_points The number of unsigned char values in aVector to be conjugated and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_conjugate_8ic_u_ssse3(lv_8sc_t* cVector, const lv_8sc_t* aVector, unsigned int num_points){
+ const unsigned int sse_iters = num_points / 8;
+
+ lv_8sc_t* c = cVector;
+ const lv_8sc_t* a = aVector;
+ __m128i tmp;
+
+ __m128i conjugator = _mm_setr_epi8(1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1);
+
+ for (int i = 0; i < sse_iters; ++i)
+ {
+ tmp = _mm_lddqu_si128((__m128i*)a);
+ tmp = _mm_sign_epi8(tmp, conjugator);
+ _mm_storeu_si128((__m128i*)c, tmp);
+ a += 8;
+ c += 8;
+ }
+
+ for (int i = 0; i<(num_points % 8); ++i)
+ {
+ *c++ = lv_conj(*a++);
+ }
+
+}
+#endif /* LV_HAVE_SSSE3 */
+
+#ifdef LV_HAVE_SSE3
+#include
+/*!
+ \brief Takes the conjugate of an unsigned char vector.
+ \param cVector The vector where the results will be stored
+ \param aVector Vector to be conjugated
+ \param num_points The number of unsigned char values in aVector to be conjugated and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_conjugate_8ic_u_sse3(lv_8sc_t* cVector, const lv_8sc_t* aVector, unsigned int num_points){
+ const unsigned int sse_iters = num_points / 8;
+
+ lv_8sc_t* c = cVector;
+ const lv_8sc_t* a = aVector;
+ __m128i tmp;
+
+ __m128i conjugator1 = _mm_setr_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255);
+ __m128i conjugator2 = _mm_setr_epi8(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1);
+
+ for (int i = 0; i < sse_iters; ++i)
+ {
+ tmp = _mm_lddqu_si128((__m128i*)a);
+ tmp = _mm_xor_si128(tmp, conjugator1);
+ tmp = _mm_add_epi8(tmp, conjugator2);
+ _mm_storeu_si128((__m128i*)c, tmp);
+ a += 8;
+ c += 8;
+ }
+
+ for (int i = 0; i<(num_points % 8); ++i)
+ {
+ *c++ = lv_conj(*a++);
+ }
+
+}
+#endif /* LV_HAVE_SSE3 */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Takes the conjugate of an unsigned char vector.
+ \param cVector The vector where the results will be stored
+ \param aVector Vector to be conjugated
+ \param num_points The number of unsigned char values in aVector to be conjugated and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_conjugate_8ic_generic(lv_8sc_t* cVector, const lv_8sc_t* aVector, unsigned int num_points){
+ lv_8sc_t* cPtr = cVector;
+ const lv_8sc_t* aPtr = aVector;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ *cPtr++ = lv_conj(*aPtr++);
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_volk_gnsssdr_8ic_conjugate_8ic_u_H */
+
+
+#ifndef INCLUDED_volk_gnsssdr_8ic_conjugate_8ic_a_H
+#define INCLUDED_volk_gnsssdr_8ic_conjugate_8ic_a_H
+
+#include
+#include
+#include
+
+#ifdef LV_HAVE_AVX
+#include "immintrin.h"
+/*!
+ \brief Takes the conjugate of an unsigned char vector.
+ \param cVector The vector where the results will be stored
+ \param aVector Vector to be conjugated
+ \param num_points The number of unsigned char values in aVector to be conjugated and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_conjugate_8ic_a_avx(lv_8sc_t* cVector, const lv_8sc_t* aVector, unsigned int num_points){
+ const unsigned int sse_iters = num_points / 16;
+
+ lv_8sc_t* c = cVector;
+ const lv_8sc_t* a = aVector;
+
+ __m256 tmp;
+ __m128i tmp128lo, tmp128hi;
+ __m256 conjugator1 = _mm256_castsi256_ps(_mm256_setr_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255));
+ __m128i conjugator2 = _mm_setr_epi8(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1);
+
+ for (int i = 0; i < sse_iters; ++i)
+ {
+ tmp = _mm256_load_ps((float*)a);
+ tmp = _mm256_xor_ps(tmp, conjugator1);
+ tmp128lo = _mm256_castsi256_si128(_mm256_castps_si256(tmp));
+ tmp128lo = _mm_add_epi8(tmp128lo, conjugator2);
+ tmp128hi = _mm256_extractf128_si256(_mm256_castps_si256(tmp),1);
+ tmp128hi = _mm_add_epi8(tmp128hi, conjugator2);
+ //tmp = _mm256_set_m128i(tmp128hi , tmp128lo); //not defined in some versions of immintrin.h
+ tmp = _mm256_insertf128_si256(_mm256_castsi128_si256(tmp128lo),(tmp128hi),1);
+ _mm256_store_ps((float*)c, tmp);
+
+ a += 16;
+ c += 16;
+ }
+
+ for (int i = 0; i<(num_points % 16); ++i)
+ {
+ *c++ = lv_conj(*a++);
+ }
+}
+#endif /* LV_HAVE_AVX */
+
+#ifdef LV_HAVE_SSSE3
+#include "tmmintrin.h"
+/*!
+ \brief Takes the conjugate of an unsigned char vector.
+ \param cVector The vector where the results will be stored
+ \param aVector Vector to be conjugated
+ \param num_points The number of unsigned char values in aVector to be conjugated and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_conjugate_8ic_a_ssse3(lv_8sc_t* cVector, const lv_8sc_t* aVector, unsigned int num_points){
+ const unsigned int sse_iters = num_points / 8;
+
+ lv_8sc_t* c = cVector;
+ const lv_8sc_t* a = aVector;
+ __m128i tmp;
+
+ __m128i conjugator = _mm_setr_epi8(1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1);
+
+ for (int i = 0; i < sse_iters; ++i)
+ {
+ tmp = _mm_load_si128((__m128i*)a);
+ tmp = _mm_sign_epi8(tmp, conjugator);
+ _mm_store_si128((__m128i*)c, tmp);
+ a += 8;
+ c += 8;
+ }
+
+ for (int i = 0; i<(num_points % 8); ++i)
+ {
+ *c++ = lv_conj(*a++);
+ }
+
+}
+#endif /* LV_HAVE_SSSE3 */
+
+#ifdef LV_HAVE_SSE3
+#include
+/*!
+ \brief Takes the conjugate of an unsigned char vector.
+ \param cVector The vector where the results will be stored
+ \param aVector Vector to be conjugated
+ \param num_points The number of unsigned char values in aVector to be conjugated and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_conjugate_8ic_a_sse3(lv_8sc_t* cVector, const lv_8sc_t* aVector, unsigned int num_points){
+ const unsigned int sse_iters = num_points / 8;
+
+ lv_8sc_t* c = cVector;
+ const lv_8sc_t* a = aVector;
+ __m128i tmp;
+
+ __m128i conjugator1 = _mm_setr_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255);
+ __m128i conjugator2 = _mm_setr_epi8(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1);
+
+ for (int i = 0; i < sse_iters; ++i)
+ {
+ tmp = _mm_load_si128((__m128i*)a);
+ tmp = _mm_xor_si128(tmp, conjugator1);
+ tmp = _mm_add_epi8(tmp, conjugator2);
+ _mm_store_si128((__m128i*)c, tmp);
+ a += 8;
+ c += 8;
+ }
+
+ for (int i = 0; i<(num_points % 8); ++i)
+ {
+ *c++ = lv_conj(*a++);
+ }
+
+}
+#endif /* LV_HAVE_SSE3 */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Takes the conjugate of an unsigned char vector.
+ \param cVector The vector where the results will be stored
+ \param aVector Vector to be conjugated
+ \param num_points The number of unsigned char values in aVector to be conjugated and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_conjugate_8ic_a_generic(lv_8sc_t* cVector, const lv_8sc_t* aVector, unsigned int num_points){
+ lv_8sc_t* cPtr = cVector;
+ const lv_8sc_t* aPtr = aVector;
+ unsigned int number = 0;
+
+ for(number = 0; number < num_points; number++){
+ *cPtr++ = lv_conj(*aPtr++);
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+#ifdef LV_HAVE_ORC
+/*!
+ \brief Takes the conjugate of an unsigned char vector.
+ \param cVector The vector where the results will be stored
+ \param aVector Vector to be conjugated
+ \param num_points The number of unsigned char values in aVector to be conjugated and stored into cVector
+ */
+extern void volk_gnsssdr_8ic_conjugate_8ic_a_orc_impl(lv_8sc_t* cVector, const lv_8sc_t* aVector, unsigned int num_points);
+static inline void volk_gnsssdr_8ic_conjugate_8ic_u_orc(lv_8sc_t* cVector, const lv_8sc_t* aVector, unsigned int num_points){
+ volk_gnsssdr_8ic_conjugate_8ic_a_orc_impl(cVector, aVector, num_points);
+}
+#endif /* LV_HAVE_ORC */
+
+#endif /* INCLUDED_volk_gnsssdr_8ic_conjugate_8ic_a_H */
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_magnitude_squared_8i.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_magnitude_squared_8i.h
new file mode 100644
index 000000000..1eab648fe
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_magnitude_squared_8i.h
@@ -0,0 +1,320 @@
+/*!
+ * \file volk_gnsssdr_8ic_magnitude_squared_8i.h
+ * \brief Volk protokernel: calculates the magnitude squared of a 16 bits vector
+ * \authors
+ * - Andrés Cecilia, 2014. a.cecilia.luque(at)gmail.com
+ *
+ *
+ * Volk protokernel that calculates the magnitude squared of a
+ * 16 bits vector (8 bits the real part and 8 bits the imaginary part)
+ * result = (real*real) + (imag*imag)
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#ifndef INCLUDED_volk_gnsssdr_8ic_magnitude_squared_8i_u_H
+#define INCLUDED_volk_gnsssdr_8ic_magnitude_squared_8i_u_H
+
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE3
+#include
+#include "tmmintrin.h"
+/*!
+ \brief Calculates the magnitude squared of complexVector and stores the results in magnitudeVector
+ \param complexVector The vector containing the complex input values
+ \param magnitudeVector The vector containing the real output values
+ \param num_points The number of complex values in complexVector to be calculated and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_magnitude_squared_8i_u_sse3(char* magnitudeVector, const lv_8sc_t* complexVector, unsigned int num_points){
+
+ const unsigned int sse_iters = num_points / 16;
+
+ const char* complexVectorPtr = (char*)complexVector;
+ char* magnitudeVectorPtr = magnitudeVector;
+
+ __m128i zero, result8;
+ __m128i avector, avectorhi, avectorlo, avectorlomult, avectorhimult, aadded, maska;
+ __m128i bvector, bvectorhi, bvectorlo, bvectorlomult, bvectorhimult, badded, maskb;
+
+ zero = _mm_setzero_si128();
+ maska = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 14, 12, 10, 8, 6, 4, 2, 0);
+ maskb = _mm_set_epi8(14, 12, 10, 8, 6, 4, 2, 0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80);
+
+ for(int number = 0;number < sse_iters; number++)
+ {
+ avector = _mm_lddqu_si128((__m128i*)complexVectorPtr);
+ avectorlo = _mm_unpacklo_epi8 (avector, zero);
+ avectorhi = _mm_unpackhi_epi8 (avector, zero);
+ avectorlomult = _mm_mullo_epi16 (avectorlo, avectorlo);
+ avectorhimult = _mm_mullo_epi16 (avectorhi, avectorhi);
+ aadded = _mm_hadd_epi16 (avectorlomult, avectorhimult);
+
+ complexVectorPtr += 16;
+
+ bvector = _mm_lddqu_si128((__m128i*)complexVectorPtr);
+ bvectorlo = _mm_unpacklo_epi8 (bvector, zero);
+ bvectorhi = _mm_unpackhi_epi8 (bvector, zero);
+ bvectorlomult = _mm_mullo_epi16 (bvectorlo, bvectorlo);
+ bvectorhimult = _mm_mullo_epi16 (bvectorhi, bvectorhi);
+ badded = _mm_hadd_epi16 (bvectorlomult, bvectorhimult);
+
+ complexVectorPtr += 16;
+
+ result8 = _mm_or_si128(_mm_shuffle_epi8(aadded, maska), _mm_shuffle_epi8(badded, maskb));
+
+ _mm_storeu_si128((__m128i*)magnitudeVectorPtr, result8);
+
+ magnitudeVectorPtr += 16;
+
+
+ }
+
+ for (int i = 0; i<(num_points % 16); ++i)
+ {
+ const char valReal = *complexVectorPtr++;
+ const char valImag = *complexVectorPtr++;
+ *magnitudeVectorPtr++ = (valReal * valReal) + (valImag * valImag);
+ }
+}
+#endif /* LV_HAVE_SSE3 */
+
+//#ifdef LV_HAVE_SSE
+//#include
+///*!
+// \brief Calculates the magnitude squared of complexVector and stores the results in magnitudeVector
+// \param complexVector The vector containing the complex input values
+// \param magnitudeVector The vector containing the real output values
+// \param num_points The number of complex values in complexVector to be calculated and stored into cVector
+// */
+//static inline void volk_gnsssdr_8ic_magnitude_squared_8i_u_sse(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
+// unsigned int number = 0;
+// const unsigned int quarterPoints = num_points / 4;
+//
+// const float* complexVectorPtr = (float*)complexVector;
+// float* magnitudeVectorPtr = magnitudeVector;
+//
+// __m128 cplxValue1, cplxValue2, iValue, qValue, result;
+// for(;number < quarterPoints; number++){
+// cplxValue1 = _mm_loadu_ps(complexVectorPtr);
+// complexVectorPtr += 4;
+//
+// cplxValue2 = _mm_loadu_ps(complexVectorPtr);
+// complexVectorPtr += 4;
+//
+// // Arrange in i1i2i3i4 format
+// iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2,0,2,0));
+// // Arrange in q1q2q3q4 format
+// qValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3,1,3,1));
+//
+// iValue = _mm_mul_ps(iValue, iValue); // Square the I values
+// qValue = _mm_mul_ps(qValue, qValue); // Square the Q Values
+//
+// result = _mm_add_ps(iValue, qValue); // Add the I2 and Q2 values
+//
+// _mm_storeu_ps(magnitudeVectorPtr, result);
+// magnitudeVectorPtr += 4;
+// }
+//
+// number = quarterPoints * 4;
+// for(; number < num_points; number++){
+// float val1Real = *complexVectorPtr++;
+// float val1Imag = *complexVectorPtr++;
+// *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
+// }
+//}
+//#endif /* LV_HAVE_SSE */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Calculates the magnitude squared of complexVector and stores the results in magnitudeVector
+ \param complexVector The vector containing the complex input values
+ \param magnitudeVector The vector containing the real output values
+ \param num_points The number of complex values in complexVector to be calculated and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_magnitude_squared_8i_generic(char* magnitudeVector, const lv_8sc_t* complexVector, unsigned int num_points){
+ const char* complexVectorPtr = (char*)complexVector;
+ char* magnitudeVectorPtr = magnitudeVector;
+
+ for(int number = 0; number < num_points; number++){
+ const char real = *complexVectorPtr++;
+ const char imag = *complexVectorPtr++;
+ *magnitudeVectorPtr++ = (real*real) + (imag*imag);
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_volk_gnsssdr_32fc_magnitude_32f_u_H */
+
+
+#ifndef INCLUDED_volk_gnsssdr_8ic_magnitude_squared_8i_a_H
+#define INCLUDED_volk_gnsssdr_8ic_magnitude_squared_8i_a_H
+
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE3
+#include
+/*!
+ \brief Calculates the magnitude squared of complexVector and stores the results in magnitudeVector
+ \param complexVector The vector containing the complex input values
+ \param magnitudeVector The vector containing the real output values
+ \param num_points The number of complex values in complexVector to be calculated and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_magnitude_squared_8i_a_sse3(char* magnitudeVector, const lv_8sc_t* complexVector, unsigned int num_points){
+
+ const unsigned int sse_iters = num_points / 16;
+
+ const char* complexVectorPtr = (char*)complexVector;
+ char* magnitudeVectorPtr = magnitudeVector;
+
+ __m128i zero, result8;
+ __m128i avector, avectorhi, avectorlo, avectorlomult, avectorhimult, aadded, maska;
+ __m128i bvector, bvectorhi, bvectorlo, bvectorlomult, bvectorhimult, badded, maskb;
+
+ zero = _mm_setzero_si128();
+ maska = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 14, 12, 10, 8, 6, 4, 2, 0);
+ maskb = _mm_set_epi8(14, 12, 10, 8, 6, 4, 2, 0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80);
+
+ for(int number = 0;number < sse_iters; number++)
+ {
+ avector = _mm_load_si128((__m128i*)complexVectorPtr);
+ avectorlo = _mm_unpacklo_epi8 (avector, zero);
+ avectorhi = _mm_unpackhi_epi8 (avector, zero);
+ avectorlomult = _mm_mullo_epi16 (avectorlo, avectorlo);
+ avectorhimult = _mm_mullo_epi16 (avectorhi, avectorhi);
+ aadded = _mm_hadd_epi16 (avectorlomult, avectorhimult);
+
+ complexVectorPtr += 16;
+
+ bvector = _mm_load_si128((__m128i*)complexVectorPtr);
+ bvectorlo = _mm_unpacklo_epi8 (bvector, zero);
+ bvectorhi = _mm_unpackhi_epi8 (bvector, zero);
+ bvectorlomult = _mm_mullo_epi16 (bvectorlo, bvectorlo);
+ bvectorhimult = _mm_mullo_epi16 (bvectorhi, bvectorhi);
+ badded = _mm_hadd_epi16 (bvectorlomult, bvectorhimult);
+
+ complexVectorPtr += 16;
+
+ result8 = _mm_or_si128(_mm_shuffle_epi8(aadded, maska), _mm_shuffle_epi8(badded, maskb));
+
+ _mm_store_si128((__m128i*)magnitudeVectorPtr, result8);
+
+ magnitudeVectorPtr += 16;
+
+
+ }
+
+ for (int i = 0; i<(num_points % 16); ++i)
+ {
+ const char valReal = *complexVectorPtr++;
+ const char valImag = *complexVectorPtr++;
+ *magnitudeVectorPtr++ = (valReal * valReal) + (valImag * valImag);
+ }
+}
+#endif /* LV_HAVE_SSE3 */
+
+//#ifdef LV_HAVE_SSE
+//#include
+///*!
+// \brief Calculates the magnitude squared of complexVector and stores the results in magnitudeVector
+// \param complexVector The vector containing the complex input values
+// \param magnitudeVector The vector containing the real output values
+// \param num_points The number of complex values in complexVector to be calculated and stored into cVector
+// */
+//static inline void volk_gnsssdr_8ic_magnitude_squared_8i_a_sse(float* magnitudeVector, const lv_32fc_t* complexVector, unsigned int num_points){
+// unsigned int number = 0;
+// const unsigned int quarterPoints = num_points / 4;
+//
+// const float* complexVectorPtr = (float*)complexVector;
+// float* magnitudeVectorPtr = magnitudeVector;
+//
+// __m128 cplxValue1, cplxValue2, iValue, qValue, result;
+// for(;number < quarterPoints; number++){
+// cplxValue1 = _mm_load_ps(complexVectorPtr);
+// complexVectorPtr += 4;
+//
+// cplxValue2 = _mm_load_ps(complexVectorPtr);
+// complexVectorPtr += 4;
+//
+// // Arrange in i1i2i3i4 format
+// iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(2,0,2,0));
+// // Arrange in q1q2q3q4 format
+// qValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3,1,3,1));
+//
+// iValue = _mm_mul_ps(iValue, iValue); // Square the I values
+// qValue = _mm_mul_ps(qValue, qValue); // Square the Q Values
+//
+// result = _mm_add_ps(iValue, qValue); // Add the I2 and Q2 values
+//
+// _mm_store_ps(magnitudeVectorPtr, result);
+// magnitudeVectorPtr += 4;
+// }
+//
+// number = quarterPoints * 4;
+// for(; number < num_points; number++){
+// float val1Real = *complexVectorPtr++;
+// float val1Imag = *complexVectorPtr++;
+// *magnitudeVectorPtr++ = (val1Real * val1Real) + (val1Imag * val1Imag);
+// }
+//}
+//#endif /* LV_HAVE_SSE */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Calculates the magnitude squared of complexVector and stores the results in magnitudeVector
+ \param complexVector The vector containing the complex input values
+ \param magnitudeVector The vector containing the real output values
+ \param num_points The number of complex values in complexVector to be calculated and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_magnitude_squared_8i_a_generic(char* magnitudeVector, const lv_8sc_t* complexVector, unsigned int num_points){
+ const char* complexVectorPtr = (char*)complexVector;
+ char* magnitudeVectorPtr = magnitudeVector;
+
+ for(int number = 0; number < num_points; number++){
+ const char real = *complexVectorPtr++;
+ const char imag = *complexVectorPtr++;
+ *magnitudeVectorPtr++ = (real*real) + (imag*imag);
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+#ifdef LV_HAVE_ORC
+/*!
+ \brief Calculates the magnitude squared of complexVector and stores the results in magnitudeVector
+ \param complexVector The vector containing the complex input values
+ \param magnitudeVector The vector containing the real output values
+ \param num_points The number of complex values in complexVector to be calculated and stored into cVector
+ */
+extern void volk_gnsssdr_8ic_magnitude_squared_8i_a_orc_impl(char* magnitudeVector, const lv_8sc_t* complexVector, unsigned int num_points);
+static inline void volk_gnsssdr_8ic_magnitude_squared_8i_u_orc(char* magnitudeVector, const lv_8sc_t* complexVector, unsigned int num_points){
+ volk_gnsssdr_8ic_magnitude_squared_8i_a_orc_impl(magnitudeVector, complexVector, num_points);
+}
+#endif /* LV_HAVE_ORC */
+
+#endif /* INCLUDED_volk_gnsssdr_32fc_magnitude_32f_a_H */
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_s8ic_multiply_8ic.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_s8ic_multiply_8ic.h
new file mode 100644
index 000000000..e0578f13a
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_s8ic_multiply_8ic.h
@@ -0,0 +1,271 @@
+/*!
+ * \file volk_gnsssdr_8ic_s8ic_multiply_8ic.h
+ * \brief Volk protokernel: multiplies a group of 16 bits vectors by one constant vector
+ * \authors
+ * - Andrés Cecilia, 2014. a.cecilia.luque(at)gmail.com
+ *
+ *
+ * Volk protokernel that multiplies a group of 16 bits vectors
+ * (8 bits the real part and 8 bits the imaginary part) by one constant vector
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#ifndef INCLUDED_volk_gnsssdr_8ic_s8ic_multiply_8ic_u_H
+#define INCLUDED_volk_gnsssdr_8ic_s8ic_multiply_8ic_u_H
+
+#include
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE3
+#include
+/*!
+ \brief Multiplies the input vector by a scalar and stores the results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector The vector to be multiplied
+ \param scalar The complex scalar to multiply aVector
+ \param num_points The number of complex values in aVector to be multiplied by sacalar and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_s8ic_multiply_8ic_u_sse3(lv_8sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t scalar, unsigned int num_points){
+
+ const unsigned int sse_iters = num_points / 8;
+
+ __m128i x, y, mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, realc, imagc, totalc;
+
+ lv_8sc_t* c = cVector;
+ const lv_8sc_t* a = aVector;
+
+ mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255);
+
+ y = _mm_set1_epi16 (*(short*)&scalar);
+ imagy = _mm_srli_si128 (y, 1);
+ imagy = _mm_and_si128 (imagy, mult1);
+ realy = _mm_and_si128 (y, mult1);
+
+ for(int number = 0;number < sse_iters; number++){
+
+ x = _mm_lddqu_si128((__m128i*)a);
+
+ imagx = _mm_srli_si128 (x, 1);
+ imagx = _mm_and_si128 (imagx, mult1);
+ realx = _mm_and_si128 (x, mult1);
+
+ realx_mult_realy = _mm_mullo_epi16 (realx, realy);
+ imagx_mult_imagy = _mm_mullo_epi16 (imagx, imagy);
+ realx_mult_imagy = _mm_mullo_epi16 (realx, imagy);
+ imagx_mult_realy = _mm_mullo_epi16 (imagx, realy);
+
+ realc = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+ realc = _mm_and_si128 (realc, mult1);
+ imagc = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+ imagc = _mm_and_si128 (imagc, mult1);
+ imagc = _mm_slli_si128 (imagc, 1);
+
+ totalc = _mm_or_si128 (realc, imagc);
+
+ _mm_storeu_si128((__m128i*)c, totalc);
+
+ a += 8;
+ c += 8;
+ }
+
+ for (int i = 0; i<(num_points % 8); ++i)
+ {
+ *c++ = (*a++) * scalar;
+ }
+
+}
+#endif /* LV_HAVE_SSE3 */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Multiplies the input vector by a scalar and stores the results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector The vector to be multiplied
+ \param scalar The complex scalar to multiply aVector
+ \param num_points The number of complex values in aVector to be multiplied by sacalar and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_s8ic_multiply_8ic_generic(lv_8sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t scalar, unsigned int num_points){
+
+ /*lv_8sc_t* cPtr = cVector;
+ const lv_8sc_t* aPtr = aVector;
+
+ for (int i = 0; i= 8){
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ number -= 8;
+ }
+
+ // clean up any remaining
+ while (number-- > 0)
+ *cPtr++ = *aPtr++ * scalar;
+}
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_volk_gnsssdr_32fc_x2_multiply_32fc_u_H */
+
+
+#ifndef INCLUDED_volk_gnsssdr_8ic_s8ic_multiply_8ic_a_H
+#define INCLUDED_volk_gnsssdr_8ic_s8ic_multiply_8ic_a_H
+
+#include
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE3
+#include
+/*!
+ \brief Multiplies the input vector by a scalar and stores the results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector The vector to be multiplied
+ \param scalar The complex scalar to multiply aVector
+ \param num_points The number of complex values in aVector to be multiplied by sacalar and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_s8ic_multiply_8ic_a_sse3(lv_8sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t scalar, unsigned int num_points){
+
+ const unsigned int sse_iters = num_points / 8;
+
+ __m128i x, y, mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, realc, imagc, totalc;
+
+ lv_8sc_t* c = cVector;
+ const lv_8sc_t* a = aVector;
+
+ mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255);
+
+ y = _mm_set1_epi16 (*(short*)&scalar);
+ imagy = _mm_srli_si128 (y, 1);
+ imagy = _mm_and_si128 (imagy, mult1);
+ realy = _mm_and_si128 (y, mult1);
+
+ for(int number = 0;number < sse_iters; number++){
+
+ x = _mm_load_si128((__m128i*)a);
+
+ imagx = _mm_srli_si128 (x, 1);
+ imagx = _mm_and_si128 (imagx, mult1);
+ realx = _mm_and_si128 (x, mult1);
+
+ realx_mult_realy = _mm_mullo_epi16 (realx, realy);
+ imagx_mult_imagy = _mm_mullo_epi16 (imagx, imagy);
+ realx_mult_imagy = _mm_mullo_epi16 (realx, imagy);
+ imagx_mult_realy = _mm_mullo_epi16 (imagx, realy);
+
+ realc = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+ realc = _mm_and_si128 (realc, mult1);
+ imagc = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+ imagc = _mm_and_si128 (imagc, mult1);
+ imagc = _mm_slli_si128 (imagc, 1);
+
+ totalc = _mm_or_si128 (realc, imagc);
+
+ _mm_store_si128((__m128i*)c, totalc);
+
+ a += 8;
+ c += 8;
+ }
+
+ for (int i = 0; i<(num_points % 8); ++i)
+ {
+ *c++ = (*a++) * scalar;
+ }
+
+}
+#endif /* LV_HAVE_SSE3 */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Multiplies the input vector by a scalar and stores the results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector The vector to be multiplied
+ \param scalar The complex scalar to multiply aVector
+ \param num_points The number of complex values in aVector to be multiplied by sacalar and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_s8ic_multiply_8ic_a_generic(lv_8sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t scalar, unsigned int num_points){
+
+ /*lv_8sc_t* cPtr = cVector;
+ const lv_8sc_t* aPtr = aVector;
+
+ for (int i = 0; i= 8){
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ *cPtr++ = (*aPtr++) * scalar;
+ number -= 8;
+ }
+
+ // clean up any remaining
+ while (number-- > 0)
+ *cPtr++ = *aPtr++ * scalar;
+}
+#endif /* LV_HAVE_GENERIC */
+
+#ifdef LV_HAVE_ORC
+/*!
+ \brief Multiplies the input vector by a scalar and stores the results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector The vector to be multiplied
+ \param scalar The complex scalar to multiply aVector
+ \param num_points The number of complex values in aVector to be multiplied by sacalar and stored into cVector
+ */
+extern void volk_gnsssdr_8ic_s8ic_multiply_8ic_a_orc_impl(lv_8sc_t* cVector, const lv_8sc_t* aVector, const char scalarreal, const char scalarimag, unsigned int num_points);
+static inline void volk_gnsssdr_8ic_s8ic_multiply_8ic_u_orc(lv_8sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t scalar, unsigned int num_points){
+ volk_gnsssdr_8ic_s8ic_multiply_8ic_a_orc_impl(cVector, aVector, lv_creal(scalar), lv_cimag(scalar), num_points);
+}
+#endif /* LV_HAVE_ORC */
+
+#endif /* INCLUDED_volk_gnsssdr_32fc_x2_multiply_32fc_a_H */
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_x2_dot_prod_8ic.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_x2_dot_prod_8ic.h
new file mode 100644
index 000000000..696b0a31f
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_x2_dot_prod_8ic.h
@@ -0,0 +1,499 @@
+/*!
+ * \file volk_gnsssdr_8ic_x2_dot_prod_8ic.h
+ * \brief Volk protokernel: multiplies two 16 bits vectors and accumulates them
+ * \authors
+ * - Andrés Cecilia, 2014. a.cecilia.luque(at)gmail.com
+ *
+ *
+ * Volk protokernel that multiplies two 16 bits vectors (8 bits the real part
+ * and 8 bits the imaginary part) and accumulates them
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#ifndef INCLUDED_volk_gnsssdr_8ic_x2_dot_prod_8ic_u_H
+#define INCLUDED_volk_gnsssdr_8ic_x2_dot_prod_8ic_u_H
+
+#include
+#include
+#include
+#include
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Multiplies the two input complex vectors and accumulates them, storing the result in the third vector
+ \param cVector The vector where the accumulated result will be stored
+ \param aVector One of the vectors to be multiplied and accumulated
+ \param bVector One of the vectors to be multiplied and accumulated
+ \param num_points The number of complex values in aVector and bVector to be multiplied together, accumulated and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_x2_dot_prod_8ic_generic(lv_8sc_t* result, const lv_8sc_t* input, const lv_8sc_t* taps, unsigned int num_points) {
+
+ /*lv_8sc_t* cPtr = result;
+ const lv_8sc_t* aPtr = input;
+ const lv_8sc_t* bPtr = taps;
+
+ for(int number = 0; number < num_points; number++){
+ *cPtr += (*aPtr++) * (*bPtr++);
+ }*/
+
+ char * res = (char*) result;
+ char * in = (char*) input;
+ char * tp = (char*) taps;
+ unsigned int n_2_ccomplex_blocks = num_points/2;
+ unsigned int isodd = num_points & 1;
+
+ char sum0[2] = {0,0};
+ char sum1[2] = {0,0};
+ unsigned int i = 0;
+
+ for(i = 0; i < n_2_ccomplex_blocks; ++i) {
+ sum0[0] += in[0] * tp[0] - in[1] * tp[1];
+ sum0[1] += in[0] * tp[1] + in[1] * tp[0];
+ sum1[0] += in[2] * tp[2] - in[3] * tp[3];
+ sum1[1] += in[2] * tp[3] + in[3] * tp[2];
+
+ in += 4;
+ tp += 4;
+ }
+
+ res[0] = sum0[0] + sum1[0];
+ res[1] = sum0[1] + sum1[1];
+
+ // Cleanup if we had an odd number of points
+ for(i = 0; i < isodd; ++i) {
+ *result += input[num_points - 1] * taps[num_points - 1];
+ }
+}
+
+#endif /*LV_HAVE_GENERIC*/
+
+#ifdef LV_HAVE_SSE2
+#include "emmintrin.h"
+/*!
+ \brief Multiplies the two input complex vectors and accumulates them, storing the result in the third vector
+ \param cVector The vector where the accumulated result will be stored
+ \param aVector One of the vectors to be multiplied and accumulated
+ \param bVector One of the vectors to be multiplied and accumulated
+ \param num_points The number of complex values in aVector and bVector to be multiplied together, accumulated and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_x2_dot_prod_8ic_u_sse2(lv_8sc_t* result, const lv_8sc_t* input, const lv_8sc_t* taps, unsigned int num_points) {
+
+ lv_8sc_t dotProduct;
+ memset(&dotProduct, 0x0, 2*sizeof(char));
+
+ const lv_8sc_t* a = input;
+ const lv_8sc_t* b = taps;
+
+ const unsigned int sse_iters = num_points/8;
+
+ if (sse_iters>0)
+ {
+ __m128i x, y, mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, realc, imagc, totalc, realcacc, imagcacc;
+
+ mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255);
+ realcacc = _mm_setzero_si128();
+ imagcacc = _mm_setzero_si128();
+
+ for(int number = 0; number < sse_iters; number++){
+
+ x = _mm_lddqu_si128((__m128i*)a);
+ y = _mm_lddqu_si128((__m128i*)b);
+
+ imagx = _mm_srli_si128 (x, 1);
+ imagx = _mm_and_si128 (imagx, mult1);
+ realx = _mm_and_si128 (x, mult1);
+
+ imagy = _mm_srli_si128 (y, 1);
+ imagy = _mm_and_si128 (imagy, mult1);
+ realy = _mm_and_si128 (y, mult1);
+
+ realx_mult_realy = _mm_mullo_epi16 (realx, realy);
+ imagx_mult_imagy = _mm_mullo_epi16 (imagx, imagy);
+ realx_mult_imagy = _mm_mullo_epi16 (realx, imagy);
+ imagx_mult_realy = _mm_mullo_epi16 (imagx, realy);
+
+ realc = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+ imagc = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+
+ realcacc = _mm_add_epi16 (realcacc, realc);
+ imagcacc = _mm_add_epi16 (imagcacc, imagc);
+
+ a += 8;
+ b += 8;
+ }
+
+ realcacc = _mm_and_si128 (realcacc, mult1);
+ imagcacc = _mm_and_si128 (imagcacc, mult1);
+ imagcacc = _mm_slli_si128 (imagcacc, 1);
+
+ totalc = _mm_or_si128 (realcacc, imagcacc);
+
+ __VOLK_ATTR_ALIGNED(16) lv_8sc_t dotProductVector[8];
+
+ _mm_storeu_si128((__m128i*)dotProductVector,totalc); // Store the results back into the dot product vector
+
+ for (int i = 0; i<8; ++i)
+ {
+ dotProduct += dotProductVector[i];
+ }
+ }
+
+ for (int i = 0; i<(num_points % 8); ++i)
+ {
+ dotProduct += (*a++) * (*b++);
+ }
+
+ *result = dotProduct;
+}
+
+#endif /*LV_HAVE_SSE2*/
+
+#ifdef LV_HAVE_SSE4_1
+#include "smmintrin.h"
+/*!
+ \brief Multiplies the two input complex vectors and accumulates them, storing the result in the third vector
+ \param cVector The vector where the accumulated result will be stored
+ \param aVector One of the vectors to be multiplied and accumulated
+ \param bVector One of the vectors to be multiplied and accumulated
+ \param num_points The number of complex values in aVector and bVector to be multiplied together, accumulated and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_x2_dot_prod_8ic_u_sse4_1(lv_8sc_t* result, const lv_8sc_t* input, const lv_8sc_t* taps, unsigned int num_points) {
+
+ lv_8sc_t dotProduct;
+ memset(&dotProduct, 0x0, 2*sizeof(char));
+
+ const lv_8sc_t* a = input;
+ const lv_8sc_t* b = taps;
+
+ const unsigned int sse_iters = num_points/8;
+
+ if (sse_iters>0)
+ {
+ __m128i x, y, mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, realc, imagc, totalc, realcacc, imagcacc;
+
+ mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255);
+ realcacc = _mm_setzero_si128();
+ imagcacc = _mm_setzero_si128();
+
+ for(int number = 0; number < sse_iters; number++){
+
+ x = _mm_lddqu_si128((__m128i*)a);
+ y = _mm_lddqu_si128((__m128i*)b);
+
+ imagx = _mm_srli_si128 (x, 1);
+ imagx = _mm_and_si128 (imagx, mult1);
+ realx = _mm_and_si128 (x, mult1);
+
+ imagy = _mm_srli_si128 (y, 1);
+ imagy = _mm_and_si128 (imagy, mult1);
+ realy = _mm_and_si128 (y, mult1);
+
+ realx_mult_realy = _mm_mullo_epi16 (realx, realy);
+ imagx_mult_imagy = _mm_mullo_epi16 (imagx, imagy);
+ realx_mult_imagy = _mm_mullo_epi16 (realx, imagy);
+ imagx_mult_realy = _mm_mullo_epi16 (imagx, realy);
+
+ realc = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+ imagc = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+
+ realcacc = _mm_add_epi16 (realcacc, realc);
+ imagcacc = _mm_add_epi16 (imagcacc, imagc);
+
+ a += 8;
+ b += 8;
+ }
+
+ imagcacc = _mm_slli_si128 (imagcacc, 1);
+
+ totalc = _mm_blendv_epi8 (imagcacc, realcacc, mult1);
+
+ __VOLK_ATTR_ALIGNED(16) lv_8sc_t dotProductVector[8];
+
+ _mm_storeu_si128((__m128i*)dotProductVector,totalc); // Store the results back into the dot product vector
+
+ for (int i = 0; i<8; ++i)
+ {
+ dotProduct += dotProductVector[i];
+ }
+ }
+
+ for (int i = 0; i<(num_points % 8); ++i)
+ {
+ dotProduct += (*a++) * (*b++);
+ }
+
+ *result = dotProduct;
+}
+
+#endif /*LV_HAVE_SSE4_1*/
+
+#endif /*INCLUDED_volk_gnsssdr_8ic_x2_dot_prod_8ic_u_H*/
+
+
+#ifndef INCLUDED_volk_gnsssdr_8ic_x2_dot_prod_8ic_a_H
+#define INCLUDED_volk_gnsssdr_8ic_x2_dot_prod_8ic_a_H
+
+#include
+#include
+#include
+#include
+
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Multiplies the two input complex vectors and accumulates them, storing the result in the third vector
+ \param cVector The vector where the accumulated result will be stored
+ \param aVector One of the vectors to be multiplied and accumulated
+ \param bVector One of the vectors to be multiplied and accumulated
+ \param num_points The number of complex values in aVector and bVector to be multiplied together, accumulated and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_x2_dot_prod_8ic_a_generic(lv_8sc_t* result, const lv_8sc_t* input, const lv_8sc_t* taps, unsigned int num_points) {
+
+ /*lv_8sc_t* cPtr = result;
+ const lv_8sc_t* aPtr = input;
+ const lv_8sc_t* bPtr = taps;
+
+ for(int number = 0; number < num_points; number++){
+ *cPtr += (*aPtr++) * (*bPtr++);
+ }*/
+
+ char * res = (char*) result;
+ char * in = (char*) input;
+ char * tp = (char*) taps;
+ unsigned int n_2_ccomplex_blocks = num_points/2;
+ unsigned int isodd = num_points & 1;
+
+ char sum0[2] = {0,0};
+ char sum1[2] = {0,0};
+ unsigned int i = 0;
+
+ for(i = 0; i < n_2_ccomplex_blocks; ++i) {
+ sum0[0] += in[0] * tp[0] - in[1] * tp[1];
+ sum0[1] += in[0] * tp[1] + in[1] * tp[0];
+ sum1[0] += in[2] * tp[2] - in[3] * tp[3];
+ sum1[1] += in[2] * tp[3] + in[3] * tp[2];
+
+ in += 4;
+ tp += 4;
+ }
+
+ res[0] = sum0[0] + sum1[0];
+ res[1] = sum0[1] + sum1[1];
+
+ // Cleanup if we had an odd number of points
+ for(i = 0; i < isodd; ++i) {
+ *result += input[num_points - 1] * taps[num_points - 1];
+ }
+}
+
+#endif /*LV_HAVE_GENERIC*/
+
+#ifdef LV_HAVE_SSE2
+#include "emmintrin.h"
+/*!
+ \brief Multiplies the two input complex vectors and accumulates them, storing the result in the third vector
+ \param cVector The vector where the accumulated result will be stored
+ \param aVector One of the vectors to be multiplied and accumulated
+ \param bVector One of the vectors to be multiplied and accumulated
+ \param num_points The number of complex values in aVector and bVector to be multiplied together, accumulated and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_x2_dot_prod_8ic_a_sse2(lv_8sc_t* result, const lv_8sc_t* input, const lv_8sc_t* taps, unsigned int num_points) {
+
+ lv_8sc_t dotProduct;
+ memset(&dotProduct, 0x0, 2*sizeof(char));
+
+ const lv_8sc_t* a = input;
+ const lv_8sc_t* b = taps;
+
+ const unsigned int sse_iters = num_points/8;
+
+ if (sse_iters>0)
+ {
+ __m128i x, y, mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, realc, imagc, totalc, realcacc, imagcacc;
+
+ mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255);
+ realcacc = _mm_setzero_si128();
+ imagcacc = _mm_setzero_si128();
+
+ for(int number = 0; number < sse_iters; number++){
+
+ x = _mm_load_si128((__m128i*)a);
+ y = _mm_load_si128((__m128i*)b);
+
+ imagx = _mm_srli_si128 (x, 1);
+ imagx = _mm_and_si128 (imagx, mult1);
+ realx = _mm_and_si128 (x, mult1);
+
+ imagy = _mm_srli_si128 (y, 1);
+ imagy = _mm_and_si128 (imagy, mult1);
+ realy = _mm_and_si128 (y, mult1);
+
+ realx_mult_realy = _mm_mullo_epi16 (realx, realy);
+ imagx_mult_imagy = _mm_mullo_epi16 (imagx, imagy);
+ realx_mult_imagy = _mm_mullo_epi16 (realx, imagy);
+ imagx_mult_realy = _mm_mullo_epi16 (imagx, realy);
+
+ realc = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+ imagc = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+
+ realcacc = _mm_add_epi16 (realcacc, realc);
+ imagcacc = _mm_add_epi16 (imagcacc, imagc);
+
+ a += 8;
+ b += 8;
+ }
+
+ realcacc = _mm_and_si128 (realcacc, mult1);
+ imagcacc = _mm_and_si128 (imagcacc, mult1);
+ imagcacc = _mm_slli_si128 (imagcacc, 1);
+
+ totalc = _mm_or_si128 (realcacc, imagcacc);
+
+ __VOLK_ATTR_ALIGNED(16) lv_8sc_t dotProductVector[8];
+
+ _mm_store_si128((__m128i*)dotProductVector,totalc); // Store the results back into the dot product vector
+
+ for (int i = 0; i<8; ++i)
+ {
+ dotProduct += dotProductVector[i];
+ }
+ }
+
+ for (int i = 0; i<(num_points % 8); ++i)
+ {
+ dotProduct += (*a++) * (*b++);
+ }
+
+ *result = dotProduct;
+}
+
+#endif /*LV_HAVE_SSE2*/
+
+#ifdef LV_HAVE_SSE4_1
+#include "smmintrin.h"
+/*!
+ \brief Multiplies the two input complex vectors and accumulates them, storing the result in the third vector
+ \param cVector The vector where the accumulated result will be stored
+ \param aVector One of the vectors to be multiplied and accumulated
+ \param bVector One of the vectors to be multiplied and accumulated
+ \param num_points The number of complex values in aVector and bVector to be multiplied together, accumulated and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_x2_dot_prod_8ic_a_sse4_1(lv_8sc_t* result, const lv_8sc_t* input, const lv_8sc_t* taps, unsigned int num_points) {
+
+ lv_8sc_t dotProduct;
+ memset(&dotProduct, 0x0, 2*sizeof(char));
+
+ const lv_8sc_t* a = input;
+ const lv_8sc_t* b = taps;
+
+ const unsigned int sse_iters = num_points/8;
+
+ if (sse_iters>0)
+ {
+ __m128i x, y, mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, realc, imagc, totalc, realcacc, imagcacc;
+
+ mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255);
+ realcacc = _mm_setzero_si128();
+ imagcacc = _mm_setzero_si128();
+
+ for(int number = 0; number < sse_iters; number++){
+
+ x = _mm_load_si128((__m128i*)a);
+ y = _mm_load_si128((__m128i*)b);
+
+ imagx = _mm_srli_si128 (x, 1);
+ imagx = _mm_and_si128 (imagx, mult1);
+ realx = _mm_and_si128 (x, mult1);
+
+ imagy = _mm_srli_si128 (y, 1);
+ imagy = _mm_and_si128 (imagy, mult1);
+ realy = _mm_and_si128 (y, mult1);
+
+ realx_mult_realy = _mm_mullo_epi16 (realx, realy);
+ imagx_mult_imagy = _mm_mullo_epi16 (imagx, imagy);
+ realx_mult_imagy = _mm_mullo_epi16 (realx, imagy);
+ imagx_mult_realy = _mm_mullo_epi16 (imagx, realy);
+
+ realc = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+ imagc = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+
+ realcacc = _mm_add_epi16 (realcacc, realc);
+ imagcacc = _mm_add_epi16 (imagcacc, imagc);
+
+ a += 8;
+ b += 8;
+ }
+
+ imagcacc = _mm_slli_si128 (imagcacc, 1);
+
+ totalc = _mm_blendv_epi8 (imagcacc, realcacc, mult1);
+
+ __VOLK_ATTR_ALIGNED(16) lv_8sc_t dotProductVector[8];
+
+ _mm_store_si128((__m128i*)dotProductVector,totalc); // Store the results back into the dot product vector
+
+ for (int i = 0; i<8; ++i)
+ {
+ dotProduct += dotProductVector[i];
+ }
+ }
+
+ for (int i = 0; i<(num_points % 8); ++i)
+ {
+ dotProduct += (*a++) * (*b++);
+ }
+
+ *result = dotProduct;
+}
+
+#endif /*LV_HAVE_SSE4_1*/
+
+#ifdef LV_HAVE_ORC
+/*!
+ \brief Multiplies the two input complex vectors and accumulates them, storing the result in the third vector
+ \param cVector The vector where the accumulated result will be stored
+ \param aVector One of the vectors to be multiplied and accumulated
+ \param bVector One of the vectors to be multiplied and accumulated
+ \param num_points The number of complex values in aVector and bVector to be multiplied together, accumulated and stored into cVector
+ */
+extern void volk_gnsssdr_8ic_x2_dot_prod_8ic_a_orc_impl(short* resRealShort, short* resImagShort, const lv_8sc_t* input, const lv_8sc_t* taps, unsigned int num_points);
+static inline void volk_gnsssdr_8ic_x2_dot_prod_8ic_u_orc(lv_8sc_t* result, const lv_8sc_t* input, const lv_8sc_t* taps, unsigned int num_points){
+
+ short resReal = 0;
+ char* resRealChar = (char*)&resReal;
+ resRealChar++;
+
+ short resImag = 0;
+ char* resImagChar = (char*)&resImag;
+ resImagChar++;
+
+ volk_gnsssdr_8ic_x2_dot_prod_8ic_a_orc_impl(&resReal, &resImag, input, taps, num_points);
+
+ *result = lv_cmake(*resRealChar, *resImagChar);
+}
+#endif /* LV_HAVE_ORC */
+
+#endif /*INCLUDED_volk_gnsssdr_8ic_x2_dot_prod_8ic_a_H*/
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_x2_multiply_8ic.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_x2_multiply_8ic.h
new file mode 100644
index 000000000..f8af2eb82
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_x2_multiply_8ic.h
@@ -0,0 +1,346 @@
+/*!
+ * \file volk_gnsssdr_8ic_x2_multiply_8ic.h
+ * \brief Volk protokernel: multiplies two 16 bits vectors
+ * \authors
+ * - Andrés Cecilia, 2014. a.cecilia.luque(at)gmail.com
+ *
+ *
+ * Volk protokernel that multiplies two 16 bits vectors (8 bits the real part
+ * and 8 bits the imaginary part)
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#ifndef INCLUDED_volk_gnsssdr_8ic_x2_multiply_8ic_u_H
+#define INCLUDED_volk_gnsssdr_8ic_x2_multiply_8ic_u_H
+
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE2
+#include "emmintrin.h"
+/*!
+ \brief Multiplies the two input complex vectors and stores their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be multiplied
+ \param bVector One of the vectors to be multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_x2_multiply_8ic_u_sse2(lv_8sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t* bVector, unsigned int num_points){
+
+ const unsigned int sse_iters = num_points / 8;
+
+ __m128i x, y, mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, realc, imagc, totalc;
+ lv_8sc_t* c = cVector;
+ const lv_8sc_t* a = aVector;
+ const lv_8sc_t* b = bVector;
+
+ mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255);
+
+ for(int number = 0;number < sse_iters; number++){
+
+ x = _mm_lddqu_si128((__m128i*)a);
+ y = _mm_lddqu_si128((__m128i*)b);
+
+ imagx = _mm_srli_si128 (x, 1);
+ imagx = _mm_and_si128 (imagx, mult1);
+ realx = _mm_and_si128 (x, mult1);
+
+ imagy = _mm_srli_si128 (y, 1);
+ imagy = _mm_and_si128 (imagy, mult1);
+ realy = _mm_and_si128 (y, mult1);
+
+ realx_mult_realy = _mm_mullo_epi16 (realx, realy);
+ imagx_mult_imagy = _mm_mullo_epi16 (imagx, imagy);
+ realx_mult_imagy = _mm_mullo_epi16 (realx, imagy);
+ imagx_mult_realy = _mm_mullo_epi16 (imagx, realy);
+
+ realc = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+ realc = _mm_and_si128 (realc, mult1);
+ imagc = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+ imagc = _mm_and_si128 (imagc, mult1);
+ imagc = _mm_slli_si128 (imagc, 1);
+
+ totalc = _mm_or_si128 (realc, imagc);
+
+ _mm_storeu_si128((__m128i*)c, totalc);
+
+ a += 8;
+ b += 8;
+ c += 8;
+ }
+
+ for (int i = 0; i<(num_points % 8); ++i)
+ {
+ *c++ = (*a++) * (*b++);
+ }
+}
+#endif /* LV_HAVE_SSE2 */
+
+#ifdef LV_HAVE_SSE4_1
+#include "smmintrin.h"
+/*!
+ \brief Multiplies the two input complex vectors and stores their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be multiplied
+ \param bVector One of the vectors to be multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_x2_multiply_8ic_u_sse4_1(lv_8sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t* bVector, unsigned int num_points){
+
+ const unsigned int sse_iters = num_points / 8;
+
+ __m128i x, y, zero;
+ __m128i mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, realc, imagc, totalc;
+ lv_8sc_t* c = cVector;
+ const lv_8sc_t* a = aVector;
+ const lv_8sc_t* b = bVector;
+
+ zero = _mm_setzero_si128();
+ mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255);
+
+ for(int number = 0;number < sse_iters; number++){
+
+ x = _mm_lddqu_si128((__m128i*)a);
+ y = _mm_lddqu_si128((__m128i*)b);
+
+ imagx = _mm_srli_si128 (x, 1);
+ imagx = _mm_and_si128 (imagx, mult1);
+ realx = _mm_and_si128 (x, mult1);
+
+ imagy = _mm_srli_si128 (y, 1);
+ imagy = _mm_and_si128 (imagy, mult1);
+ realy = _mm_and_si128 (y, mult1);
+
+ realx_mult_realy = _mm_mullo_epi16 (realx, realy);
+ imagx_mult_imagy = _mm_mullo_epi16 (imagx, imagy);
+ realx_mult_imagy = _mm_mullo_epi16 (realx, imagy);
+ imagx_mult_realy = _mm_mullo_epi16 (imagx, realy);
+
+ realc = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+ imagc = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+ imagc = _mm_slli_si128 (imagc, 1);
+
+ totalc = _mm_blendv_epi8 (imagc, realc, mult1);
+
+ _mm_storeu_si128((__m128i*)c, totalc);
+
+ a += 8;
+ b += 8;
+ c += 8;
+ }
+
+ for (int i = 0; i<(num_points % 8); ++i)
+ {
+ *c++ = (*a++) * (*b++);
+ }
+}
+#endif /* LV_HAVE_SSE4_1 */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Multiplies the two input complex vectors and stores their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be multiplied
+ \param bVector One of the vectors to be multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_x2_multiply_8ic_generic(lv_8sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t* bVector, unsigned int num_points){
+ lv_8sc_t* cPtr = cVector;
+ const lv_8sc_t* aPtr = aVector;
+ const lv_8sc_t* bPtr = bVector;
+
+ for(int number = 0; number < num_points; number++){
+ *cPtr++ = (*aPtr++) * (*bPtr++);
+ }
+}
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_volk_gnsssdr_8ic_x2_multiply_8ic_u_H */
+
+
+#ifndef INCLUDED_volk_gnsssdr_8ic_x2_multiply_8ic_a_H
+#define INCLUDED_volk_gnsssdr_8ic_x2_multiply_8ic_a_H
+
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE2
+#include "emmintrin.h"
+/*!
+ \brief Multiplies the two input complex vectors and stores their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be multiplied
+ \param bVector One of the vectors to be multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_x2_multiply_8ic_a_sse2(lv_8sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t* bVector, unsigned int num_points){
+
+ const unsigned int sse_iters = num_points / 8;
+
+ __m128i x, y, mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, realc, imagc, totalc;
+ lv_8sc_t* c = cVector;
+ const lv_8sc_t* a = aVector;
+ const lv_8sc_t* b = bVector;
+
+ mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255);
+
+ for(int number = 0;number < sse_iters; number++){
+
+ x = _mm_load_si128((__m128i*)a);
+ y = _mm_load_si128((__m128i*)b);
+
+ imagx = _mm_srli_si128 (x, 1);
+ imagx = _mm_and_si128 (imagx, mult1);
+ realx = _mm_and_si128 (x, mult1);
+
+ imagy = _mm_srli_si128 (y, 1);
+ imagy = _mm_and_si128 (imagy, mult1);
+ realy = _mm_and_si128 (y, mult1);
+
+ realx_mult_realy = _mm_mullo_epi16 (realx, realy);
+ imagx_mult_imagy = _mm_mullo_epi16 (imagx, imagy);
+ realx_mult_imagy = _mm_mullo_epi16 (realx, imagy);
+ imagx_mult_realy = _mm_mullo_epi16 (imagx, realy);
+
+ realc = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+ realc = _mm_and_si128 (realc, mult1);
+ imagc = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+ imagc = _mm_and_si128 (imagc, mult1);
+ imagc = _mm_slli_si128 (imagc, 1);
+
+ totalc = _mm_or_si128 (realc, imagc);
+
+ _mm_store_si128((__m128i*)c, totalc);
+
+ a += 8;
+ b += 8;
+ c += 8;
+ }
+
+ for (int i = 0; i<(num_points % 8); ++i)
+ {
+ *c++ = (*a++) * (*b++);
+ }
+}
+#endif /* LV_HAVE_SSE2 */
+
+#ifdef LV_HAVE_SSE4_1
+#include "smmintrin.h"
+/*!
+ \brief Multiplies the two input complex vectors and stores their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be multiplied
+ \param bVector One of the vectors to be multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_x2_multiply_8ic_a_sse4_1(lv_8sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t* bVector, unsigned int num_points){
+
+ const unsigned int sse_iters = num_points / 8;
+
+ __m128i x, y, zero;
+ __m128i mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, realc, imagc, totalc;
+ lv_8sc_t* c = cVector;
+ const lv_8sc_t* a = aVector;
+ const lv_8sc_t* b = bVector;
+
+ zero = _mm_setzero_si128();
+ mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255);
+
+ for(int number = 0;number < sse_iters; number++){
+
+ x = _mm_load_si128((__m128i*)a);
+ y = _mm_load_si128((__m128i*)b);
+
+ imagx = _mm_srli_si128 (x, 1);
+ imagx = _mm_and_si128 (imagx, mult1);
+ realx = _mm_and_si128 (x, mult1);
+
+ imagy = _mm_srli_si128 (y, 1);
+ imagy = _mm_and_si128 (imagy, mult1);
+ realy = _mm_and_si128 (y, mult1);
+
+ realx_mult_realy = _mm_mullo_epi16 (realx, realy);
+ imagx_mult_imagy = _mm_mullo_epi16 (imagx, imagy);
+ realx_mult_imagy = _mm_mullo_epi16 (realx, imagy);
+ imagx_mult_realy = _mm_mullo_epi16 (imagx, realy);
+
+ realc = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+ imagc = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+ imagc = _mm_slli_si128 (imagc, 1);
+
+ totalc = _mm_blendv_epi8 (imagc, realc, mult1);
+
+ _mm_store_si128((__m128i*)c, totalc);
+
+ a += 8;
+ b += 8;
+ c += 8;
+ }
+
+ for (int i = 0; i<(num_points % 8); ++i)
+ {
+ *c++ = (*a++) * (*b++);
+ }
+}
+#endif /* LV_HAVE_SSE4_1 */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Multiplies the two input complex vectors and stores their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be multiplied
+ \param bVector One of the vectors to be multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+static inline void volk_gnsssdr_8ic_x2_multiply_8ic_a_generic(lv_8sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t* bVector, unsigned int num_points){
+ lv_8sc_t* cPtr = cVector;
+ const lv_8sc_t* aPtr = aVector;
+ const lv_8sc_t* bPtr = bVector;
+
+ for(int number = 0; number < num_points; number++){
+ *cPtr++ = (*aPtr++) * (*bPtr++);
+ }
+
+}
+#endif /* LV_HAVE_GENERIC */
+
+#ifdef LV_HAVE_ORC
+/*!
+ \brief Multiplies the two input complex vectors and stores their results in the third vector
+ \param cVector The vector where the results will be stored
+ \param aVector One of the vectors to be multiplied
+ \param bVector One of the vectors to be multiplied
+ \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
+ */
+extern void volk_gnsssdr_8ic_x2_multiply_8ic_a_orc_impl(lv_8sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t* bVector, unsigned int num_points);
+static inline void volk_gnsssdr_8ic_x2_multiply_8ic_u_orc(lv_8sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t* bVector, unsigned int num_points){
+ volk_gnsssdr_8ic_x2_multiply_8ic_a_orc_impl(cVector, aVector, bVector, num_points);
+}
+#endif /* LV_HAVE_ORC */
+
+#endif /* INCLUDED_volk_gnsssdr_8ic_x2_multiply_8ic_a_H */
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3.h
new file mode 100644
index 000000000..fcbebdde3
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3.h
@@ -0,0 +1,882 @@
+/*!
+ * \file volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3.h
+ * \brief Volk protokernel: performs the carrier wipe-off mixing and the Early, Prompt, and Late correlation with 16 bits vectors
+ * \authors
+ * - Andrés Cecilia, 2014. a.cecilia.luque(at)gmail.com
+ *
+ *
+ * Volk protokernel that performs the carrier wipe-off mixing and the
+ * Early, Prompt, and Late correlation with 16 bits vectors (8 bits the
+ * real part and 8 bits the imaginary part):
+ * - The carrier wipe-off is done by multiplying the input signal by the
+ * carrier (multiplication of 16 bits vectors) It returns the input
+ * signal in base band (BB)
+ * - Early values are calculated by multiplying the input signal in BB by the
+ * early code (multiplication of 16 bits vectors), accumulating the results
+ * - Prompt values are calculated by multiplying the input signal in BB by the
+ * prompt code (multiplication of 16 bits vectors), accumulating the results
+ * - Late values are calculated by multiplying the input signal in BB by the
+ * late code (multiplication of 16 bits vectors), accumulating the results
+ *
+ * -------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2014 (see AUTHORS file for a list of contributors)
+ *
+ * GNSS-SDR is a software defined Global Navigation
+ * Satellite Systems receiver
+ *
+ * This file is part of GNSS-SDR.
+ *
+ * GNSS-SDR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * GNSS-SDR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNSS-SDR. If not, see .
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#ifndef INCLUDED_gnsssdr_volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3_u_H
+#define INCLUDED_gnsssdr_volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3_u_H
+
+#include
+#include
+#include
+#include
+#include
+
+#ifdef LV_HAVE_SSE4_1
+#include "smmintrin.h"
+ /*!
+ \brief Performs the carrier wipe-off mixing and the Early, Prompt, and Late correlation
+ \param input The input signal input
+ \param carrier The carrier signal input
+ \param E_code Early PRN code replica input
+ \param P_code Early PRN code replica input
+ \param L_code Early PRN code replica input
+ \param E_out Early correlation output
+ \param P_out Early correlation output
+ \param L_out Early correlation output
+ \param num_points The number of complex values in vectors
+ */
+static inline void volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3_u_sse4_1(lv_32fc_t* E_out, lv_32fc_t* P_out, lv_32fc_t* L_out, const lv_8sc_t* input, const lv_8sc_t* carrier, const lv_8sc_t* E_code, const lv_8sc_t* P_code, const lv_8sc_t* L_code, unsigned int num_points)
+{
+ const unsigned int sse_iters = num_points / 8;
+
+ __m128i x, y, real_bb_signal_sample, imag_bb_signal_sample, real_E_code_acc, imag_E_code_acc, real_L_code_acc, imag_L_code_acc, real_P_code_acc, imag_P_code_acc;
+ __m128i mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, output, real_output, imag_output;
+
+ const lv_8sc_t* input_ptr = input;
+ const lv_8sc_t* carrier_ptr = carrier;
+
+ const lv_8sc_t* E_code_ptr = E_code;
+ lv_8sc_t* E_out_ptr = E_out;
+ const lv_8sc_t* L_code_ptr = L_code;
+ lv_8sc_t* L_out_ptr = L_out;
+ const lv_8sc_t* P_code_ptr = P_code;
+ lv_8sc_t* P_out_ptr = P_out;
+
+ *E_out_ptr = 0;
+ *P_out_ptr = 0;
+ *L_out_ptr = 0;
+
+ mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255);
+
+ real_E_code_acc = _mm_setzero_si128();
+ imag_E_code_acc = _mm_setzero_si128();
+ real_L_code_acc = _mm_setzero_si128();
+ imag_L_code_acc = _mm_setzero_si128();
+ real_P_code_acc = _mm_setzero_si128();
+ imag_P_code_acc = _mm_setzero_si128();
+
+ if (sse_iters>0)
+ {
+ for(int number = 0;number < sse_iters; number++){
+
+ //Perform the carrier wipe-off
+ x = _mm_lddqu_si128((__m128i*)input_ptr);
+ y = _mm_lddqu_si128((__m128i*)carrier_ptr);
+
+ imagx = _mm_srli_si128 (x, 1);
+ imagx = _mm_and_si128 (imagx, mult1);
+ realx = _mm_and_si128 (x, mult1);
+
+ imagy = _mm_srli_si128 (y, 1);
+ imagy = _mm_and_si128 (imagy, mult1);
+ realy = _mm_and_si128 (y, mult1);
+
+ realx_mult_realy = _mm_mullo_epi16 (realx, realy);
+ imagx_mult_imagy = _mm_mullo_epi16 (imagx, imagy);
+ realx_mult_imagy = _mm_mullo_epi16 (realx, imagy);
+ imagx_mult_realy = _mm_mullo_epi16 (imagx, realy);
+
+ real_bb_signal_sample = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+ imag_bb_signal_sample = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+
+ //Get early values
+ y = _mm_lddqu_si128((__m128i*)E_code_ptr);
+
+ imagy = _mm_srli_si128 (y, 1);
+ imagy = _mm_and_si128 (imagy, mult1);
+ realy = _mm_and_si128 (y, mult1);
+
+ realx_mult_realy = _mm_mullo_epi16 (real_bb_signal_sample, realy);
+ imagx_mult_imagy = _mm_mullo_epi16 (imag_bb_signal_sample, imagy);
+ realx_mult_imagy = _mm_mullo_epi16 (real_bb_signal_sample, imagy);
+ imagx_mult_realy = _mm_mullo_epi16 (imag_bb_signal_sample, realy);
+
+ real_output = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+ imag_output = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+
+ real_E_code_acc = _mm_add_epi16 (real_E_code_acc, real_output);
+ imag_E_code_acc = _mm_add_epi16 (imag_E_code_acc, imag_output);
+
+ //Get late values
+ y = _mm_lddqu_si128((__m128i*)L_code_ptr);
+
+ imagy = _mm_srli_si128 (y, 1);
+ imagy = _mm_and_si128 (imagy, mult1);
+ realy = _mm_and_si128 (y, mult1);
+
+ realx_mult_realy = _mm_mullo_epi16 (real_bb_signal_sample, realy);
+ imagx_mult_imagy = _mm_mullo_epi16 (imag_bb_signal_sample, imagy);
+ realx_mult_imagy = _mm_mullo_epi16 (real_bb_signal_sample, imagy);
+ imagx_mult_realy = _mm_mullo_epi16 (imag_bb_signal_sample, realy);
+
+ real_output = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+ imag_output = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+
+ real_L_code_acc = _mm_add_epi16 (real_L_code_acc, real_output);
+ imag_L_code_acc = _mm_add_epi16 (imag_L_code_acc, imag_output);
+
+ //Get prompt values
+ y = _mm_lddqu_si128((__m128i*)P_code_ptr);
+
+ imagy = _mm_srli_si128 (y, 1);
+ imagy = _mm_and_si128 (imagy, mult1);
+ realy = _mm_and_si128 (y, mult1);
+
+ realx_mult_realy = _mm_mullo_epi16 (real_bb_signal_sample, realy);
+ imagx_mult_imagy = _mm_mullo_epi16 (imag_bb_signal_sample, imagy);
+ realx_mult_imagy = _mm_mullo_epi16 (real_bb_signal_sample, imagy);
+ imagx_mult_realy = _mm_mullo_epi16 (imag_bb_signal_sample, realy);
+
+ real_output = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+ imag_output = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+
+ real_P_code_acc = _mm_add_epi16 (real_P_code_acc, real_output);
+ imag_P_code_acc = _mm_add_epi16 (imag_P_code_acc, imag_output);
+
+ input_ptr += 8;
+ carrier_ptr += 8;
+ E_code_ptr += 8;
+ L_code_ptr += 8;
+ P_code_ptr += 8;
+ }
+
+ __VOLK_ATTR_ALIGNED(16) lv_16sc_t E_dotProductVector[8];
+ __VOLK_ATTR_ALIGNED(16) lv_16sc_t L_dotProductVector[8];
+ __VOLK_ATTR_ALIGNED(16) lv_16sc_t P_dotProductVector[8];
+
+ imag_E_code_acc = _mm_slli_si128 (imag_E_code_acc, 1);
+ output = _mm_blendv_epi8 (imag_E_code_acc, real_E_code_acc, mult1);
+ _mm_storeu_si128((__m128i*)E_dotProductVector, output);
+
+ imag_L_code_acc = _mm_slli_si128 (imag_L_code_acc, 1);
+ output = _mm_blendv_epi8 (imag_L_code_acc, real_L_code_acc, mult1);
+ _mm_storeu_si128((__m128i*)L_dotProductVector, output);
+
+ imag_P_code_acc = _mm_slli_si128 (imag_P_code_acc, 1);
+ output = _mm_blendv_epi8 (imag_P_code_acc, real_P_code_acc, mult1);
+ _mm_storeu_si128((__m128i*)P_dotProductVector, output);
+
+ for (int i = 0; i<8; ++i)
+ {
+ *E_out_ptr += E_dotProductVector[i];
+ *L_out_ptr += L_dotProductVector[i];
+ *P_out_ptr += P_dotProductVector[i];
+ }
+ }
+
+ lv_8sc_t bb_signal_sample;
+ for(int i=0; i < num_points%8; ++i)
+ {
+ //Perform the carrier wipe-off
+ bb_signal_sample = (*input_ptr++) * (*carrier_ptr++);
+ // Now get early, late, and prompt values for each
+ *E_out_ptr += bb_signal_sample * (*E_code_ptr++);
+ *P_out_ptr += bb_signal_sample * (*P_code_ptr++);
+ *L_out_ptr += bb_signal_sample * (*L_code_ptr++);
+ }
+}
+
+#endif /* LV_HAVE_SSE4_1 */
+
+//#ifdef LV_HAVE_SSE2
+//#include "emmintrin.h"
+///*!
+// \brief Performs the carrier wipe-off mixing and the Early, Prompt, and Late correlation
+// \param input The input signal input
+// \param carrier The carrier signal input
+// \param E_code Early PRN code replica input
+// \param P_code Early PRN code replica input
+// \param L_code Early PRN code replica input
+// \param E_out Early correlation output
+// \param P_out Early correlation output
+// \param L_out Early correlation output
+// \param num_points The number of complex values in vectors
+// */
+//static inline void volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3_u_sse2(lv_8sc_t* E_out, lv_8sc_t* P_out, lv_8sc_t* L_out, const lv_8sc_t* input, const lv_8sc_t* carrier, const lv_8sc_t* E_code, const lv_8sc_t* P_code, const lv_8sc_t* L_code, unsigned int num_points)
+//{
+// const unsigned int sse_iters = num_points / 8;
+//
+// __m128i x, y, real_bb_signal_sample, imag_bb_signal_sample, real_E_code_acc, imag_E_code_acc, real_L_code_acc, imag_L_code_acc, real_P_code_acc, imag_P_code_acc;
+// __m128i mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, output, real_output, imag_output;
+//
+// const lv_8sc_t* input_ptr = input;
+// const lv_8sc_t* carrier_ptr = carrier;
+//
+// const lv_8sc_t* E_code_ptr = E_code;
+// lv_8sc_t* E_out_ptr = E_out;
+// const lv_8sc_t* L_code_ptr = L_code;
+// lv_8sc_t* L_out_ptr = L_out;
+// const lv_8sc_t* P_code_ptr = P_code;
+// lv_8sc_t* P_out_ptr = P_out;
+//
+// *E_out_ptr = 0;
+// *P_out_ptr = 0;
+// *L_out_ptr = 0;
+//
+// mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255);
+//
+// real_E_code_acc = _mm_setzero_si128();
+// imag_E_code_acc = _mm_setzero_si128();
+// real_L_code_acc = _mm_setzero_si128();
+// imag_L_code_acc = _mm_setzero_si128();
+// real_P_code_acc = _mm_setzero_si128();
+// imag_P_code_acc = _mm_setzero_si128();
+//
+// if (sse_iters>0)
+// {
+// for(int number = 0;number < sse_iters; number++){
+//
+// //Perform the carrier wipe-off
+// x = _mm_lddqu_si128((__m128i*)input_ptr);
+// y = _mm_lddqu_si128((__m128i*)carrier_ptr);
+//
+// imagx = _mm_srli_si128 (x, 1);
+// imagx = _mm_and_si128 (imagx, mult1);
+// realx = _mm_and_si128 (x, mult1);
+//
+// imagy = _mm_srli_si128 (y, 1);
+// imagy = _mm_and_si128 (imagy, mult1);
+// realy = _mm_and_si128 (y, mult1);
+//
+// realx_mult_realy = _mm_mullo_epi16 (realx, realy);
+// imagx_mult_imagy = _mm_mullo_epi16 (imagx, imagy);
+// realx_mult_imagy = _mm_mullo_epi16 (realx, imagy);
+// imagx_mult_realy = _mm_mullo_epi16 (imagx, realy);
+//
+// real_bb_signal_sample = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+// imag_bb_signal_sample = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+//
+// //Get early values
+// y = _mm_lddqu_si128((__m128i*)E_code_ptr);
+//
+// imagy = _mm_srli_si128 (y, 1);
+// imagy = _mm_and_si128 (imagy, mult1);
+// realy = _mm_and_si128 (y, mult1);
+//
+// realx_mult_realy = _mm_mullo_epi16 (real_bb_signal_sample, realy);
+// imagx_mult_imagy = _mm_mullo_epi16 (imag_bb_signal_sample, imagy);
+// realx_mult_imagy = _mm_mullo_epi16 (real_bb_signal_sample, imagy);
+// imagx_mult_realy = _mm_mullo_epi16 (imag_bb_signal_sample, realy);
+//
+// real_output = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+// imag_output = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+//
+// real_E_code_acc = _mm_add_epi16 (real_E_code_acc, real_output);
+// imag_E_code_acc = _mm_add_epi16 (imag_E_code_acc, imag_output);
+//
+// //Get late values
+// y = _mm_lddqu_si128((__m128i*)L_code_ptr);
+//
+// imagy = _mm_srli_si128 (y, 1);
+// imagy = _mm_and_si128 (imagy, mult1);
+// realy = _mm_and_si128 (y, mult1);
+//
+// realx_mult_realy = _mm_mullo_epi16 (real_bb_signal_sample, realy);
+// imagx_mult_imagy = _mm_mullo_epi16 (imag_bb_signal_sample, imagy);
+// realx_mult_imagy = _mm_mullo_epi16 (real_bb_signal_sample, imagy);
+// imagx_mult_realy = _mm_mullo_epi16 (imag_bb_signal_sample, realy);
+//
+// real_output = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+// imag_output = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+//
+// real_L_code_acc = _mm_add_epi16 (real_L_code_acc, real_output);
+// imag_L_code_acc = _mm_add_epi16 (imag_L_code_acc, imag_output);
+//
+// //Get prompt values
+// y = _mm_lddqu_si128((__m128i*)P_code_ptr);
+//
+// imagy = _mm_srli_si128 (y, 1);
+// imagy = _mm_and_si128 (imagy, mult1);
+// realy = _mm_and_si128 (y, mult1);
+//
+// realx_mult_realy = _mm_mullo_epi16 (real_bb_signal_sample, realy);
+// imagx_mult_imagy = _mm_mullo_epi16 (imag_bb_signal_sample, imagy);
+// realx_mult_imagy = _mm_mullo_epi16 (real_bb_signal_sample, imagy);
+// imagx_mult_realy = _mm_mullo_epi16 (imag_bb_signal_sample, realy);
+//
+// real_output = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+// imag_output = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+//
+// real_P_code_acc = _mm_add_epi16 (real_P_code_acc, real_output);
+// imag_P_code_acc = _mm_add_epi16 (imag_P_code_acc, imag_output);
+//
+// input_ptr += 8;
+// carrier_ptr += 8;
+// E_code_ptr += 8;
+// L_code_ptr += 8;
+// P_code_ptr += 8;
+// }
+//
+// __VOLK_ATTR_ALIGNED(16) lv_8sc_t E_dotProductVector[8];
+// __VOLK_ATTR_ALIGNED(16) lv_8sc_t L_dotProductVector[8];
+// __VOLK_ATTR_ALIGNED(16) lv_8sc_t P_dotProductVector[8];
+//
+// real_E_code_acc = _mm_and_si128 (real_E_code_acc, mult1);
+// imag_E_code_acc = _mm_and_si128 (imag_E_code_acc, mult1);
+// imag_E_code_acc = _mm_slli_si128 (imag_E_code_acc, 1);
+// output = _mm_or_si128 (real_E_code_acc, imag_E_code_acc);
+// _mm_storeu_si128((__m128i*)E_dotProductVector, output);
+//
+// real_L_code_acc = _mm_and_si128 (real_L_code_acc, mult1);
+// imag_L_code_acc = _mm_and_si128 (imag_L_code_acc, mult1);
+// imag_L_code_acc = _mm_slli_si128 (imag_L_code_acc, 1);
+// output = _mm_or_si128 (real_L_code_acc, imag_L_code_acc);
+// _mm_storeu_si128((__m128i*)L_dotProductVector, output);
+//
+// real_P_code_acc = _mm_and_si128 (real_P_code_acc, mult1);
+// imag_P_code_acc = _mm_and_si128 (imag_P_code_acc, mult1);
+// imag_P_code_acc = _mm_slli_si128 (imag_P_code_acc, 1);
+// output = _mm_or_si128 (real_P_code_acc, imag_P_code_acc);
+// _mm_storeu_si128((__m128i*)P_dotProductVector, output);
+//
+// for (int i = 0; i<8; ++i)
+// {
+// *E_out_ptr += E_dotProductVector[i];
+// *L_out_ptr += L_dotProductVector[i];
+// *P_out_ptr += P_dotProductVector[i];
+// }
+// }
+//
+// lv_8sc_t bb_signal_sample;
+// for(int i=0; i < num_points%8; ++i)
+// {
+// //Perform the carrier wipe-off
+// bb_signal_sample = (*input_ptr++) * (*carrier_ptr++);
+// // Now get early, late, and prompt values for each
+// *E_out_ptr += bb_signal_sample * (*E_code_ptr++);
+// *P_out_ptr += bb_signal_sample * (*P_code_ptr++);
+// *L_out_ptr += bb_signal_sample * (*L_code_ptr++);
+// }
+//}
+//
+//#endif /* LV_HAVE_SSE2 */
+
+#ifdef LV_HAVE_GENERIC
+/*!
+ \brief Performs the carrier wipe-off mixing and the Early, Prompt, and Late correlation
+ \param input The input signal input
+ \param carrier The carrier signal input
+ \param E_code Early PRN code replica input
+ \param P_code Early PRN code replica input
+ \param L_code Early PRN code replica input
+ \param E_out Early correlation output
+ \param P_out Early correlation output
+ \param L_out Early correlation output
+ \param num_points The number of complex values in vectors
+ */
+static inline void volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3_generic(lv_32fc_t* E_out, lv_32fc_t* P_out, lv_32fc_t* L_out, const lv_8sc_t* input, const lv_8sc_t* carrier, const lv_8sc_t* E_code, const lv_8sc_t* P_code, const lv_8sc_t* L_code, unsigned int num_points)
+{
+ lv_8sc_t bb_signal_sample;
+ lv_16sc_t tmp1;
+ lv_16sc_t tmp2;
+ lv_16sc_t tmp3;
+
+ bb_signal_sample = lv_cmake(0, 0);
+
+ *E_out = 0;
+ *P_out = 0;
+ *L_out = 0;
+ // perform Early, Prompt and Late correlation
+ for(int i=0; i < num_points; ++i)
+ {
+ //Perform the carrier wipe-off
+ bb_signal_sample = input[i] * carrier[i];
+
+ tmp1 = bb_signal_sample * E_code[i];
+ tmp2 = bb_signal_sample * P_code[i];
+ tmp3 = bb_signal_sample * L_code[i];
+
+ // Now get early, late, and prompt values for each
+ *E_out += tmp1;
+ *P_out += tmp2;
+ *L_out += tmp3;
+ }
+}
+
+#endif /* LV_HAVE_GENERIC */
+
+#endif /* INCLUDED_gnsssdr_volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3_u_H */
+
+
+//#ifndef INCLUDED_gnsssdr_volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3_a_H
+//#define INCLUDED_gnsssdr_volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3_a_H
+//
+//#include
+//#include
+//#include
+//#include
+//#include
+//
+//#ifdef LV_HAVE_SSE4_1
+//#include "smmintrin.h"
+///*!
+// \brief Performs the carrier wipe-off mixing and the Early, Prompt, and Late correlation
+// \param input The input signal input
+// \param carrier The carrier signal input
+// \param E_code Early PRN code replica input
+// \param P_code Early PRN code replica input
+// \param L_code Early PRN code replica input
+// \param E_out Early correlation output
+// \param P_out Early correlation output
+// \param L_out Early correlation output
+// \param num_points The number of complex values in vectors
+// */
+//static inline void volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3_a_sse4_1(lv_8sc_t* E_out, lv_8sc_t* P_out, lv_8sc_t* L_out, const lv_8sc_t* input, const lv_8sc_t* carrier, const lv_8sc_t* E_code, const lv_8sc_t* P_code, const lv_8sc_t* L_code, unsigned int num_points)
+//{
+// const unsigned int sse_iters = num_points / 8;
+//
+// __m128i x, y, real_bb_signal_sample, imag_bb_signal_sample, real_E_code_acc, imag_E_code_acc, real_L_code_acc, imag_L_code_acc, real_P_code_acc, imag_P_code_acc;
+// __m128i mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, output, real_output, imag_output;
+//
+// const lv_8sc_t* input_ptr = input;
+// const lv_8sc_t* carrier_ptr = carrier;
+//
+// const lv_8sc_t* E_code_ptr = E_code;
+// lv_8sc_t* E_out_ptr = E_out;
+// const lv_8sc_t* L_code_ptr = L_code;
+// lv_8sc_t* L_out_ptr = L_out;
+// const lv_8sc_t* P_code_ptr = P_code;
+// lv_8sc_t* P_out_ptr = P_out;
+//
+// *E_out_ptr = 0;
+// *P_out_ptr = 0;
+// *L_out_ptr = 0;
+//
+// mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255);
+//
+// real_E_code_acc = _mm_setzero_si128();
+// imag_E_code_acc = _mm_setzero_si128();
+// real_L_code_acc = _mm_setzero_si128();
+// imag_L_code_acc = _mm_setzero_si128();
+// real_P_code_acc = _mm_setzero_si128();
+// imag_P_code_acc = _mm_setzero_si128();
+//
+// if (sse_iters>0)
+// {
+// for(int number = 0;number < sse_iters; number++){
+//
+// //Perform the carrier wipe-off
+// x = _mm_load_si128((__m128i*)input_ptr);
+// y = _mm_load_si128((__m128i*)carrier_ptr);
+//
+// imagx = _mm_srli_si128 (x, 1);
+// imagx = _mm_and_si128 (imagx, mult1);
+// realx = _mm_and_si128 (x, mult1);
+//
+// imagy = _mm_srli_si128 (y, 1);
+// imagy = _mm_and_si128 (imagy, mult1);
+// realy = _mm_and_si128 (y, mult1);
+//
+// realx_mult_realy = _mm_mullo_epi16 (realx, realy);
+// imagx_mult_imagy = _mm_mullo_epi16 (imagx, imagy);
+// realx_mult_imagy = _mm_mullo_epi16 (realx, imagy);
+// imagx_mult_realy = _mm_mullo_epi16 (imagx, realy);
+//
+// real_bb_signal_sample = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+// imag_bb_signal_sample = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+//
+// //Get early values
+// y = _mm_load_si128((__m128i*)E_code_ptr);
+//
+// imagy = _mm_srli_si128 (y, 1);
+// imagy = _mm_and_si128 (imagy, mult1);
+// realy = _mm_and_si128 (y, mult1);
+//
+// realx_mult_realy = _mm_mullo_epi16 (real_bb_signal_sample, realy);
+// imagx_mult_imagy = _mm_mullo_epi16 (imag_bb_signal_sample, imagy);
+// realx_mult_imagy = _mm_mullo_epi16 (real_bb_signal_sample, imagy);
+// imagx_mult_realy = _mm_mullo_epi16 (imag_bb_signal_sample, realy);
+//
+// real_output = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+// imag_output = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+//
+// real_E_code_acc = _mm_add_epi16 (real_E_code_acc, real_output);
+// imag_E_code_acc = _mm_add_epi16 (imag_E_code_acc, imag_output);
+//
+// //Get late values
+// y = _mm_load_si128((__m128i*)L_code_ptr);
+//
+// imagy = _mm_srli_si128 (y, 1);
+// imagy = _mm_and_si128 (imagy, mult1);
+// realy = _mm_and_si128 (y, mult1);
+//
+// realx_mult_realy = _mm_mullo_epi16 (real_bb_signal_sample, realy);
+// imagx_mult_imagy = _mm_mullo_epi16 (imag_bb_signal_sample, imagy);
+// realx_mult_imagy = _mm_mullo_epi16 (real_bb_signal_sample, imagy);
+// imagx_mult_realy = _mm_mullo_epi16 (imag_bb_signal_sample, realy);
+//
+// real_output = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+// imag_output = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+//
+// real_L_code_acc = _mm_add_epi16 (real_L_code_acc, real_output);
+// imag_L_code_acc = _mm_add_epi16 (imag_L_code_acc, imag_output);
+//
+// //Get prompt values
+// y = _mm_load_si128((__m128i*)P_code_ptr);
+//
+// imagy = _mm_srli_si128 (y, 1);
+// imagy = _mm_and_si128 (imagy, mult1);
+// realy = _mm_and_si128 (y, mult1);
+//
+// realx_mult_realy = _mm_mullo_epi16 (real_bb_signal_sample, realy);
+// imagx_mult_imagy = _mm_mullo_epi16 (imag_bb_signal_sample, imagy);
+// realx_mult_imagy = _mm_mullo_epi16 (real_bb_signal_sample, imagy);
+// imagx_mult_realy = _mm_mullo_epi16 (imag_bb_signal_sample, realy);
+//
+// real_output = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+// imag_output = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+//
+// real_P_code_acc = _mm_add_epi16 (real_P_code_acc, real_output);
+// imag_P_code_acc = _mm_add_epi16 (imag_P_code_acc, imag_output);
+//
+// input_ptr += 8;
+// carrier_ptr += 8;
+// E_code_ptr += 8;
+// L_code_ptr += 8;
+// P_code_ptr += 8;
+// }
+//
+// __VOLK_ATTR_ALIGNED(16) lv_8sc_t E_dotProductVector[8];
+// __VOLK_ATTR_ALIGNED(16) lv_8sc_t L_dotProductVector[8];
+// __VOLK_ATTR_ALIGNED(16) lv_8sc_t P_dotProductVector[8];
+//
+// imag_E_code_acc = _mm_slli_si128 (imag_E_code_acc, 1);
+// output = _mm_blendv_epi8 (imag_E_code_acc, real_E_code_acc, mult1);
+// _mm_store_si128((__m128i*)E_dotProductVector, output);
+//
+// imag_L_code_acc = _mm_slli_si128 (imag_L_code_acc, 1);
+// output = _mm_blendv_epi8 (imag_L_code_acc, real_L_code_acc, mult1);
+// _mm_store_si128((__m128i*)L_dotProductVector, output);
+//
+// imag_P_code_acc = _mm_slli_si128 (imag_P_code_acc, 1);
+// output = _mm_blendv_epi8 (imag_P_code_acc, real_P_code_acc, mult1);
+// _mm_store_si128((__m128i*)P_dotProductVector, output);
+//
+// for (int i = 0; i<8; ++i)
+// {
+// *E_out_ptr += E_dotProductVector[i];
+// *L_out_ptr += L_dotProductVector[i];
+// *P_out_ptr += P_dotProductVector[i];
+// }
+// }
+//
+// lv_8sc_t bb_signal_sample;
+// for(int i=0; i < num_points%8; ++i)
+// {
+// //Perform the carrier wipe-off
+// bb_signal_sample = (*input_ptr++) * (*carrier_ptr++);
+// // Now get early, late, and prompt values for each
+// *E_out_ptr += bb_signal_sample * (*E_code_ptr++);
+// *P_out_ptr += bb_signal_sample * (*P_code_ptr++);
+// *L_out_ptr += bb_signal_sample * (*L_code_ptr++);
+// }
+//}
+//
+//#endif /* LV_HAVE_SSE4_1 */
+//
+//#ifdef LV_HAVE_SSE2
+//#include "emmintrin.h"
+///*!
+// \brief Performs the carrier wipe-off mixing and the Early, Prompt, and Late correlation
+// \param input The input signal input
+// \param carrier The carrier signal input
+// \param E_code Early PRN code replica input
+// \param P_code Early PRN code replica input
+// \param L_code Early PRN code replica input
+// \param E_out Early correlation output
+// \param P_out Early correlation output
+// \param L_out Early correlation output
+// \param num_points The number of complex values in vectors
+// */
+//static inline void volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3_a_sse2(lv_8sc_t* E_out, lv_8sc_t* P_out, lv_8sc_t* L_out, const lv_8sc_t* input, const lv_8sc_t* carrier, const lv_8sc_t* E_code, const lv_8sc_t* P_code, const lv_8sc_t* L_code, unsigned int num_points)
+//{
+// const unsigned int sse_iters = num_points / 8;
+//
+// __m128i x, y, real_bb_signal_sample, imag_bb_signal_sample, real_E_code_acc, imag_E_code_acc, real_L_code_acc, imag_L_code_acc, real_P_code_acc, imag_P_code_acc;
+// __m128i mult1, realx, imagx, realy, imagy, realx_mult_realy, imagx_mult_imagy, realx_mult_imagy, imagx_mult_realy, output, real_output, imag_output;
+//
+// const lv_8sc_t* input_ptr = input;
+// const lv_8sc_t* carrier_ptr = carrier;
+//
+// const lv_8sc_t* E_code_ptr = E_code;
+// lv_8sc_t* E_out_ptr = E_out;
+// const lv_8sc_t* L_code_ptr = L_code;
+// lv_8sc_t* L_out_ptr = L_out;
+// const lv_8sc_t* P_code_ptr = P_code;
+// lv_8sc_t* P_out_ptr = P_out;
+//
+// *E_out_ptr = 0;
+// *P_out_ptr = 0;
+// *L_out_ptr = 0;
+//
+// mult1 = _mm_set_epi8(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255);
+//
+// real_E_code_acc = _mm_setzero_si128();
+// imag_E_code_acc = _mm_setzero_si128();
+// real_L_code_acc = _mm_setzero_si128();
+// imag_L_code_acc = _mm_setzero_si128();
+// real_P_code_acc = _mm_setzero_si128();
+// imag_P_code_acc = _mm_setzero_si128();
+//
+// if (sse_iters>0)
+// {
+// for(int number = 0;number < sse_iters; number++){
+//
+// //Perform the carrier wipe-off
+// x = _mm_load_si128((__m128i*)input_ptr);
+// y = _mm_load_si128((__m128i*)carrier_ptr);
+//
+// imagx = _mm_srli_si128 (x, 1);
+// imagx = _mm_and_si128 (imagx, mult1);
+// realx = _mm_and_si128 (x, mult1);
+//
+// imagy = _mm_srli_si128 (y, 1);
+// imagy = _mm_and_si128 (imagy, mult1);
+// realy = _mm_and_si128 (y, mult1);
+//
+// realx_mult_realy = _mm_mullo_epi16 (realx, realy);
+// imagx_mult_imagy = _mm_mullo_epi16 (imagx, imagy);
+// realx_mult_imagy = _mm_mullo_epi16 (realx, imagy);
+// imagx_mult_realy = _mm_mullo_epi16 (imagx, realy);
+//
+// real_bb_signal_sample = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+// imag_bb_signal_sample = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+//
+// //Get early values
+// y = _mm_load_si128((__m128i*)E_code_ptr);
+//
+// imagy = _mm_srli_si128 (y, 1);
+// imagy = _mm_and_si128 (imagy, mult1);
+// realy = _mm_and_si128 (y, mult1);
+//
+// realx_mult_realy = _mm_mullo_epi16 (real_bb_signal_sample, realy);
+// imagx_mult_imagy = _mm_mullo_epi16 (imag_bb_signal_sample, imagy);
+// realx_mult_imagy = _mm_mullo_epi16 (real_bb_signal_sample, imagy);
+// imagx_mult_realy = _mm_mullo_epi16 (imag_bb_signal_sample, realy);
+//
+// real_output = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+// imag_output = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+//
+// real_E_code_acc = _mm_add_epi16 (real_E_code_acc, real_output);
+// imag_E_code_acc = _mm_add_epi16 (imag_E_code_acc, imag_output);
+//
+// //Get late values
+// y = _mm_load_si128((__m128i*)L_code_ptr);
+//
+// imagy = _mm_srli_si128 (y, 1);
+// imagy = _mm_and_si128 (imagy, mult1);
+// realy = _mm_and_si128 (y, mult1);
+//
+// realx_mult_realy = _mm_mullo_epi16 (real_bb_signal_sample, realy);
+// imagx_mult_imagy = _mm_mullo_epi16 (imag_bb_signal_sample, imagy);
+// realx_mult_imagy = _mm_mullo_epi16 (real_bb_signal_sample, imagy);
+// imagx_mult_realy = _mm_mullo_epi16 (imag_bb_signal_sample, realy);
+//
+// real_output = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+// imag_output = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+//
+// real_L_code_acc = _mm_add_epi16 (real_L_code_acc, real_output);
+// imag_L_code_acc = _mm_add_epi16 (imag_L_code_acc, imag_output);
+//
+// //Get prompt values
+// y = _mm_load_si128((__m128i*)P_code_ptr);
+//
+// imagy = _mm_srli_si128 (y, 1);
+// imagy = _mm_and_si128 (imagy, mult1);
+// realy = _mm_and_si128 (y, mult1);
+//
+// realx_mult_realy = _mm_mullo_epi16 (real_bb_signal_sample, realy);
+// imagx_mult_imagy = _mm_mullo_epi16 (imag_bb_signal_sample, imagy);
+// realx_mult_imagy = _mm_mullo_epi16 (real_bb_signal_sample, imagy);
+// imagx_mult_realy = _mm_mullo_epi16 (imag_bb_signal_sample, realy);
+//
+// real_output = _mm_sub_epi16 (realx_mult_realy, imagx_mult_imagy);
+// imag_output = _mm_add_epi16 (realx_mult_imagy, imagx_mult_realy);
+//
+// real_P_code_acc = _mm_add_epi16 (real_P_code_acc, real_output);
+// imag_P_code_acc = _mm_add_epi16 (imag_P_code_acc, imag_output);
+//
+// input_ptr += 8;
+// carrier_ptr += 8;
+// E_code_ptr += 8;
+// L_code_ptr += 8;
+// P_code_ptr += 8;
+// }
+//
+// __VOLK_ATTR_ALIGNED(16) lv_8sc_t E_dotProductVector[8];
+// __VOLK_ATTR_ALIGNED(16) lv_8sc_t L_dotProductVector[8];
+// __VOLK_ATTR_ALIGNED(16) lv_8sc_t P_dotProductVector[8];
+//
+// real_E_code_acc = _mm_and_si128 (real_E_code_acc, mult1);
+// imag_E_code_acc = _mm_and_si128 (imag_E_code_acc, mult1);
+// imag_E_code_acc = _mm_slli_si128 (imag_E_code_acc, 1);
+// output = _mm_or_si128 (real_E_code_acc, imag_E_code_acc);
+// _mm_store_si128((__m128i*)E_dotProductVector, output);
+//
+// real_L_code_acc = _mm_and_si128 (real_L_code_acc, mult1);
+// imag_L_code_acc = _mm_and_si128 (imag_L_code_acc, mult1);
+// imag_L_code_acc = _mm_slli_si128 (imag_L_code_acc, 1);
+// output = _mm_or_si128 (real_L_code_acc, imag_L_code_acc);
+// _mm_store_si128((__m128i*)L_dotProductVector, output);
+//
+// real_P_code_acc = _mm_and_si128 (real_P_code_acc, mult1);
+// imag_P_code_acc = _mm_and_si128 (imag_P_code_acc, mult1);
+// imag_P_code_acc = _mm_slli_si128 (imag_P_code_acc, 1);
+// output = _mm_or_si128 (real_P_code_acc, imag_P_code_acc);
+// _mm_store_si128((__m128i*)P_dotProductVector, output);
+//
+// for (int i = 0; i<8; ++i)
+// {
+// *E_out_ptr += E_dotProductVector[i];
+// *L_out_ptr += L_dotProductVector[i];
+// *P_out_ptr += P_dotProductVector[i];
+// }
+// }
+//
+// lv_8sc_t bb_signal_sample;
+// for(int i=0; i < num_points%8; ++i)
+// {
+// //Perform the carrier wipe-off
+// bb_signal_sample = (*input_ptr++) * (*carrier_ptr++);
+// // Now get early, late, and prompt values for each
+// *E_out_ptr += bb_signal_sample * (*E_code_ptr++);
+// *P_out_ptr += bb_signal_sample * (*P_code_ptr++);
+// *L_out_ptr += bb_signal_sample * (*L_code_ptr++);
+// }
+//}
+//
+//#endif /* LV_HAVE_SSE2 */
+//
+//#ifdef LV_HAVE_GENERIC
+///*!
+// \brief Performs the carrier wipe-off mixing and the Early, Prompt, and Late correlation
+// \param input The input signal input
+// \param carrier The carrier signal input
+// \param E_code Early PRN code replica input
+// \param P_code Early PRN code replica input
+// \param L_code Early PRN code replica input
+// \param E_out Early correlation output
+// \param P_out Early correlation output
+// \param L_out Early correlation output
+// \param num_points The number of complex values in vectors
+// */
+//static inline void volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3_a_generic(lv_8sc_t* E_out, lv_8sc_t* P_out, lv_8sc_t* L_out, const lv_8sc_t* input, const lv_8sc_t* carrier, const lv_8sc_t* E_code, const lv_8sc_t* P_code, const lv_8sc_t* L_code, unsigned int num_points)
+//{
+// lv_8sc_t bb_signal_sample;
+//
+// bb_signal_sample = lv_cmake(0, 0);
+//
+// *E_out = 0;
+// *P_out = 0;
+// *L_out = 0;
+// // perform Early, Prompt and Late correlation
+// for(int i=0; i < num_points; ++i)
+// {
+// //Perform the carrier wipe-off
+// bb_signal_sample = input[i] * carrier[i];
+// // Now get early, late, and prompt values for each
+// *E_out += bb_signal_sample * E_code[i];
+// *P_out += bb_signal_sample * P_code[i];
+// *L_out += bb_signal_sample * L_code[i];
+// }
+//}
+//
+//#endif /* LV_HAVE_GENERIC */
+//
+//#ifdef LV_HAVE_ORC
+///*!
+// \brief Performs the carrier wipe-off mixing and the Early, Prompt, and Late correlation
+// \param input The input signal input
+// \param carrier The carrier signal input
+// \param E_code Early PRN code replica input
+// \param P_code Early PRN code replica input
+// \param L_code Early PRN code replica input
+// \param E_out Early correlation output
+// \param P_out Early correlation output
+// \param L_out Early correlation output
+// \param num_points The number of complex values in vectors
+// */
+//
+//extern void volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3_first_a_orc_impl(short* E_out_real, short* E_out_imag, short* P_out_real, short* P_out_imag, const lv_8sc_t* input, const lv_8sc_t* carrier, const lv_8sc_t* E_code, const lv_8sc_t* P_code, unsigned int num_points);
+//extern void volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3_second_a_orc_impl(short* L_out_real, short* L_out_imag, const lv_8sc_t* input, const lv_8sc_t* carrier, const lv_8sc_t* L_code, unsigned int num_points);
+//static inline void volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3_u_orc(lv_8sc_t* E_out, lv_8sc_t* P_out, lv_8sc_t* L_out, const lv_8sc_t* input, const lv_8sc_t* carrier, const lv_8sc_t* E_code, const lv_8sc_t* P_code, const lv_8sc_t* L_code, unsigned int num_points){
+//
+// short E_out_real = 0;
+// short E_out_imag = 0;
+// char* E_out_real_c = (char*)&E_out_real;
+// E_out_real_c++;
+// char* E_out_imag_c = (char*)&E_out_imag;
+// E_out_imag_c++;
+//
+// short P_out_real = 0;
+// short P_out_imag = 0;
+// char* P_out_real_c = (char*)&P_out_real;
+// P_out_real_c++;
+// char* P_out_imag_c = (char*)&P_out_imag;
+// P_out_imag_c++;
+//
+// short L_out_real = 0;
+// short L_out_imag = 0;
+// char* L_out_real_c = (char*)&L_out_real;
+// L_out_real_c++;
+// char* L_out_imag_c = (char*)&L_out_imag;
+// L_out_imag_c++;
+//
+// volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3_first_a_orc_impl( &E_out_real, &E_out_imag, &P_out_real, &P_out_imag, input, carrier, E_code, P_code, num_points);
+// volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3_second_a_orc_impl( &L_out_real, &L_out_imag, input, carrier, L_code, num_points);
+//
+// //ORC implementation of 8ic_x5_cw_epl_corr_32fc_x3 is done in two different functions because it seems that
+// //in one function the length of the code gives memory problems (bad access, segmentation fault).
+// //Also, the maximum number of accumulators that can be used is 4 (and we need 6).
+// //The "carrier wipe-off" step is done two times: one in the first function and another one in the second.
+// //Joining all the ORC code in one function would be quicker because the "carrier wipe-off" step would be done just
+// //one time.
+//
+// *E_out = lv_cmake(*E_out_real_c, *E_out_imag_c);
+// *P_out = lv_cmake(*P_out_real_c, *P_out_imag_c);
+// *L_out = lv_cmake(*L_out_real_c, *L_out_imag_c);
+//}
+//#endif /* LV_HAVE_ORC */
+//
+//#endif /* INCLUDED_gnsssdr_volk_gnsssdr_8ic_x5_cw_epl_corr_32fc_x3_a_H */
diff --git a/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_x5_cw_epl_corr_8ic_x3.h b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_x5_cw_epl_corr_8ic_x3.h
new file mode 100644
index 000000000..b58931d8a
--- /dev/null
+++ b/src/algorithms/libs/volk_gnsssdr/kernels/volk_gnsssdr/volk_gnsssdr_8ic_x5_cw_epl_corr_8ic_x3.h
@@ -0,0 +1,874 @@
+/*!
+ * \file volk_gnsssdr_8ic_x5_cw_epl_corr_8ic_x3.h
+ * \brief Volk protokernel: performs the carrier wipe-off mixing and the Early, Prompt, and Late correlation with 16 bits vectors
+ * \authors