GNU Radio 3.6.4.2 C++ API
volk_16u_byteswap.h
Go to the documentation of this file.
00001 #ifndef INCLUDED_volk_16u_byteswap_u_H
00002 #define INCLUDED_volk_16u_byteswap_u_H
00003 
00004 #include <inttypes.h>
00005 #include <stdio.h>
00006 
00007 #ifdef LV_HAVE_SSE2
00008 #include <emmintrin.h>
00009 
00010 /*!
00011   \brief Byteswaps (in-place) an unaligned vector of int16_t's.
00012   \param intsToSwap The vector of data to byte swap
00013   \param numDataPoints The number of data points
00014 */
00015 static inline void volk_16u_byteswap_u_sse2(uint16_t* intsToSwap, unsigned int num_points){
00016   unsigned int number = 0;
00017   uint16_t* inputPtr = intsToSwap;
00018   __m128i input, left, right, output;
00019 
00020   const unsigned int eighthPoints = num_points / 8;
00021   for(;number < eighthPoints; number++){
00022     // Load the 16t values, increment inputPtr later since we're doing it in-place.
00023     input = _mm_loadu_si128((__m128i*)inputPtr);
00024     // Do the two shifts
00025     left = _mm_slli_epi16(input, 8);
00026     right = _mm_srli_epi16(input, 8);
00027     // Or the left and right halves together
00028     output = _mm_or_si128(left, right);
00029     // Store the results
00030     _mm_storeu_si128((__m128i*)inputPtr, output);
00031     inputPtr += 8;
00032   }
00033 
00034   // Byteswap any remaining points:
00035   number = eighthPoints*8;
00036   for(; number < num_points; number++){
00037     uint16_t outputVal = *inputPtr;
00038     outputVal = (((outputVal >> 8) & 0xff) | ((outputVal << 8) & 0xff00));
00039     *inputPtr = outputVal;
00040     inputPtr++;
00041   }
00042 }
00043 #endif /* LV_HAVE_SSE2 */
00044 
00045 #ifdef LV_HAVE_GENERIC
00046 /*!
00047   \brief Byteswaps (in-place) an unaligned vector of int16_t's.
00048   \param intsToSwap The vector of data to byte swap
00049   \param numDataPoints The number of data points
00050 */
00051 static inline void volk_16u_byteswap_generic(uint16_t* intsToSwap, unsigned int num_points){
00052   unsigned int point;
00053   uint16_t* inputPtr = intsToSwap;
00054   for(point = 0; point < num_points; point++){
00055     uint16_t output = *inputPtr;
00056     output = (((output >> 8) & 0xff) | ((output << 8) & 0xff00));
00057     *inputPtr = output;
00058     inputPtr++;
00059   }
00060 }
00061 #endif /* LV_HAVE_GENERIC */
00062 
00063 #endif /* INCLUDED_volk_16u_byteswap_u_H */
00064 #ifndef INCLUDED_volk_16u_byteswap_a_H
00065 #define INCLUDED_volk_16u_byteswap_a_H
00066 
00067 #include <inttypes.h>
00068 #include <stdio.h>
00069 
00070 #ifdef LV_HAVE_SSE2
00071 #include <emmintrin.h>
00072 
00073 /*!
00074   \brief Byteswaps (in-place) an aligned vector of int16_t's.
00075   \param intsToSwap The vector of data to byte swap
00076   \param numDataPoints The number of data points
00077 */
00078 static inline void volk_16u_byteswap_a_sse2(uint16_t* intsToSwap, unsigned int num_points){
00079   unsigned int number = 0;
00080   uint16_t* inputPtr = intsToSwap;
00081   __m128i input, left, right, output;
00082 
00083   const unsigned int eighthPoints = num_points / 8;
00084   for(;number < eighthPoints; number++){
00085     // Load the 16t values, increment inputPtr later since we're doing it in-place.
00086     input = _mm_load_si128((__m128i*)inputPtr);
00087     // Do the two shifts
00088     left = _mm_slli_epi16(input, 8);
00089     right = _mm_srli_epi16(input, 8);
00090     // Or the left and right halves together
00091     output = _mm_or_si128(left, right);
00092     // Store the results
00093     _mm_store_si128((__m128i*)inputPtr, output);
00094     inputPtr += 8;
00095   }
00096 
00097 
00098   // Byteswap any remaining points:
00099   number = eighthPoints*8;
00100   for(; number < num_points; number++){
00101     uint16_t outputVal = *inputPtr;
00102     outputVal = (((outputVal >> 8) & 0xff) | ((outputVal << 8) & 0xff00));
00103     *inputPtr = outputVal;
00104     inputPtr++;
00105   }
00106 }
00107 #endif /* LV_HAVE_SSE2 */
00108 
00109 #ifdef LV_HAVE_GENERIC
00110 /*!
00111   \brief Byteswaps (in-place) an aligned vector of int16_t's.
00112   \param intsToSwap The vector of data to byte swap
00113   \param numDataPoints The number of data points
00114 */
00115 static inline void volk_16u_byteswap_a_generic(uint16_t* intsToSwap, unsigned int num_points){
00116   unsigned int point;
00117   uint16_t* inputPtr = intsToSwap;
00118   for(point = 0; point < num_points; point++){
00119     uint16_t output = *inputPtr;
00120     output = (((output >> 8) & 0xff) | ((output << 8) & 0xff00));
00121     *inputPtr = output;
00122     inputPtr++;
00123   }
00124 }
00125 #endif /* LV_HAVE_GENERIC */
00126 
00127 #ifdef LV_HAVE_ORC
00128 /*!
00129   \brief Byteswaps (in-place) an aligned vector of int16_t's.
00130   \param intsToSwap The vector of data to byte swap
00131   \param numDataPoints The number of data points
00132 */
00133 extern void volk_16u_byteswap_a_orc_impl(uint16_t* intsToSwap, unsigned int num_points);
00134 static inline void volk_16u_byteswap_u_orc(uint16_t* intsToSwap, unsigned int num_points){
00135     volk_16u_byteswap_a_orc_impl(intsToSwap, num_points);
00136 }
00137 #endif /* LV_HAVE_ORC */
00138 
00139 
00140 #endif /* INCLUDED_volk_16u_byteswap_a_H */