diff options
author | Tom Tsou <tom.tsou@ettus.com> | 2017-07-07 15:32:20 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2017-07-25 10:15:37 -0700 |
commit | 0e9f204029e5eac51d94f16ceb19f003e3faf7e8 (patch) | |
tree | ad71a66f4aa84fc17e965d8682741584f64aa18d /host/lib/convert/convert_unpack_sc12.cpp | |
parent | 8223a289727bbda353bd7129512daf00d46d898c (diff) | |
download | uhd-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_unpack_sc12.cpp')
-rw-r--r-- | host/lib/convert/convert_unpack_sc12.cpp | 99 |
1 files changed, 2 insertions, 97 deletions
diff --git a/host/lib/convert/convert_unpack_sc12.cpp b/host/lib/convert/convert_unpack_sc12.cpp index 07f9cffa0..43c35ee3b 100644 --- a/host/lib/convert/convert_unpack_sc12.cpp +++ b/host/lib/convert/convert_unpack_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,105 +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_unpack_sc12.hpp" using namespace uhd::convert; -typedef uint32_t (*tohost32_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; -}; - -/* - * convert_sc12_item32_3_to_star_4 takes in 3 lines with 32 bit each - * and converts them 4 samples of type 'std::complex<type>'. - * The structure of the 3 lines is as follows: - * _ _ _ _ _ _ _ _ - * |_ _ _1_ _ _|_ _| - * |_2_ _ _|_ _ _3_| - * |_ _|_ _ _4_ _ _| - * - * The numbers mark the position of one complex sample. - */ -template <typename type, tohost32_type tohost> -void convert_sc12_item32_3_to_star_4 -( - const item32_sc12_3x &input, - std::complex<type> &out0, - std::complex<type> &out1, - std::complex<type> &out2, - std::complex<type> &out3, - const double scalar, - typename std::enable_if<std::is_floating_point<type>::value>::type* = NULL -) -{ - //step 0: extract the lines from the input buffer - const item32_t line0 = tohost(input.line0); - const item32_t line1 = tohost(input.line1); - const item32_t line2 = tohost(input.line2); - const uint64_t line01 = (uint64_t(line0) << 32) | line1; - const uint64_t line12 = (uint64_t(line1) << 32) | line2; - - //step 1: shift out and mask off the individual numbers - const type i0 = type(int16_t((line0 >> 16) & 0xfff0)*scalar); - const type q0 = type(int16_t((line0 >> 4) & 0xfff0)*scalar); - - const type i1 = type(int16_t((line01 >> 24) & 0xfff0)*scalar); - const type q1 = type(int16_t((line1 >> 12) & 0xfff0)*scalar); - - const type i2 = type(int16_t((line1 >> 0) & 0xfff0)*scalar); - const type q2 = type(int16_t((line12 >> 20) & 0xfff0)*scalar); - - const type i3 = type(int16_t((line2 >> 8) & 0xfff0)*scalar); - const type q3 = type(int16_t((line2 << 4) & 0xfff0)*scalar); - - //step 2: load the outputs - out0 = std::complex<type>(i0, q0); - out1 = std::complex<type>(i1, q1); - out2 = std::complex<type>(i2, q2); - out3 = std::complex<type>(i3, q3); -} - -template <typename type, tohost32_type tohost> -void convert_sc12_item32_3_to_star_4 -( - const item32_sc12_3x &input, - std::complex<type> &out0, - std::complex<type> &out1, - std::complex<type> &out2, - std::complex<type> &out3, - const double, - typename std::enable_if<std::is_integral<type>::value>::type* = NULL -) -{ - //step 0: extract the lines from the input buffer - const item32_t line0 = tohost(input.line0); - const item32_t line1 = tohost(input.line1); - const item32_t line2 = tohost(input.line2); - const uint64_t line01 = (uint64_t(line0) << 32) | line1; - const uint64_t line12 = (uint64_t(line1) << 32) | line2; - - //step 1: extract and load the outputs - out0 = std::complex<type>(line0 >> 16 & 0xfff0, line0 >> 4 & 0xfff0); - out1 = std::complex<type>(line01 >> 24 & 0xfff0, line1 >> 12 & 0xfff0); - out2 = std::complex<type>(line1 >> 0 & 0xfff0, line12 >> 20 & 0xfff0); - out3 = std::complex<type>(line2 >> 8 & 0xfff0, line2 << 4 & 0xfff0); -} - template <typename type, tohost32_type tohost> struct convert_sc12_item32_1_to_star_1 : public converter { |