1 | /* Copyright (C) 2013 Povilas Kanapickas <povilas@radix.lt> |
2 | |
3 | Distributed under the Boost Software License, Version 1.0. |
4 | (See accompanying file LICENSE_1_0.txt or copy at |
5 | http://www.boost.org/LICENSE_1_0.txt) |
6 | */ |
7 | |
8 | #ifndef LIBSIMDPP_ALTIVEC_LOAD1_H |
9 | #define LIBSIMDPP_ALTIVEC_LOAD1_H |
10 | #if SIMDPP_USE_ALTIVEC |
11 | |
12 | #ifndef LIBSIMDPP_SIMD_H |
13 | #error "This file must be included through simd.h" |
14 | #endif |
15 | |
16 | #include <simdpp/types.h> |
17 | |
18 | namespace simdpp { |
19 | namespace SIMDPP_ARCH_NAMESPACE { |
20 | namespace detail { |
21 | namespace altivec { |
22 | |
23 | /** Loads a single element from unaligned memory location and places it to the |
24 | first position in the vector. The contents of the rest of the vector are |
25 | undefined. |
26 | |
27 | @code |
28 | a.vec(0) = *p |
29 | @endcode |
30 | |
31 | @icost{ALTIVEC, 2} |
32 | */ |
33 | static SIMDPP_INL |
34 | uint8x16 load1_u(uint8x16& a, const uint8_t* p) |
35 | { |
36 | a = vec_lde(0, p); |
37 | #pragma GCC diagnostic push |
38 | #pragma GCC diagnostic ignored "-Wdeprecated" |
39 | __vector uint8_t perm = vec_lvsl(0, p); |
40 | #pragma GCC diagnostic pop |
41 | a = (__vector uint8_t) vec_perm(a.native(), a.native(), perm); |
42 | return a; |
43 | } |
44 | |
45 | static SIMDPP_INL |
46 | uint16x8 load1_u(uint16x8& a, const uint16_t* p) |
47 | { |
48 | __vector uint16_t r = vec_lde(0, p); |
49 | #pragma GCC diagnostic push |
50 | #pragma GCC diagnostic ignored "-Wdeprecated" |
51 | __vector uint8_t perm = vec_lvsl(0, p); |
52 | #pragma GCC diagnostic pop |
53 | a = (__vector uint16_t) vec_perm((__vector uint8_t)r, |
54 | (__vector uint8_t)r, perm); |
55 | return a; |
56 | } |
57 | |
58 | static SIMDPP_INL |
59 | uint32x4 load1_u(uint32x4& a, const uint32_t* p) |
60 | { |
61 | __vector uint32_t r = vec_lde(0, p); |
62 | #pragma GCC diagnostic push |
63 | #pragma GCC diagnostic ignored "-Wdeprecated" |
64 | __vector uint8_t perm = vec_lvsl(0, p); |
65 | #pragma GCC diagnostic pop |
66 | a = (__vector uint32_t) vec_perm((__vector uint8_t)r, |
67 | (__vector uint8_t)r, perm); |
68 | return a; |
69 | } |
70 | |
71 | static SIMDPP_INL |
72 | float32x4 load1_u(float32x4& a, const float* p) |
73 | { |
74 | __vector float r = vec_lde(0, p); |
75 | #pragma GCC diagnostic push |
76 | #pragma GCC diagnostic ignored "-Wdeprecated" |
77 | __vector uint8_t perm = vec_lvsl(0, p); |
78 | #pragma GCC diagnostic pop |
79 | a = (__vector float) vec_perm((__vector uint8_t)r, |
80 | (__vector uint8_t)r, perm); |
81 | return a; |
82 | } |
83 | |
84 | /** Loads a single element from a memory location and places it to the vector. |
85 | The position of the element is determined by the last 4 address @a p bits. |
86 | The contents of the rest of the vector are undefined. |
87 | |
88 | @code |
89 | i = (p % 15) / sizeof(element) |
90 | a[i] = *p |
91 | @endcode |
92 | */ |
93 | static SIMDPP_INL |
94 | uint8x16 load1(uint8x16& a, const uint8_t* p) |
95 | { |
96 | a = vec_lde(0, p); |
97 | return a; |
98 | } |
99 | |
100 | static SIMDPP_INL |
101 | uint16x8 load1(uint16x8& a, const uint16_t* p) |
102 | { |
103 | a = vec_lde(0, p); |
104 | return a; |
105 | } |
106 | |
107 | static SIMDPP_INL |
108 | uint32x4 load1(uint32x4& a, const uint32_t* p) |
109 | { |
110 | a = vec_lde(0, p); |
111 | return a; |
112 | } |
113 | |
114 | static SIMDPP_INL |
115 | float32x4 load1(float32x4& a, const float* p) |
116 | { |
117 | a = vec_lde(0, p); |
118 | return a; |
119 | } |
120 | |
121 | } // namespace altivec |
122 | } // namespace detail |
123 | } // namespace SIMDPP_ARCH_NAMESPACE |
124 | } // namespace simdpp |
125 | |
126 | #endif |
127 | #endif |
128 | |