mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-30 23:03:05 +00:00 
			
		
		
		
	Added cmake version check. Deleted original volk
Added cmake version checks. Deleted original volk protokernels. Fixes.
This commit is contained in:
		| @@ -205,6 +205,14 @@ set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "") | ||||
| # Append -O2 optimization flag for Debug builds | ||||
| set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O2") | ||||
|  | ||||
| ################################################################################ | ||||
| # Checkout cmake version | ||||
| ################################################################################ | ||||
| if(CMAKE_VERSION VERSION_LESS 2.8.8) | ||||
|       message(STATUS "Your CMake version is too old and does not support some features required by GNSS-SDR. CMake version must be at least 2.8.8. For more information check https://github.com/joakimkarlsson/bandit/issues/40") | ||||
|       message(FATAL_ERROR "Fatal error: CMake >= 2.8.8 required.") | ||||
| endif(CMAKE_VERSION VERSION_LESS 2.8.8) | ||||
|  | ||||
| ################################################################################ | ||||
| # Checkout compiler version | ||||
| ################################################################################ | ||||
|   | ||||
| @@ -179,27 +179,18 @@ int main(int argc, char *argv[]) { | ||||
|      VOLK_PROFILE(volk_gnsssdr_32fc_convert_8ic, 1e-4, 0, 16000, 250, &results, benchmark_mode, kernel_regex); | ||||
|      VOLK_PROFILE(volk_gnsssdr_32fc_s32f_convert_8ic, 1e-4, 5, 16000, 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); | ||||
|      VOLK_PROFILE(volk_gnsssdr_64f_accumulator_64f, 1e-4, 0, 16000, 1000, &results, benchmark_mode, kernel_regex); | ||||
|      VOLK_PROFILE(volk_gnsssdr_32f_s32f_convert_16i, 1e-4, 1, 204602, 250, &results, benchmark_mode, kernel_regex); | ||||
|      VOLK_PROFILE(volk_gnsssdr_16i_s32f_convert_32f, 1e-4, 1, 204602, 250, &results, benchmark_mode, kernel_regex); | ||||
|      | ||||
|     // Until we can update the config on a kernel by kernel basis | ||||
|     // do not overwrite volk_config when using a regex. | ||||
|   | ||||
| @@ -1,241 +0,0 @@ | ||||
| #ifndef INCLUDED_volk_gnsssdr_16i_s32f_convert_32f_u_H | ||||
| #define INCLUDED_volk_gnsssdr_16i_s32f_convert_32f_u_H | ||||
|  | ||||
| #include <inttypes.h> | ||||
| #include <stdio.h> | ||||
|  | ||||
| #ifdef LV_HAVE_SSE4_1 | ||||
| #include <smmintrin.h> | ||||
|  | ||||
|   /*! | ||||
|     \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 <xmmintrin.h> | ||||
|  | ||||
|   /*! | ||||
|     \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 <inttypes.h> | ||||
| #include <stdio.h> | ||||
|  | ||||
| #ifdef LV_HAVE_SSE4_1 | ||||
| #include <smmintrin.h> | ||||
|  | ||||
|   /*! | ||||
|     \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 <xmmintrin.h> | ||||
|  | ||||
|   /*! | ||||
|     \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 */ | ||||
| @@ -1,68 +0,0 @@ | ||||
| #ifndef INCLUDED_volk_gnsssdr_32f_accumulator_s32f_a_H | ||||
| #define INCLUDED_volk_gnsssdr_32f_accumulator_s32f_a_H | ||||
|  | ||||
| #include <volk_gnsssdr/volk_gnsssdr_common.h> | ||||
| #include <inttypes.h> | ||||
| #include <stdio.h> | ||||
|  | ||||
| #ifdef LV_HAVE_SSE | ||||
| #include <xmmintrin.h> | ||||
| /*! | ||||
|   \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 */ | ||||
| @@ -1,149 +0,0 @@ | ||||
| #ifndef INCLUDED_volk_gnsssdr_32f_index_max_16u_a_H | ||||
| #define INCLUDED_volk_gnsssdr_32f_index_max_16u_a_H | ||||
|  | ||||
| #include <volk_gnsssdr/volk_gnsssdr_common.h> | ||||
| #include <volk_gnsssdr/volk_gnsssdr_common.h> | ||||
| #include <inttypes.h> | ||||
| #include <stdio.h> | ||||
|  | ||||
| #ifdef LV_HAVE_SSE4_1 | ||||
| #include <smmintrin.h> | ||||
|  | ||||
| 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<xmmintrin.h> | ||||
|  | ||||
| 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*/ | ||||
| @@ -1,302 +0,0 @@ | ||||
| #ifndef INCLUDED_volk_gnsssdr_32f_s32f_convert_16i_u_H | ||||
| #define INCLUDED_volk_gnsssdr_32f_s32f_convert_16i_u_H | ||||
|  | ||||
| #include <inttypes.h> | ||||
| #include <stdio.h> | ||||
| #include <math.h> | ||||
|  | ||||
| #ifdef LV_HAVE_SSE2 | ||||
| #include <emmintrin.h> | ||||
|   /*! | ||||
|     \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 16 bit integer value | ||||
|     \param inputVector The floating point input data buffer | ||||
|     \param outputVector The 16 bit output data buffer | ||||
|     \param scalar The value multiplied against each point in the input buffer | ||||
|     \param num_points The number of data values to be converted | ||||
|     \note Input buffer does NOT need to be properly aligned | ||||
|   */ | ||||
| static inline void volk_gnsssdr_32f_s32f_convert_16i_u_sse2(int16_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){ | ||||
|   unsigned int number = 0; | ||||
|  | ||||
|   const unsigned int eighthPoints = num_points / 8; | ||||
|  | ||||
|   const float* inputVectorPtr = (const float*)inputVector; | ||||
|   int16_t* outputVectorPtr = outputVector; | ||||
|  | ||||
|   float min_val = -32768; | ||||
|   float max_val = 32767; | ||||
|   float r; | ||||
|  | ||||
|   __m128 vScalar = _mm_set_ps1(scalar); | ||||
|   __m128 inputVal1, inputVal2; | ||||
|   __m128i intInputVal1, intInputVal2; | ||||
|   __m128 ret1, ret2; | ||||
|   __m128 vmin_val = _mm_set_ps1(min_val); | ||||
|   __m128 vmax_val = _mm_set_ps1(max_val); | ||||
|  | ||||
|   for(;number < eighthPoints; number++){ | ||||
|     inputVal1 = _mm_loadu_ps(inputVectorPtr); inputVectorPtr += 4; | ||||
|     inputVal2 = _mm_loadu_ps(inputVectorPtr); inputVectorPtr += 4; | ||||
|  | ||||
|     // Scale and clip | ||||
|     ret1 = _mm_max_ps(_mm_min_ps(_mm_mul_ps(inputVal1, vScalar), vmax_val), vmin_val); | ||||
|     ret2 = _mm_max_ps(_mm_min_ps(_mm_mul_ps(inputVal2, vScalar), vmax_val), vmin_val); | ||||
|  | ||||
|     intInputVal1 = _mm_cvtps_epi32(ret1); | ||||
|     intInputVal2 = _mm_cvtps_epi32(ret2); | ||||
|  | ||||
|     intInputVal1 = _mm_packs_epi32(intInputVal1, intInputVal2); | ||||
|  | ||||
|     _mm_storeu_si128((__m128i*)outputVectorPtr, intInputVal1); | ||||
|     outputVectorPtr += 8; | ||||
|   } | ||||
|  | ||||
|   number = eighthPoints * 8; | ||||
|   for(; number < num_points; number++){ | ||||
|     r = inputVector[number] * scalar; | ||||
|     if(r > max_val) | ||||
|       r = max_val; | ||||
|     else if(r < min_val) | ||||
|       r = min_val; | ||||
|     outputVector[number] = (int16_t)rintf(r); | ||||
|   } | ||||
| } | ||||
| #endif /* LV_HAVE_SSE2 */ | ||||
|  | ||||
| #ifdef LV_HAVE_SSE | ||||
| #include <xmmintrin.h> | ||||
|   /*! | ||||
|     \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 16 bit integer value | ||||
|     \param inputVector The floating point input data buffer | ||||
|     \param outputVector The 16 bit output data buffer | ||||
|     \param scalar The value multiplied against each point in the input buffer | ||||
|     \param num_points The number of data values to be converted | ||||
|     \note Input buffer does NOT need to be properly aligned | ||||
|   */ | ||||
| static inline void volk_gnsssdr_32f_s32f_convert_16i_u_sse(int16_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){ | ||||
|   unsigned int number = 0; | ||||
|  | ||||
|   const unsigned int quarterPoints = num_points / 4; | ||||
|  | ||||
|   const float* inputVectorPtr = (const float*)inputVector; | ||||
|   int16_t* outputVectorPtr = outputVector; | ||||
|  | ||||
|   float min_val = -32768; | ||||
|   float max_val = 32767; | ||||
|   float r; | ||||
|  | ||||
|   __m128 vScalar = _mm_set_ps1(scalar); | ||||
|   __m128 ret; | ||||
|   __m128 vmin_val = _mm_set_ps1(min_val); | ||||
|   __m128 vmax_val = _mm_set_ps1(max_val); | ||||
|  | ||||
|   __VOLK_ATTR_ALIGNED(16) float outputFloatBuffer[4]; | ||||
|  | ||||
|   for(;number < quarterPoints; number++){ | ||||
|     ret = _mm_loadu_ps(inputVectorPtr); | ||||
|     inputVectorPtr += 4; | ||||
|  | ||||
|     // Scale and clip | ||||
|     ret = _mm_max_ps(_mm_min_ps(_mm_mul_ps(ret, vScalar), vmax_val), vmin_val); | ||||
|  | ||||
|     _mm_store_ps(outputFloatBuffer, ret); | ||||
|     *outputVectorPtr++ = (int16_t)rintf(outputFloatBuffer[0]); | ||||
|     *outputVectorPtr++ = (int16_t)rintf(outputFloatBuffer[1]); | ||||
|     *outputVectorPtr++ = (int16_t)rintf(outputFloatBuffer[2]); | ||||
|     *outputVectorPtr++ = (int16_t)rintf(outputFloatBuffer[3]); | ||||
|   } | ||||
|  | ||||
|   number = quarterPoints * 4; | ||||
|   for(; number < num_points; number++){ | ||||
|     r = inputVector[number] * scalar; | ||||
|     if(r > max_val) | ||||
|       r = max_val; | ||||
|     else if(r < min_val) | ||||
|       r = min_val; | ||||
|     outputVector[number] = (int16_t)rintf(r); | ||||
|   } | ||||
| } | ||||
| #endif /* LV_HAVE_SSE */ | ||||
|  | ||||
| #ifdef LV_HAVE_GENERIC | ||||
|   /*! | ||||
|     \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 16 bit integer value | ||||
|     \param inputVector The floating point input data buffer | ||||
|     \param outputVector The 16 bit output data buffer | ||||
|     \param scalar The value multiplied against each point in the input buffer | ||||
|     \param num_points The number of data values to be converted | ||||
|     \note Input buffer does NOT need to be properly aligned | ||||
|   */ | ||||
| static inline void volk_gnsssdr_32f_s32f_convert_16i_generic(int16_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){ | ||||
|   int16_t* outputVectorPtr = outputVector; | ||||
|   const float* inputVectorPtr = inputVector; | ||||
|   unsigned int number = 0; | ||||
|   float min_val = -32768; | ||||
|   float max_val = 32767; | ||||
|   float r; | ||||
|  | ||||
|   for(number = 0; number < num_points; number++){ | ||||
|     r = *inputVectorPtr++  * scalar; | ||||
|     if(r > max_val) | ||||
|       r = max_val; | ||||
|     else if(r < min_val) | ||||
|       r = min_val; | ||||
|     *outputVectorPtr++ = (int16_t)rintf(r); | ||||
|   } | ||||
| } | ||||
| #endif /* LV_HAVE_GENERIC */ | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #endif /* INCLUDED_volk_gnsssdr_32f_s32f_convert_16i_u_H */ | ||||
| #ifndef INCLUDED_volk_gnsssdr_32f_s32f_convert_16i_a_H | ||||
| #define INCLUDED_volk_gnsssdr_32f_s32f_convert_16i_a_H | ||||
|  | ||||
| #include <volk/volk_common.h> | ||||
| #include <inttypes.h> | ||||
| #include <stdio.h> | ||||
| #include <math.h> | ||||
|  | ||||
| #ifdef LV_HAVE_SSE2 | ||||
| #include <emmintrin.h> | ||||
|   /*! | ||||
|     \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 16 bit integer value | ||||
|     \param inputVector The floating point input data buffer | ||||
|     \param outputVector The 16 bit output data buffer | ||||
|     \param scalar The value multiplied against each point in the input buffer | ||||
|     \param num_points The number of data values to be converted | ||||
|   */ | ||||
| static inline void volk_gnsssdr_32f_s32f_convert_16i_a_sse2(int16_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){ | ||||
|   unsigned int number = 0; | ||||
|  | ||||
|   const unsigned int eighthPoints = num_points / 8; | ||||
|  | ||||
|   const float* inputVectorPtr = (const float*)inputVector; | ||||
|   int16_t* outputVectorPtr = outputVector; | ||||
|  | ||||
|   float min_val = -32768; | ||||
|   float max_val = 32767; | ||||
|   float r; | ||||
|  | ||||
|   __m128 vScalar = _mm_set_ps1(scalar); | ||||
|   __m128 inputVal1, inputVal2; | ||||
|   __m128i intInputVal1, intInputVal2; | ||||
|   __m128 ret1, ret2; | ||||
|   __m128 vmin_val = _mm_set_ps1(min_val); | ||||
|   __m128 vmax_val = _mm_set_ps1(max_val); | ||||
|  | ||||
|   for(;number < eighthPoints; number++){ | ||||
|     inputVal1 = _mm_load_ps(inputVectorPtr); inputVectorPtr += 4; | ||||
|     inputVal2 = _mm_load_ps(inputVectorPtr); inputVectorPtr += 4; | ||||
|  | ||||
|     // Scale and clip | ||||
|     ret1 = _mm_max_ps(_mm_min_ps(_mm_mul_ps(inputVal1, vScalar), vmax_val), vmin_val); | ||||
|     ret2 = _mm_max_ps(_mm_min_ps(_mm_mul_ps(inputVal2, vScalar), vmax_val), vmin_val); | ||||
|  | ||||
|     intInputVal1 = _mm_cvtps_epi32(ret1); | ||||
|     intInputVal2 = _mm_cvtps_epi32(ret2); | ||||
|  | ||||
|     intInputVal1 = _mm_packs_epi32(intInputVal1, intInputVal2); | ||||
|  | ||||
|     _mm_store_si128((__m128i*)outputVectorPtr, intInputVal1); | ||||
|     outputVectorPtr += 8; | ||||
|   } | ||||
|  | ||||
|   number = eighthPoints * 8; | ||||
|   for(; number < num_points; number++){ | ||||
|     r = inputVector[number] * scalar; | ||||
|     if(r > max_val) | ||||
|       r = max_val; | ||||
|     else if(r < min_val) | ||||
|       r = min_val; | ||||
|     outputVector[number] = (int16_t)rintf(r); | ||||
|   } | ||||
| } | ||||
| #endif /* LV_HAVE_SSE2 */ | ||||
|  | ||||
| #ifdef LV_HAVE_SSE | ||||
| #include <xmmintrin.h> | ||||
|   /*! | ||||
|     \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 16 bit integer value | ||||
|     \param inputVector The floating point input data buffer | ||||
|     \param outputVector The 16 bit output data buffer | ||||
|     \param scalar The value multiplied against each point in the input buffer | ||||
|     \param num_points The number of data values to be converted | ||||
|   */ | ||||
| static inline void volk_gnsssdr_32f_s32f_convert_16i_a_sse(int16_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){ | ||||
|   unsigned int number = 0; | ||||
|  | ||||
|   const unsigned int quarterPoints = num_points / 4; | ||||
|  | ||||
|   const float* inputVectorPtr = (const float*)inputVector; | ||||
|   int16_t* outputVectorPtr = outputVector; | ||||
|  | ||||
|   float min_val = -32768; | ||||
|   float max_val = 32767; | ||||
|   float r; | ||||
|  | ||||
|   __m128 vScalar = _mm_set_ps1(scalar); | ||||
|   __m128 ret; | ||||
|   __m128 vmin_val = _mm_set_ps1(min_val); | ||||
|   __m128 vmax_val = _mm_set_ps1(max_val); | ||||
|  | ||||
|   __VOLK_ATTR_ALIGNED(16) float outputFloatBuffer[4]; | ||||
|  | ||||
|   for(;number < quarterPoints; number++){ | ||||
|     ret = _mm_load_ps(inputVectorPtr); | ||||
|     inputVectorPtr += 4; | ||||
|  | ||||
|     // Scale and clip | ||||
|     ret = _mm_max_ps(_mm_min_ps(_mm_mul_ps(ret, vScalar), vmax_val), vmin_val); | ||||
|  | ||||
|     _mm_store_ps(outputFloatBuffer, ret); | ||||
|     *outputVectorPtr++ = (int16_t)rintf(outputFloatBuffer[0]); | ||||
|     *outputVectorPtr++ = (int16_t)rintf(outputFloatBuffer[1]); | ||||
|     *outputVectorPtr++ = (int16_t)rintf(outputFloatBuffer[2]); | ||||
|     *outputVectorPtr++ = (int16_t)rintf(outputFloatBuffer[3]); | ||||
|   } | ||||
|  | ||||
|   number = quarterPoints * 4; | ||||
|   for(; number < num_points; number++){ | ||||
|     r = inputVector[number] * scalar; | ||||
|     if(r > max_val) | ||||
|       r = max_val; | ||||
|     else if(r < min_val) | ||||
|       r = min_val; | ||||
|     outputVector[number] = (int16_t)rintf(r); | ||||
|   } | ||||
| } | ||||
| #endif /* LV_HAVE_SSE */ | ||||
|  | ||||
| #ifdef LV_HAVE_GENERIC | ||||
|   /*! | ||||
|     \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 16 bit integer value | ||||
|     \param inputVector The floating point input data buffer | ||||
|     \param outputVector The 16 bit output data buffer | ||||
|     \param scalar The value multiplied against each point in the input buffer | ||||
|     \param num_points The number of data values to be converted | ||||
|   */ | ||||
| static inline void volk_gnsssdr_32f_s32f_convert_16i_a_generic(int16_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){ | ||||
|   int16_t* outputVectorPtr = outputVector; | ||||
|   const float* inputVectorPtr = inputVector; | ||||
|   unsigned int number = 0; | ||||
|   float min_val = -32768; | ||||
|   float max_val = 32767; | ||||
|   float r; | ||||
|  | ||||
|   for(number = 0; number < num_points; number++){ | ||||
|     r  = *inputVectorPtr++ * scalar; | ||||
|     if(r < min_val) | ||||
|       r = min_val; | ||||
|     else if(r > max_val) | ||||
|       r = max_val; | ||||
|     *outputVectorPtr++ = (int16_t)rintf(r); | ||||
|   } | ||||
| } | ||||
| #endif /* LV_HAVE_GENERIC */ | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #endif /* INCLUDED_volk_gnsssdr_32f_s32f_convert_16i_a_H */ | ||||
| @@ -1,147 +0,0 @@ | ||||
| #ifndef INCLUDED_volk_gnsssdr_32f_x2_add_32f_u_H | ||||
| #define INCLUDED_volk_gnsssdr_32f_x2_add_32f_u_H | ||||
|  | ||||
| #include <inttypes.h> | ||||
| #include <stdio.h> | ||||
|  | ||||
| #ifdef LV_HAVE_SSE | ||||
| #include <xmmintrin.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_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 <inttypes.h> | ||||
| #include <stdio.h> | ||||
|  | ||||
| #ifdef LV_HAVE_SSE | ||||
| #include <xmmintrin.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_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 */ | ||||
| @@ -1,127 +0,0 @@ | ||||
| #ifndef INCLUDED_volk_gnsssdr_32fc_conjugate_32fc_u_H | ||||
| #define INCLUDED_volk_gnsssdr_32fc_conjugate_32fc_u_H | ||||
|  | ||||
| #include <inttypes.h> | ||||
| #include <stdio.h> | ||||
| #include <volk_gnsssdr/volk_gnsssdr_complex.h> | ||||
| #include <float.h> | ||||
|  | ||||
| #ifdef LV_HAVE_SSE3 | ||||
| #include <pmmintrin.h> | ||||
|   /*! | ||||
|     \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 <inttypes.h> | ||||
| #include <stdio.h> | ||||
| #include <volk_gnsssdr/volk_gnsssdr_complex.h> | ||||
| #include <float.h> | ||||
|  | ||||
| #ifdef LV_HAVE_SSE3 | ||||
| #include <pmmintrin.h> | ||||
|   /*! | ||||
|     \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 */ | ||||
| @@ -1,228 +0,0 @@ | ||||
| #ifndef INCLUDED_volk_gnsssdr_32fc_magnitude_squared_32f_u_H | ||||
| #define INCLUDED_volk_gnsssdr_32fc_magnitude_squared_32f_u_H | ||||
|  | ||||
| #include <inttypes.h> | ||||
| #include <stdio.h> | ||||
| #include <math.h> | ||||
|  | ||||
| #ifdef LV_HAVE_SSE3 | ||||
| #include <pmmintrin.h> | ||||
|   /*! | ||||
|     \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 <xmmintrin.h> | ||||
|   /*! | ||||
|     \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 <inttypes.h> | ||||
| #include <stdio.h> | ||||
| #include <math.h> | ||||
|  | ||||
| #ifdef LV_HAVE_SSE3 | ||||
| #include <pmmintrin.h> | ||||
|   /*! | ||||
|     \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 <xmmintrin.h> | ||||
|   /*! | ||||
|     \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 */ | ||||
| @@ -99,7 +99,7 @@ static inline void volk_gnsssdr_32fc_s32f_x4_update_local_code_32fc_u_sse4_1(lv_ | ||||
|     if (num_points%4!=0) | ||||
|     { | ||||
|         __VOLK_ATTR_ALIGNED(16) float tcode_half_chips_stored[4]; | ||||
|         _mm_storeu_si128 ((__m128i*)tcode_half_chips_stored, tcode_half_chips_array); | ||||
|         _mm_storeu_ps ((float*)tcode_half_chips_stored, tcode_half_chips_array); | ||||
|          | ||||
|         int associated_chip_index; | ||||
|         float tcode_half_chips = tcode_half_chips_stored[0]; | ||||
| @@ -215,7 +215,7 @@ static inline void volk_gnsssdr_32fc_s32f_x4_update_local_code_32fc_a_sse4_1(lv_ | ||||
|     if (num_points%4!=0) | ||||
|     { | ||||
|         __VOLK_ATTR_ALIGNED(16) float tcode_half_chips_stored[4]; | ||||
|         _mm_store_si128 ((__m128i*)tcode_half_chips_stored, tcode_half_chips_array); | ||||
|         _mm_storeu_ps ((float*)tcode_half_chips_stored, tcode_half_chips_array); | ||||
|          | ||||
|         int associated_chip_index; | ||||
|         float tcode_half_chips = tcode_half_chips_stored[0]; | ||||
|   | ||||
| @@ -1,178 +0,0 @@ | ||||
| #ifndef INCLUDED_volk_gnsssdr_32fc_s32fc_multiply_32fc_u_H | ||||
| #define INCLUDED_volk_gnsssdr_32fc_s32fc_multiply_32fc_u_H | ||||
|  | ||||
| #include <inttypes.h> | ||||
| #include <stdio.h> | ||||
| #include <volk_gnsssdr/volk_gnsssdr_complex.h> | ||||
| #include <float.h> | ||||
|  | ||||
| #ifdef LV_HAVE_SSE3 | ||||
| #include <pmmintrin.h> | ||||
| /*! | ||||
|   \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 <inttypes.h> | ||||
| #include <stdio.h> | ||||
| #include <volk_gnsssdr/volk_gnsssdr_complex.h> | ||||
| #include <float.h> | ||||
|  | ||||
| #ifdef LV_HAVE_SSE3 | ||||
| #include <pmmintrin.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_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 */ | ||||
| @@ -1,759 +0,0 @@ | ||||
| #ifndef INCLUDED_volk_gnsssdr_32fc_x2_dot_prod_32fc_u_H | ||||
| #define INCLUDED_volk_gnsssdr_32fc_x2_dot_prod_32fc_u_H | ||||
|  | ||||
| #include <volk_gnsssdr/volk_gnsssdr_common.h> | ||||
| #include <volk_gnsssdr/volk_gnsssdr_complex.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
|  | ||||
|  | ||||
| #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 <pmmintrin.h> | ||||
|  | ||||
| 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 <smmintrin.h> | ||||
|  | ||||
| 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 <volk_gnsssdr/volk_gnsssdr_common.h> | ||||
| #include <volk_gnsssdr/volk_gnsssdr_complex.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
|  | ||||
|  | ||||
| #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 <pmmintrin.h> | ||||
|  | ||||
| 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 <smmintrin.h> | ||||
|  | ||||
| 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*/ | ||||
| @@ -1,170 +0,0 @@ | ||||
| #ifndef INCLUDED_volk_gnsssdr_32fc_x2_multiply_32fc_u_H | ||||
| #define INCLUDED_volk_gnsssdr_32fc_x2_multiply_32fc_u_H | ||||
|  | ||||
| #include <inttypes.h> | ||||
| #include <stdio.h> | ||||
| #include <volk_gnsssdr/volk_gnsssdr_complex.h> | ||||
| #include <float.h> | ||||
|  | ||||
| #ifdef LV_HAVE_SSE3 | ||||
| #include <pmmintrin.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_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 <inttypes.h> | ||||
| #include <stdio.h> | ||||
| #include <volk_gnsssdr/volk_gnsssdr_complex.h> | ||||
| #include <float.h> | ||||
|  | ||||
| #ifdef LV_HAVE_SSE3 | ||||
| #include <pmmintrin.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_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 */ | ||||
| @@ -1,3 +1,49 @@ | ||||
| /*! | ||||
|  * \file volk_gnsssdr_32fc_x5_cw_vepl_corr_32fc_x5 | ||||
|  * \brief Volk protokernel: performs the carrier wipe-off mixing and the Early, Prompt and Late correlation with 64 bits vectors | ||||
|  * \authors <ul> | ||||
|  *          <li>Javier Arribas, 2011. jarribas(at)cttc.es | ||||
|  *          <li> Andrés Cecilia, 2014. a.cecilia.luque(at)gmail.com | ||||
|  *          </ul> | ||||
|  * | ||||
|  * Volk protokernel that performs the carrier wipe-off mixing and the | ||||
|  * Early, Prompt and Late 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) | ||||
|  * - 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 | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * 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 <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #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 | ||||
|  | ||||
|   | ||||
| @@ -24,17 +24,6 @@ | ||||
| #include <volk_gnsssdr/volk_gnsssdr.h> | ||||
| #include <boost/test/unit_test.hpp> | ||||
|  | ||||
| //VOLK PROTOKERNELS OBTAINED FROM THE GNURADIO BASE | ||||
| VOLK_RUN_TESTS(volk_gnsssdr_32fc_x2_multiply_32fc, 1e-4, 0, 20462, 1); | ||||
| VOLK_RUN_TESTS(volk_gnsssdr_32fc_x2_dot_prod_32fc, 1e-4, 0, 204603, 1); | ||||
| VOLK_RUN_TESTS(volk_gnsssdr_32fc_s32fc_multiply_32fc, 1e-4, 0, 20462, 1); | ||||
| VOLK_RUN_TESTS(volk_gnsssdr_32fc_conjugate_32fc, 1e-4, 0, 20462, 1); | ||||
| VOLK_RUN_TESTS(volk_gnsssdr_32f_x2_add_32f, 1e-4, 0, 20462, 1); | ||||
| VOLK_RUN_TESTS(volk_gnsssdr_32f_index_max_16u, 3, 0, 20462, 1); | ||||
| VOLK_RUN_TESTS(volk_gnsssdr_32f_accumulator_s32f, 1e-4, 0, 20462, 1); | ||||
| VOLK_RUN_TESTS(volk_gnsssdr_32fc_magnitude_squared_32f, 1e-4, 0, 20462, 1); | ||||
| VOLK_RUN_TESTS(volk_gnsssdr_32f_s32f_convert_16i, 3, 0, 20462, 1); | ||||
|  | ||||
| //GNSS-SDR PROTO-KERNELS | ||||
| VOLK_RUN_TESTS(volk_gnsssdr_8ic_x2_multiply_8ic, 1e-4, 0, 20462, 1); | ||||
| VOLK_RUN_TESTS(volk_gnsssdr_8u_x2_multiply_8u, 1e-4, 0, 20462, 1); | ||||
| @@ -52,7 +41,6 @@ VOLK_RUN_TESTS(volk_gnsssdr_64f_accumulator_64f, 3, 0, 20462, 1); | ||||
| VOLK_RUN_TESTS(volk_gnsssdr_32fc_convert_16ic, 3, 0, 20462, 1); | ||||
| VOLK_RUN_TESTS(volk_gnsssdr_32fc_s32f_convert_8ic, 3, 0, 20462, 1); | ||||
| VOLK_RUN_TESTS(volk_gnsssdr_32fc_convert_8ic, 3, 0, 20462, 1); | ||||
| VOLK_RUN_TESTS(volk_gnsssdr_16i_s32f_convert_32f, 3, 0, 20462, 1); | ||||
|  | ||||
| VOLK_RUN_TESTS(volk_gnsssdr_32fc_x5_cw_epl_corr_32fc_x3, 1e-4, 0, 20462, 1); | ||||
| VOLK_RUN_TESTS(volk_gnsssdr_8ic_x5_cw_epl_corr_8ic_x3, 1e-4, 0, 20462, 1); | ||||
|   | ||||
| @@ -244,7 +244,6 @@ void galileo_volk_e1_dll_pll_veml_tracking_cc::update_local_code() | ||||
| { | ||||
|     double tcode_half_chips; | ||||
|     float rem_code_phase_half_chips; | ||||
|     int associated_chip_index; | ||||
|     int code_length_half_chips = static_cast<int>(Galileo_E1_B_CODE_LENGTH_CHIPS) * 2; | ||||
|     double code_phase_step_chips; | ||||
|     double code_phase_step_half_chips; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 andres
					andres