1 // Copyright (C) 2020 Free Software Foundation, Inc.
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
18 #include "bits/verify.h"
20 // simd_mask generator functions
23 make_mask(const std::initializer_list
<bool>& init
)
42 make_alternating_mask()
44 return make_mask
<M
>({false, true});
51 using M
= typename
V::mask_type
;
53 constexpr size_t alignment
= 2 * std::experimental::memory_alignment_v
<M
>;
54 alignas(alignment
) bool mem
[3 * M::size()];
55 std::memset(mem
, 0, sizeof(mem
));
56 for (std::size_t i
= 1; i
< sizeof(mem
) / sizeof(*mem
); i
+= 2)
58 COMPARE(mem
[i
- 1], false);
61 using std::experimental::element_aligned
;
62 using std::experimental::vector_aligned
;
63 constexpr size_t stride_alignment
78 : M::size() & 128 ? 128
79 : M::size() & 256 ? 256 : 512;
80 using stride_aligned_t
= std::conditional_t
<
81 M::size() == stride_alignment
, decltype(vector_aligned
),
82 std::experimental::overaligned_tag
<stride_alignment
* sizeof(bool)>>;
83 constexpr stride_aligned_t stride_aligned
= {};
84 constexpr auto overaligned
= std::experimental::overaligned
<alignment
>;
86 const M alternating_mask
= make_alternating_mask
<M
>();
88 M
x(&mem
[M::size()], stride_aligned
);
89 COMPARE(x
, M::size() % 2 == 1 ? !alternating_mask
: alternating_mask
)
91 << ", alternating_mask: " << alternating_mask
.__to_bitset();
92 x
= {&mem
[1], element_aligned
};
93 COMPARE(x
, !alternating_mask
);
94 x
= M
{mem
, overaligned
};
95 COMPARE(x
, alternating_mask
);
97 x
.copy_from(&mem
[M::size()], stride_aligned
);
98 COMPARE(x
, M::size() % 2 == 1 ? !alternating_mask
: alternating_mask
);
99 x
.copy_from(&mem
[1], element_aligned
);
100 COMPARE(x
, !alternating_mask
);
101 x
.copy_from(mem
, vector_aligned
);
102 COMPARE(x
, alternating_mask
);
104 x
= !alternating_mask
;
105 where(alternating_mask
, x
).copy_from(&mem
[M::size()], stride_aligned
);
106 COMPARE(x
, M::size() % 2 == 1 ? !alternating_mask
: M
{true});
108 where(alternating_mask
, x
).copy_from(&mem
[1], element_aligned
); // load .0.0
109 COMPARE(x
, !alternating_mask
); // 1010
110 where(alternating_mask
, x
).copy_from(mem
, overaligned
); // load .1.1
111 COMPARE(x
, M
{true}); // 1111
114 memset(mem
, 0, sizeof(mem
));
116 x
.copy_to(&mem
[M::size()], stride_aligned
);
118 for (; i
< M::size(); ++i
)
120 COMPARE(mem
[i
], false);
122 for (; i
< 2 * M::size(); ++i
)
124 COMPARE(mem
[i
], true) << "i: " << i
<< ", x: " << x
;
126 for (; i
< 3 * M::size(); ++i
)
128 COMPARE(mem
[i
], false);
130 memset(mem
, 0, sizeof(mem
));
131 x
.copy_to(&mem
[1], element_aligned
);
132 COMPARE(mem
[0], false);
133 for (i
= 1; i
<= M::size(); ++i
)
135 COMPARE(mem
[i
], true);
137 for (; i
< 3 * M::size(); ++i
)
139 COMPARE(mem
[i
], false);
141 memset(mem
, 0, sizeof(mem
));
142 alternating_mask
.copy_to(mem
, overaligned
);
143 for (i
= 0; i
< M::size(); ++i
)
145 COMPARE(mem
[i
], (i
& 1) == 1);
147 for (; i
< 3 * M::size(); ++i
)
149 COMPARE(mem
[i
], false);
151 x
.copy_to(mem
, vector_aligned
);
152 where(alternating_mask
, !x
).copy_to(mem
, overaligned
);
153 for (i
= 0; i
< M::size(); ++i
)
155 COMPARE(mem
[i
], i
% 2 == 0);
157 for (; i
< 3 * M::size(); ++i
)
159 COMPARE(mem
[i
], false);