aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/convert
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2011-06-15 14:50:02 -0700
committerJosh Blum <josh@joshknows.com>2011-06-15 14:50:02 -0700
commit0cef788d3d34a298c975e32c488e800a5c65ccce (patch)
tree14b7f4242a28927b1701a73a3e8ec0df3fa04811 /host/lib/convert
parent7951170c6161d9266726ec19e8c009500cf11f75 (diff)
parent27f1622d439ceb787e7dada733d0eb82270c5532 (diff)
downloaduhd-0cef788d3d34a298c975e32c488e800a5c65ccce.tar.gz
uhd-0cef788d3d34a298c975e32c488e800a5c65ccce.tar.bz2
uhd-0cef788d3d34a298c975e32c488e800a5c65ccce.zip
Merge branch 'next'
Diffstat (limited to 'host/lib/convert')
-rw-r--r--host/lib/convert/CMakeLists.txt46
-rw-r--r--host/lib/convert/convert_common.hpp40
-rw-r--r--host/lib/convert/convert_orc.orc63
-rw-r--r--host/lib/convert/convert_with_neon.cpp8
-rw-r--r--host/lib/convert/convert_with_orc.cpp54
-rw-r--r--host/lib/convert/convert_with_sse2.cpp16
-rw-r--r--host/lib/convert/gen_convert_general.py8
7 files changed, 193 insertions, 42 deletions
diff --git a/host/lib/convert/CMakeLists.txt b/host/lib/convert/CMakeLists.txt
index d189aa687..5f05b0cb8 100644
--- a/host/lib/convert/CMakeLists.txt
+++ b/host/lib/convert/CMakeLists.txt
@@ -26,6 +26,7 @@ MESSAGE(STATUS "")
########################################################################
IF(CMAKE_COMPILER_IS_GNUCXX)
SET(EMMINTRIN_FLAGS -msse2)
+ SET(NEON_FLAGS "-mfloat-abi=softfp -mfpu=neon")
ELSEIF(MSVC)
SET(EMMINTRIN_FLAGS /arch:SSE2)
ENDIF()
@@ -47,12 +48,53 @@ ENDIF(HAVE_EMMINTRIN_H)
########################################################################
# Check for NEON SIMD headers
########################################################################
+SET(CMAKE_REQUIRED_FLAGS ${NEON_FLAGS})
CHECK_INCLUDE_FILE_CXX(arm_neon.h HAVE_ARM_NEON_H)
-IF(HAVE_ARM_NEON_H)
+UNSET(CMAKE_REQUIRED_FLAGS)
+if(HAVE_ARM_NEON_H)
+ MESSAGE(STATUS "Enabling NEON support")
+ SET_SOURCE_FILES_PROPERTIES(
+ ${CMAKE_CURRENT_SOURCE_DIR}/convert_with_neon.cpp
+ PROPERTIES COMPILE_FLAGS "${NEON_FLAGS}"
+ )
LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/convert_with_neon.cpp
)
-ENDIF(HAVE_ARM_NEON_H)
+else(HAVE_ARM_NEON_H)
+ MESSAGE(STATUS "Disabling NEON support")
+endif(HAVE_ARM_NEON_H)
+########################################################################
+# Look for Orc support
+########################################################################
+FIND_PACKAGE(PkgConfig)
+IF(PKG_CONFIG_FOUND)
+PKG_CHECK_MODULES(ORC "orc-0.4")
+ENDIF(PKG_CONFIG_FOUND)
+
+FIND_PROGRAM(ORCC_EXECUTABLE orcc)
+
+IF(ORC_FOUND AND ORCC_EXECUTABLE)
+ INCLUDE_DIRECTORIES(${ORC_INCLUDE_DIRS})
+ LINK_DIRECTORIES(${ORC_LIBRARY_DIRS})
+ ENABLE_LANGUAGE(C)
+
+ SET(orcc_src ${CMAKE_CURRENT_SOURCE_DIR}/convert_orc.orc)
+
+ GET_FILENAME_COMPONENT(orc_file_name_we ${orcc_src} NAME_WE)
+ SET(orcc_gen ${CMAKE_CURRENT_BINARY_DIR}/${orc_file_name_we}.c)
+ MESSAGE(STATUS "Orc found, enabling Orc support")
+ ADD_CUSTOM_COMMAND(
+ COMMAND ${ORCC_EXECUTABLE} --implementation -o ${orcc_gen} ${orcc_src}
+ DEPENDS ${orcc_src} OUTPUT ${orcc_gen}
+ )
+ LIBUHD_APPEND_SOURCES(${orcc_gen})
+ LIBUHD_APPEND_SOURCES(
+ ${CMAKE_CURRENT_SOURCE_DIR}/convert_with_orc.cpp
+ )
+ LIBUHD_APPEND_LIBS(${ORC_LIBRARIES})
+ELSE()
+ MESSAGE(STATUS "Orc not found, disabling orc support...")
+ENDIF(ORC_FOUND AND ORCC_EXECUTABLE)
########################################################################
# Convert types generation
diff --git a/host/lib/convert/convert_common.hpp b/host/lib/convert/convert_common.hpp
index c2ca233d9..7f513b124 100644
--- a/host/lib/convert/convert_common.hpp
+++ b/host/lib/convert/convert_common.hpp
@@ -27,7 +27,7 @@
static void fcn( \
const uhd::convert::input_type &inputs, \
const uhd::convert::output_type &outputs, \
- size_t nsamps \
+ size_t nsamps, double scale_factor \
); \
UHD_STATIC_BLOCK(register_##fcn##_##prio){ \
uhd::convert::register_converter(#fcn, fcn, prio); \
@@ -35,7 +35,7 @@
static void fcn( \
const uhd::convert::input_type &inputs, \
const uhd::convert::output_type &outputs, \
- size_t nsamps \
+ size_t nsamps, double scale_factor \
)
/***********************************************************************
@@ -50,7 +50,7 @@ typedef boost::uint32_t item32_t;
/***********************************************************************
* Convert complex short buffer to items32
**********************************************************************/
-static UHD_INLINE item32_t sc16_to_item32(sc16_t num){
+static UHD_INLINE item32_t sc16_to_item32(sc16_t num, double){
boost::uint16_t real = num.real();
boost::uint16_t imag = num.imag();
return (item32_t(real) << 16) | (item32_t(imag) << 0);
@@ -59,7 +59,7 @@ static UHD_INLINE item32_t sc16_to_item32(sc16_t num){
/***********************************************************************
* Convert items32 buffer to complex short
**********************************************************************/
-static UHD_INLINE sc16_t item32_to_sc16(item32_t item){
+static UHD_INLINE sc16_t item32_to_sc16(item32_t item, double){
return sc16_t(
boost::int16_t(item >> 16),
boost::int16_t(item >> 0)
@@ -69,46 +69,38 @@ static UHD_INLINE sc16_t item32_to_sc16(item32_t item){
/***********************************************************************
* Convert complex float buffer to items32 (no swap)
**********************************************************************/
-static const float shorts_per_float = float(32767);
-
-static UHD_INLINE item32_t fc32_to_item32(fc32_t num){
- boost::uint16_t real = boost::int16_t(num.real()*shorts_per_float);
- boost::uint16_t imag = boost::int16_t(num.imag()*shorts_per_float);
+static UHD_INLINE item32_t fc32_to_item32(fc32_t num, float scale_factor){
+ boost::uint16_t real = boost::int16_t(num.real()*scale_factor);
+ boost::uint16_t imag = boost::int16_t(num.imag()*scale_factor);
return (item32_t(real) << 16) | (item32_t(imag) << 0);
}
/***********************************************************************
* Convert items32 buffer to complex float
**********************************************************************/
-static const float floats_per_short = float(1.0/shorts_per_float);
-
-static UHD_INLINE fc32_t item32_to_fc32(item32_t item){
+static UHD_INLINE fc32_t item32_to_fc32(item32_t item, float scale_factor){
return fc32_t(
- float(boost::int16_t(item >> 16)*floats_per_short),
- float(boost::int16_t(item >> 0)*floats_per_short)
+ float(boost::int16_t(item >> 16)*scale_factor),
+ float(boost::int16_t(item >> 0)*scale_factor)
);
}
/***********************************************************************
* Convert complex double buffer to items32 (no swap)
**********************************************************************/
-static const double shorts_per_double = double(32767);
-
-static UHD_INLINE item32_t fc64_to_item32(fc64_t num){
- boost::uint16_t real = boost::int16_t(num.real()*shorts_per_double);
- boost::uint16_t imag = boost::int16_t(num.imag()*shorts_per_double);
+static UHD_INLINE item32_t fc64_to_item32(fc64_t num, double scale_factor){
+ boost::uint16_t real = boost::int16_t(num.real()*scale_factor);
+ boost::uint16_t imag = boost::int16_t(num.imag()*scale_factor);
return (item32_t(real) << 16) | (item32_t(imag) << 0);
}
/***********************************************************************
* Convert items32 buffer to complex double
**********************************************************************/
-static const double doubles_per_short = double(1.0/shorts_per_double);
-
-static UHD_INLINE fc64_t item32_to_fc64(item32_t item){
+static UHD_INLINE fc64_t item32_to_fc64(item32_t item, double scale_factor){
return fc64_t(
- float(boost::int16_t(item >> 16)*doubles_per_short),
- float(boost::int16_t(item >> 0)*doubles_per_short)
+ float(boost::int16_t(item >> 16)*scale_factor),
+ float(boost::int16_t(item >> 0)*scale_factor)
);
}
diff --git a/host/lib/convert/convert_orc.orc b/host/lib/convert/convert_orc.orc
new file mode 100644
index 000000000..5450bf4db
--- /dev/null
+++ b/host/lib/convert/convert_orc.orc
@@ -0,0 +1,63 @@
+.function _convert_fc32_1_to_item32_1_nswap_orc
+.source 8 src
+.dest 4 dst
+.floatparam 4 scalar
+.temp 8 scaled
+.temp 8 converted
+.temp 4 short
+x2 mulf scaled, src, scalar
+x2 convfl converted, scaled
+x2 convlw short, converted
+swapl short, short
+x2 swapw dst, short
+
+.function _convert_fc32_1_to_item32_1_bswap_orc
+.source 8 src
+.dest 4 dst
+.floatparam 4 scalar
+.temp 8 scaled
+.temp 8 converted
+.temp 4 short
+x2 mulf scaled, src, scalar
+x2 convfl converted, scaled
+x2 convlw short, converted
+x2 swapw dst, short
+
+.function _convert_item32_1_to_fc32_1_nswap_orc
+.source 4 src
+.dest 8 dst
+.floatparam 4 scalar
+.temp 4 tmp1
+.temp 8 tmp2
+x2 swapw tmp1, src
+swapl tmp1, tmp1
+x2 convswl tmp2, tmp1
+x2 convlf tmp2, tmp2
+x2 mulf dst, tmp2, scalar
+
+.function _convert_item32_1_to_fc32_1_bswap_orc
+.source 4 src
+.dest 8 dst
+.floatparam 4 scalar
+.temp 4 tmp1
+.temp 8 tmp2
+x2 swapw tmp1, src
+x2 convswl tmp2, tmp1
+x2 convlf tmp2, tmp2
+x2 mulf dst, tmp2, scalar
+
+.function _convert_sc16_1_to_item32_1_nswap_orc
+.source 4 src
+.dest 4 dst
+.temp 4 tmp
+.floatparam 4 scalar
+swapl tmp, src
+x2 swapw dst, tmp
+
+.function _convert_item32_1_to_sc16_1_nswap_orc
+.source 4 src
+.dest 4 dst
+.floatparam 4 scalar
+.temp 4 tmp
+x2 swapw tmp, src
+swapl dst, tmp
diff --git a/host/lib/convert/convert_with_neon.cpp b/host/lib/convert/convert_with_neon.cpp
index 3d677db5b..e5f08cad9 100644
--- a/host/lib/convert/convert_with_neon.cpp
+++ b/host/lib/convert/convert_with_neon.cpp
@@ -26,7 +26,7 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_CUSTOM){
size_t i;
- float32x4_t Q0 = vdupq_n_f32(shorts_per_float);
+ float32x4_t Q0 = vdupq_n_f32(float(scale_factor));
for (i=0; i < (nsamps & ~0x03); i+=2) {
float32x4_t Q1 = vld1q_f32(reinterpret_cast<const float *>(&input[i]));
float32x4_t Q2 = vmulq_f32(Q1, Q0);
@@ -37,7 +37,7 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_CUSTOM){
}
for (; i < nsamps; i++)
- output[i] = fc32_to_item32(input[i]);
+ output[i] = fc32_to_item32(input[i], float(scale_factor));
}
DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){
@@ -46,7 +46,7 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){
size_t i;
- float32x4_t Q1 = vdupq_n_f32(floats_per_short);
+ float32x4_t Q1 = vdupq_n_f32(float(scale_factor));
for (i=0; i < (nsamps & ~0x03); i+=2) {
int16x4_t D0 = vld1_s16(reinterpret_cast<const int16_t *>(&input[i]));
int16x4_t D1 = vrev32_s16(D0);
@@ -57,5 +57,5 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){
}
for (; i < nsamps; i++)
- output[i] = item32_to_fc32(input[i]);
+ output[i] = item32_to_fc32(input[i], float(scale_factor));
}
diff --git a/host/lib/convert/convert_with_orc.cpp b/host/lib/convert/convert_with_orc.cpp
new file mode 100644
index 000000000..844c2595c
--- /dev/null
+++ b/host/lib/convert/convert_with_orc.cpp
@@ -0,0 +1,54 @@
+//
+// Copyright 2011 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include "convert_common.hpp"
+#include <uhd/utils/byteswap.hpp>
+
+using namespace uhd::convert;
+
+extern "C" {
+extern void _convert_fc32_1_to_item32_1_nswap_orc(void *, const void *, float, int);
+extern void _convert_fc32_1_to_item32_1_bswap_orc(void *, const void *, float, int);
+extern void _convert_item32_1_to_fc32_1_nswap_orc(void *, const void *, float, int);
+extern void _convert_item32_1_to_fc32_1_bswap_orc(void *, const void *, float, int);
+extern void _convert_sc16_1_to_item32_1_nswap_orc(void *, const void *, float, int);
+extern void _convert_item32_1_to_sc16_1_nswap_orc(void *, const void *, float, int);
+}
+
+DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_LIBORC){
+ _convert_fc32_1_to_item32_1_nswap_orc(outputs[0], inputs[0], scale_factor, nsamps);
+}
+
+DECLARE_CONVERTER(convert_fc32_1_to_item32_1_bswap, PRIORITY_LIBORC){
+ _convert_fc32_1_to_item32_1_bswap_orc(outputs[0], inputs[0], scale_factor, nsamps);
+}
+
+DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_LIBORC){
+ _convert_item32_1_to_fc32_1_nswap_orc(outputs[0], inputs[0], scale_factor, nsamps);
+}
+
+DECLARE_CONVERTER(convert_item32_1_to_fc32_1_bswap, PRIORITY_LIBORC){
+ _convert_item32_1_to_fc32_1_bswap_orc(outputs[0], inputs[0], scale_factor, nsamps);
+}
+
+DECLARE_CONVERTER(convert_sc16_1_to_item32_1_nswap, PRIORITY_LIBORC){
+ _convert_sc16_1_to_item32_1_nswap_orc(outputs[0], inputs[0], scale_factor, nsamps);
+}
+
+DECLARE_CONVERTER(convert_item32_1_to_sc16_1_nswap, PRIORITY_LIBORC){
+ _convert_item32_1_to_sc16_1_nswap_orc(outputs[0], inputs[0], scale_factor, nsamps);
+}
diff --git a/host/lib/convert/convert_with_sse2.cpp b/host/lib/convert/convert_with_sse2.cpp
index 96ee9134c..52beea24a 100644
--- a/host/lib/convert/convert_with_sse2.cpp
+++ b/host/lib/convert/convert_with_sse2.cpp
@@ -25,7 +25,7 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_CUSTOM){
const fc32_t *input = reinterpret_cast<const fc32_t *>(inputs[0]);
item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
- __m128 scalar = _mm_set_ps1(shorts_per_float);
+ __m128 scalar = _mm_set_ps1(float(scale_factor));
//convert blocks of samples with intrinsics
size_t i = 0; for (; i < (nsamps & ~0x3); i+=4){
@@ -48,7 +48,7 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_CUSTOM){
//convert remainder
for (; i < nsamps; i++){
- output[i] = fc32_to_item32(input[i]);
+ output[i] = fc32_to_item32(input[i], float(scale_factor));
}
}
@@ -56,7 +56,7 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_bswap, PRIORITY_CUSTOM){
const fc32_t *input = reinterpret_cast<const fc32_t *>(inputs[0]);
item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
- __m128 scalar = _mm_set_ps1(shorts_per_float);
+ __m128 scalar = _mm_set_ps1(float(scale_factor));
//convert blocks of samples with intrinsics
size_t i = 0; for (; i < (nsamps & ~0x3); i+=4){
@@ -78,7 +78,7 @@ DECLARE_CONVERTER(convert_fc32_1_to_item32_1_bswap, PRIORITY_CUSTOM){
//convert remainder
for (; i < nsamps; i++){
- output[i] = uhd::byteswap(fc32_to_item32(input[i]));
+ output[i] = uhd::byteswap(fc32_to_item32(input[i], float(scale_factor)));
}
}
@@ -86,7 +86,7 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){
const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]);
fc32_t *output = reinterpret_cast<fc32_t *>(outputs[0]);
- __m128 scalar = _mm_set_ps1(floats_per_short/(1 << 16));
+ __m128 scalar = _mm_set_ps1(float(scale_factor)/(1 << 16));
__m128i zeroi = _mm_setzero_si128();
//convert blocks of samples with intrinsics
@@ -111,7 +111,7 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){
//convert remainder
for (; i < nsamps; i++){
- output[i] = item32_to_fc32(input[i]);
+ output[i] = item32_to_fc32(input[i], float(scale_factor));
}
}
@@ -119,7 +119,7 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_bswap, PRIORITY_CUSTOM){
const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]);
fc32_t *output = reinterpret_cast<fc32_t *>(outputs[0]);
- __m128 scalar = _mm_set_ps1(floats_per_short/(1 << 16));
+ __m128 scalar = _mm_set_ps1(float(scale_factor)/(1 << 16));
__m128i zeroi = _mm_setzero_si128();
//convert blocks of samples with intrinsics
@@ -143,6 +143,6 @@ DECLARE_CONVERTER(convert_item32_1_to_fc32_1_bswap, PRIORITY_CUSTOM){
//convert remainder
for (; i < nsamps; i++){
- output[i] = item32_to_fc32(uhd::byteswap(input[i]));
+ output[i] = item32_to_fc32(uhd::byteswap(input[i]), float(scale_factor));
}
}
diff --git a/host/lib/convert/gen_convert_general.py b/host/lib/convert/gen_convert_general.py
index f03448047..8c3138bda 100644
--- a/host/lib/convert/gen_convert_general.py
+++ b/host/lib/convert/gen_convert_general.py
@@ -34,7 +34,7 @@ DECLARE_CONVERTER(convert_$(cpu_type)_1_to_item32_1_$(swap), PRIORITY_GENERAL){
item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
for (size_t i = 0; i < nsamps; i++){
- output[i] = $(swap_fcn)($(cpu_type)_to_item32(input[i]));
+ output[i] = $(swap_fcn)($(cpu_type)_to_item32(input[i], float(scale_factor)));
}
}
@@ -43,7 +43,7 @@ DECLARE_CONVERTER(convert_item32_1_to_$(cpu_type)_1_$(swap), PRIORITY_GENERAL){
$(cpu_type)_t *output = reinterpret_cast<$(cpu_type)_t *>(outputs[0]);
for (size_t i = 0; i < nsamps; i++){
- output[i] = item32_to_$(cpu_type)($(swap_fcn)(input[i]));
+ output[i] = item32_to_$(cpu_type)($(swap_fcn)(input[i]), float(scale_factor));
}
}
"""
@@ -56,7 +56,7 @@ DECLARE_CONVERTER(convert_$(cpu_type)_$(width)_to_item32_1_$(swap), PRIORITY_GEN
for (size_t i = 0, j = 0; i < nsamps; i++){
#for $w in range($width)
- output[j++] = $(swap_fcn)($(cpu_type)_to_item32(input$(w)[i]));
+ output[j++] = $(swap_fcn)($(cpu_type)_to_item32(input$(w)[i], float(scale_factor)));
#end for
}
}
@@ -69,7 +69,7 @@ DECLARE_CONVERTER(convert_item32_1_to_$(cpu_type)_$(width)_$(swap), PRIORITY_GEN
for (size_t i = 0, j = 0; i < nsamps; i++){
#for $w in range($width)
- output$(w)[i] = item32_to_$(cpu_type)($(swap_fcn)(input[j++]));
+ output$(w)[i] = item32_to_$(cpu_type)($(swap_fcn)(input[j++]), float(scale_factor));
#end for
}
}