aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/convert/convert_pack_sc12.cpp
diff options
context:
space:
mode:
authorTom Tsou <tom.tsou@ettus.com>2017-07-07 15:32:20 -0700
committerMartin Braun <martin.braun@ettus.com>2017-07-25 10:15:37 -0700
commit0e9f204029e5eac51d94f16ceb19f003e3faf7e8 (patch)
treead71a66f4aa84fc17e965d8682741584f64aa18d /host/lib/convert/convert_pack_sc12.cpp
parent8223a289727bbda353bd7129512daf00d46d898c (diff)
downloaduhd-0e9f204029e5eac51d94f16ceb19f003e3faf7e8.tar.gz
uhd-0e9f204029e5eac51d94f16ceb19f003e3faf7e8.tar.bz2
uhd-0e9f204029e5eac51d94f16ceb19f003e3faf7e8.zip
convert: Add SSE implementation for sc12
Implementation uses SSSE3 intructions to perform 12-bit sample pack/unpack operations to/from standard 16 and 32 bit host values. Input/output shuffle orderings for a single 128-bit SSE register with 16-bit integers shown below. 16-bit interleaved I/Q --------------------------------------- | Q3 | I3 | Q2 | I2 | Q1 | I1 | Q0 | I0 | Input --------------------------------------- | 127 0 | 12-bit packed I/Q byteswapped ----------------------- | I0 | Q0 | I1 | 0 |-----------------------| | I1 | Q1 | I2 | Q2 | Output |-----------------------| | Q2 | I3 | Q3 | |-----------------------| | Unused | 3 ----------------------- 31 0 Fixes: #1740, #966 Related: #1739
Diffstat (limited to 'host/lib/convert/convert_pack_sc12.cpp')
-rw-r--r--host/lib/convert/convert_pack_sc12.cpp116
1 files changed, 2 insertions, 114 deletions
diff --git a/host/lib/convert/convert_pack_sc12.cpp b/host/lib/convert/convert_pack_sc12.cpp
index 2e45e19f5..85194dcdd 100644
--- a/host/lib/convert/convert_pack_sc12.cpp
+++ b/host/lib/convert/convert_pack_sc12.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2013 Ettus Research LLC
+// Copyright 2017 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
@@ -15,122 +15,10 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-#include "convert_common.hpp"
-#include <uhd/utils/byteswap.hpp>
-#include <uhd/utils/log.hpp>
-#include <boost/math/special_functions/round.hpp>
-#include <vector>
-#include <type_traits>
+#include "convert_pack_sc12.hpp"
using namespace uhd::convert;
-typedef uint32_t (*towire32_type)(uint32_t);
-
-/* C language specification requires this to be packed
- * (i.e., line0, line1, line2 will be in adjacent memory locations).
- * If this was not true, we'd need compiler flags here to specify
- * alignment/packing.
- */
-struct item32_sc12_3x
-{
- item32_t line0;
- item32_t line1;
- item32_t line2;
-};
-
-enum item32_sc12_3x_enable {
- CONVERT12_LINE0 = 0x01,
- CONVERT12_LINE1 = 0x02,
- CONVERT12_LINE2 = 0x04,
- CONVERT12_LINE_ALL = 0x07,
-};
-
-/*
- * Packed 12-bit converter with selective line enable
- *
- * The converter operates on 4 complex inputs and selectively writes to one to
- * three 32-bit lines. Line selection allows for partial writes of less than
- * 4 complex samples, or a full 3 x 32-bit struct. Writes are always full 32-bit
- * lines, so in the case of partial writes, the number of bytes written will
- * exceed the the number of bytes filled by actual samples.
- *
- * _ _ _ _ _ _ _ _
- * |_ _ _1_ _ _|_ _| 0
- * |_2_ _ _|_ _ _3_|
- * |_ _|_ _ _4_ _ _| 2
- * 31 0
- */
-template <towire32_type towire>
-inline void pack(item32_sc12_3x &output, int enable, const int32_t i[4], const int32_t q[4])
-{
- if (enable & CONVERT12_LINE0)
- output.line0 = towire(i[0] << 20 | q[0] << 8 | i[1] >> 4);
- if (enable & CONVERT12_LINE1)
- output.line1 = towire(i[1] << 28 | q[1] << 16 | i[2] << 4 | q[2] >> 8);
- if (enable & CONVERT12_LINE2)
- output.line2 = towire(q[2] << 24 | i[3] << 12 | q[3]);
-}
-
-template <typename type, towire32_type towire>
-void convert_star_4_to_sc12_item32_3
-(
- const std::complex<type> &in0,
- const std::complex<type> &in1,
- const std::complex<type> &in2,
- const std::complex<type> &in3,
- const int enable,
- item32_sc12_3x &output,
- const double scalar,
- typename std::enable_if<std::is_floating_point<type>::value>::type* = NULL
-)
-{
- int32_t i[4] {
- int32_t(in0.real()*scalar) & 0xfff,
- int32_t(in1.real()*scalar) & 0xfff,
- int32_t(in2.real()*scalar) & 0xfff,
- int32_t(in3.real()*scalar) & 0xfff,
- };
-
- int32_t q[4] {
- int32_t(in0.imag()*scalar) & 0xfff,
- int32_t(in1.imag()*scalar) & 0xfff,
- int32_t(in2.imag()*scalar) & 0xfff,
- int32_t(in3.imag()*scalar) & 0xfff,
- };
-
- pack<towire>(output, enable, i, q);
-}
-
-template <typename type, towire32_type towire>
-void convert_star_4_to_sc12_item32_3
-(
- const std::complex<type> &in0,
- const std::complex<type> &in1,
- const std::complex<type> &in2,
- const std::complex<type> &in3,
- const int enable,
- item32_sc12_3x &output,
- const double,
- typename std::enable_if<std::is_same<type, short>::value>::type* = NULL
-)
-{
- int32_t i[4] {
- int32_t(in0.real() >> 4) & 0xfff,
- int32_t(in1.real() >> 4) & 0xfff,
- int32_t(in2.real() >> 4) & 0xfff,
- int32_t(in3.real() >> 4) & 0xfff,
- };
-
- int32_t q[4] {
- int32_t(in0.imag() >> 4) & 0xfff,
- int32_t(in1.imag() >> 4) & 0xfff,
- int32_t(in2.imag() >> 4) & 0xfff,
- int32_t(in3.imag() >> 4) & 0xfff,
- };
-
- pack<towire>(output, enable, i, q);
-}
-
template <typename type, towire32_type towire>
struct convert_star_1_to_sc12_item32_1 : public converter
{