GNU Radio 3.4.0 C++ API
|
00001 #ifndef INCLUDED_volk_32f_s32f_convert_8i_a16_H 00002 #define INCLUDED_volk_32f_s32f_convert_8i_a16_H 00003 00004 #include <inttypes.h> 00005 #include <stdio.h> 00006 00007 #if LV_HAVE_SSE2 00008 #include <emmintrin.h> 00009 /*! 00010 \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 8 bit integer value 00011 \param inputVector The floating point input data buffer 00012 \param outputVector The 8 bit output data buffer 00013 \param scalar The value multiplied against each point in the input buffer 00014 \param num_points The number of data values to be converted 00015 */ 00016 static inline void volk_32f_s32f_convert_8i_a16_sse2(int8_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){ 00017 unsigned int number = 0; 00018 00019 const unsigned int sixteenthPoints = num_points / 16; 00020 00021 const float* inputVectorPtr = (const float*)inputVector; 00022 int8_t* outputVectorPtr = outputVector; 00023 __m128 vScalar = _mm_set_ps1(scalar); 00024 __m128 inputVal1, inputVal2, inputVal3, inputVal4; 00025 __m128i intInputVal1, intInputVal2, intInputVal3, intInputVal4; 00026 00027 for(;number < sixteenthPoints; number++){ 00028 inputVal1 = _mm_load_ps(inputVectorPtr); inputVectorPtr += 4; 00029 inputVal2 = _mm_load_ps(inputVectorPtr); inputVectorPtr += 4; 00030 inputVal3 = _mm_load_ps(inputVectorPtr); inputVectorPtr += 4; 00031 inputVal4 = _mm_load_ps(inputVectorPtr); inputVectorPtr += 4; 00032 00033 intInputVal1 = _mm_cvtps_epi32(_mm_mul_ps(inputVal1, vScalar)); 00034 intInputVal2 = _mm_cvtps_epi32(_mm_mul_ps(inputVal2, vScalar)); 00035 intInputVal3 = _mm_cvtps_epi32(_mm_mul_ps(inputVal3, vScalar)); 00036 intInputVal4 = _mm_cvtps_epi32(_mm_mul_ps(inputVal4, vScalar)); 00037 00038 intInputVal1 = _mm_packs_epi32(intInputVal1, intInputVal2); 00039 intInputVal3 = _mm_packs_epi32(intInputVal3, intInputVal4); 00040 00041 intInputVal1 = _mm_packs_epi16(intInputVal1, intInputVal3); 00042 00043 _mm_store_si128((__m128i*)outputVectorPtr, intInputVal1); 00044 outputVectorPtr += 16; 00045 } 00046 00047 number = sixteenthPoints * 16; 00048 for(; number < num_points; number++){ 00049 outputVector[number] = (int8_t)(inputVector[number] * scalar); 00050 } 00051 } 00052 #endif /* LV_HAVE_SSE2 */ 00053 00054 #if LV_HAVE_SSE 00055 #include <xmmintrin.h> 00056 /*! 00057 \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 8 bit integer value 00058 \param inputVector The floating point input data buffer 00059 \param outputVector The 8 bit output data buffer 00060 \param scalar The value multiplied against each point in the input buffer 00061 \param num_points The number of data values to be converted 00062 */ 00063 static inline void volk_32f_s32f_convert_8i_a16_sse(int8_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){ 00064 unsigned int number = 0; 00065 00066 const unsigned int quarterPoints = num_points / 4; 00067 00068 const float* inputVectorPtr = (const float*)inputVector; 00069 int8_t* outputVectorPtr = outputVector; 00070 __m128 vScalar = _mm_set_ps1(scalar); 00071 __m128 ret; 00072 00073 float outputFloatBuffer[4] __attribute__((aligned(128))); 00074 00075 for(;number < quarterPoints; number++){ 00076 ret = _mm_load_ps(inputVectorPtr); 00077 inputVectorPtr += 4; 00078 00079 ret = _mm_mul_ps(ret, vScalar); 00080 00081 _mm_store_ps(outputFloatBuffer, ret); 00082 *outputVectorPtr++ = (int8_t)(outputFloatBuffer[0]); 00083 *outputVectorPtr++ = (int8_t)(outputFloatBuffer[1]); 00084 *outputVectorPtr++ = (int8_t)(outputFloatBuffer[2]); 00085 *outputVectorPtr++ = (int8_t)(outputFloatBuffer[3]); 00086 } 00087 00088 number = quarterPoints * 4; 00089 for(; number < num_points; number++){ 00090 outputVector[number] = (int8_t)(inputVector[number] * scalar); 00091 } 00092 } 00093 #endif /* LV_HAVE_SSE */ 00094 00095 #ifdef LV_HAVE_GENERIC 00096 /*! 00097 \brief Multiplies each point in the input buffer by the scalar value, then converts the result into a 8 bit integer value 00098 \param inputVector The floating point input data buffer 00099 \param outputVector The 8 bit output data buffer 00100 \param scalar The value multiplied against each point in the input buffer 00101 \param num_points The number of data values to be converted 00102 */ 00103 static inline void volk_32f_s32f_convert_8i_a16_generic(int8_t* outputVector, const float* inputVector, const float scalar, unsigned int num_points){ 00104 int8_t* outputVectorPtr = outputVector; 00105 const float* inputVectorPtr = inputVector; 00106 unsigned int number = 0; 00107 00108 for(number = 0; number < num_points; number++){ 00109 *outputVectorPtr++ = (int8_t)(*inputVectorPtr++ * scalar); 00110 } 00111 } 00112 #endif /* LV_HAVE_GENERIC */ 00113 00114 00115 00116 00117 #endif /* INCLUDED_volk_32f_s32f_convert_8i_a16_H */