Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/c++/13/experimental/bits/simd_scalar.h
$ cat -n /usr/include/c++/13/experimental/bits/simd_scalar.h 1 // Simd scalar ABI specific implementations -*- C++ -*- 2 3 // Copyright (C) 2020-2023 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 #ifndef _GLIBCXX_EXPERIMENTAL_SIMD_SCALAR_H_ 26 #define _GLIBCXX_EXPERIMENTAL_SIMD_SCALAR_H_ 27 #if __cplusplus >= 201703L 28 29 #include <cmath> 30 31 _GLIBCXX_SIMD_BEGIN_NAMESPACE 32 33 // __promote_preserving_unsigned{{{ 34 // work around crazy semantics of unsigned integers of lower rank than int: 35 // Before applying an operator the operands are promoted to int. In which case 36 // over- or underflow is UB, even though the operand types were unsigned. 37 template <typename _Tp> 38 _GLIBCXX_SIMD_INTRINSIC constexpr decltype(auto) 39 __promote_preserving_unsigned(const _Tp& __x) 40 { 41 if constexpr (is_signed_v<decltype(+__x)> && is_unsigned_v<_Tp>) 42 return static_cast<unsigned int>(__x); 43 else 44 return __x; 45 } 46 47 // }}} 48 49 struct _CommonImplScalar; 50 struct _CommonImplBuiltin; 51 struct _SimdImplScalar; 52 struct _MaskImplScalar; 53 54 // simd_abi::_Scalar {{{ 55 struct simd_abi::_Scalar 56 { 57 template <typename _Tp> 58 static constexpr size_t _S_size = 1; 59 60 template <typename _Tp> 61 static constexpr size_t _S_full_size = 1; 62 63 template <typename _Tp> 64 static constexpr bool _S_is_partial = false; 65 66 struct _IsValidAbiTag : true_type {}; 67 68 template <typename _Tp> 69 struct _IsValidSizeFor : true_type {}; 70 71 template <typename _Tp> 72 struct _IsValid : __is_vectorizable<_Tp> {}; 73 74 template <typename _Tp> 75 static constexpr bool _S_is_valid_v = _IsValid<_Tp>::value; 76 77 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 78 _S_masked(bool __x) 79 { return __x; } 80 81 using _CommonImpl = _CommonImplScalar; 82 using _SimdImpl = _SimdImplScalar; 83 using _MaskImpl = _MaskImplScalar; 84 85 template <typename _Tp, bool = _S_is_valid_v<_Tp>> 86 struct __traits : _InvalidTraits {}; 87 88 template <typename _Tp> 89 struct __traits<_Tp, true> 90 { 91 using _IsValid = true_type; 92 using _SimdImpl = _SimdImplScalar; 93 using _MaskImpl = _MaskImplScalar; 94 using _SimdMember = _Tp; 95 using _MaskMember = bool; 96 97 static constexpr size_t _S_simd_align = alignof(_SimdMember); 98 static constexpr size_t _S_mask_align = alignof(_MaskMember); 99 100 // nothing the user can spell converts to/from simd/simd_mask 101 struct _SimdCastType { _SimdCastType() = delete; }; 102 struct _MaskCastType { _MaskCastType() = delete; }; 103 struct _SimdBase {}; 104 struct _MaskBase {}; 105 }; 106 }; 107 108 // }}} 109 // _CommonImplScalar {{{ 110 struct _CommonImplScalar 111 { 112 // _S_store {{{ 113 template <typename _Tp> 114 _GLIBCXX_SIMD_INTRINSIC static void 115 _S_store(_Tp __x, void* __addr) 116 { __builtin_memcpy(__addr, &__x, sizeof(_Tp)); } 117 118 // }}} 119 // _S_store_bool_array(_BitMask) {{{ 120 template <size_t _Np, bool _Sanitized> 121 _GLIBCXX_SIMD_INTRINSIC static constexpr void 122 _S_store_bool_array(_BitMask<_Np, _Sanitized> __x, bool* __mem) 123 { 124 __make_dependent_t<decltype(__x), _CommonImplBuiltin>::_S_store_bool_array( 125 __x, __mem); 126 } 127 128 // }}} 129 }; 130 131 // }}} 132 // _SimdImplScalar {{{ 133 struct _SimdImplScalar 134 { 135 // member types {{{2 136 using abi_type = simd_abi::scalar; 137 138 template <typename _Tp> 139 using _TypeTag = _Tp*; 140 141 // _S_broadcast {{{2 142 template <typename _Tp> 143 _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp 144 _S_broadcast(_Tp __x) noexcept 145 { return __x; } 146 147 // _S_generator {{{2 148 template <typename _Fp, typename _Tp> 149 _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp 150 _S_generator(_Fp&& __gen, _TypeTag<_Tp>) 151 { return __gen(_SizeConstant<0>()); } 152 153 // _S_load {{{2 154 template <typename _Tp, typename _Up> 155 _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp 156 _S_load(const _Up* __mem, _TypeTag<_Tp>) noexcept 157 { return static_cast<_Tp>(__mem[0]); } 158 159 // _S_masked_load {{{2 160 template <typename _Tp, typename _Up> 161 _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp 162 _S_masked_load(_Tp __merge, bool __k, const _Up* __mem) noexcept 163 { 164 if (__k) 165 __merge = static_cast<_Tp>(__mem[0]); 166 return __merge; 167 } 168 169 // _S_store {{{2 170 template <typename _Tp, typename _Up> 171 _GLIBCXX_SIMD_INTRINSIC static constexpr void 172 _S_store(_Tp __v, _Up* __mem, _TypeTag<_Tp>) noexcept 173 { __mem[0] = static_cast<_Up>(__v); } 174 175 // _S_masked_store {{{2 176 template <typename _Tp, typename _Up> 177 _GLIBCXX_SIMD_INTRINSIC static constexpr void 178 _S_masked_store(const _Tp __v, _Up* __mem, const bool __k) noexcept 179 { if (__k) __mem[0] = __v; } 180 181 // _S_negate {{{2 182 template <typename _Tp> 183 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 184 _S_negate(_Tp __x) noexcept 185 { return !__x; } 186 187 // _S_reduce {{{2 188 template <typename _Tp, typename _BinaryOperation> 189 _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp 190 _S_reduce(const simd<_Tp, simd_abi::scalar>& __x, const _BinaryOperation&) 191 { return __x._M_data; } 192 193 // _S_min, _S_max {{{2 194 template <typename _Tp> 195 _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp 196 _S_min(const _Tp __a, const _Tp __b) 197 { return std::min(__a, __b); } 198 199 template <typename _Tp> 200 _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp 201 _S_max(const _Tp __a, const _Tp __b) 202 { return std::max(__a, __b); } 203 204 // _S_complement {{{2 205 template <typename _Tp> 206 _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp 207 _S_complement(_Tp __x) noexcept 208 { return static_cast<_Tp>(~__x); } 209 210 // _S_unary_minus {{{2 211 template <typename _Tp> 212 _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp 213 _S_unary_minus(_Tp __x) noexcept 214 { return static_cast<_Tp>(-__x); } 215 216 // arithmetic operators {{{2 217 template <typename _Tp> 218 _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp 219 _S_plus(_Tp __x, _Tp __y) 220 { 221 return static_cast<_Tp>(__promote_preserving_unsigned(__x) 222 + __promote_preserving_unsigned(__y)); 223 } 224 225 template <typename _Tp> 226 _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp 227 _S_minus(_Tp __x, _Tp __y) 228 { 229 return static_cast<_Tp>(__promote_preserving_unsigned(__x) 230 - __promote_preserving_unsigned(__y)); 231 } 232 233 template <typename _Tp> 234 _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp 235 _S_multiplies(_Tp __x, _Tp __y) 236 { 237 return static_cast<_Tp>(__promote_preserving_unsigned(__x) 238 * __promote_preserving_unsigned(__y)); 239 } 240 241 template <typename _Tp> 242 _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp 243 _S_divides(_Tp __x, _Tp __y) 244 { 245 return static_cast<_Tp>(__promote_preserving_unsigned(__x) 246 / __promote_preserving_unsigned(__y)); 247 } 248 249 template <typename _Tp> 250 _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp 251 _S_modulus(_Tp __x, _Tp __y) 252 { 253 return static_cast<_Tp>(__promote_preserving_unsigned(__x) 254 % __promote_preserving_unsigned(__y)); 255 } 256 257 template <typename _Tp> 258 _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp 259 _S_bit_and(_Tp __x, _Tp __y) 260 { 261 if constexpr (is_floating_point_v<_Tp>) 262 { 263 using _Ip = __int_for_sizeof_t<_Tp>; 264 return __bit_cast<_Tp>(__bit_cast<_Ip>(__x) & __bit_cast<_Ip>(__y)); 265 } 266 else 267 return static_cast<_Tp>(__promote_preserving_unsigned(__x) 268 & __promote_preserving_unsigned(__y)); 269 } 270 271 template <typename _Tp> 272 _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp 273 _S_bit_or(_Tp __x, _Tp __y) 274 { 275 if constexpr (is_floating_point_v<_Tp>) 276 { 277 using _Ip = __int_for_sizeof_t<_Tp>; 278 return __bit_cast<_Tp>(__bit_cast<_Ip>(__x) | __bit_cast<_Ip>(__y)); 279 } 280 else 281 return static_cast<_Tp>(__promote_preserving_unsigned(__x) 282 | __promote_preserving_unsigned(__y)); 283 } 284 285 template <typename _Tp> 286 _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp 287 _S_bit_xor(_Tp __x, _Tp __y) 288 { 289 if constexpr (is_floating_point_v<_Tp>) 290 { 291 using _Ip = __int_for_sizeof_t<_Tp>; 292 return __bit_cast<_Tp>(__bit_cast<_Ip>(__x) ^ __bit_cast<_Ip>(__y)); 293 } 294 else 295 return static_cast<_Tp>(__promote_preserving_unsigned(__x) 296 ^ __promote_preserving_unsigned(__y)); 297 } 298 299 template <typename _Tp> 300 _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp 301 _S_bit_shift_left(_Tp __x, int __y) 302 { return static_cast<_Tp>(__promote_preserving_unsigned(__x) << __y); } 303 304 template <typename _Tp> 305 _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp 306 _S_bit_shift_right(_Tp __x, int __y) 307 { return static_cast<_Tp>(__promote_preserving_unsigned(__x) >> __y); } 308 309 // math {{{2 310 // frexp, modf and copysign implemented in simd_math.h 311 template <typename _Tp> 312 using _ST = _SimdTuple<_Tp, simd_abi::scalar>; 313 314 template <typename _Tp> 315 _GLIBCXX_SIMD_INTRINSIC static _Tp 316 _S_acos(_Tp __x) 317 { return std::acos(__x); } 318 319 template <typename _Tp> 320 _GLIBCXX_SIMD_INTRINSIC static _Tp 321 _S_asin(_Tp __x) 322 { return std::asin(__x); } 323 324 template <typename _Tp> 325 _GLIBCXX_SIMD_INTRINSIC static _Tp 326 _S_atan(_Tp __x) 327 { return std::atan(__x); } 328 329 template <typename _Tp> 330 _GLIBCXX_SIMD_INTRINSIC static _Tp 331 _S_cos(_Tp __x) 332 { return std::cos(__x); } 333 334 template <typename _Tp> 335 _GLIBCXX_SIMD_INTRINSIC static _Tp 336 _S_sin(_Tp __x) 337 { return std::sin(__x); } 338 339 template <typename _Tp> 340 _GLIBCXX_SIMD_INTRINSIC static _Tp 341 _S_tan(_Tp __x) 342 { return std::tan(__x); } 343 344 template <typename _Tp> 345 _GLIBCXX_SIMD_INTRINSIC static _Tp 346 _S_acosh(_Tp __x) 347 { return std::acosh(__x); } 348 349 template <typename _Tp> 350 _GLIBCXX_SIMD_INTRINSIC static _Tp 351 _S_asinh(_Tp __x) 352 { return std::asinh(__x); } 353 354 template <typename _Tp> 355 _GLIBCXX_SIMD_INTRINSIC static _Tp 356 _S_atanh(_Tp __x) 357 { return std::atanh(__x); } 358 359 template <typename _Tp> 360 _GLIBCXX_SIMD_INTRINSIC static _Tp 361 _S_cosh(_Tp __x) 362 { return std::cosh(__x); } 363 364 template <typename _Tp> 365 _GLIBCXX_SIMD_INTRINSIC static _Tp 366 _S_sinh(_Tp __x) 367 { return std::sinh(__x); } 368 369 template <typename _Tp> 370 _GLIBCXX_SIMD_INTRINSIC static _Tp 371 _S_tanh(_Tp __x) 372 { return std::tanh(__x); } 373 374 template <typename _Tp> 375 _GLIBCXX_SIMD_INTRINSIC static _Tp 376 _S_atan2(_Tp __x, _Tp __y) 377 { return std::atan2(__x, __y); } 378 379 template <typename _Tp> 380 _GLIBCXX_SIMD_INTRINSIC static _Tp 381 _S_exp(_Tp __x) 382 { return std::exp(__x); } 383 384 template <typename _Tp> 385 _GLIBCXX_SIMD_INTRINSIC static _Tp 386 _S_exp2(_Tp __x) 387 { return std::exp2(__x); } 388 389 template <typename _Tp> 390 _GLIBCXX_SIMD_INTRINSIC static _Tp 391 _S_expm1(_Tp __x) 392 { return std::expm1(__x); } 393 394 template <typename _Tp> 395 _GLIBCXX_SIMD_INTRINSIC static _Tp 396 _S_log(_Tp __x) 397 { return std::log(__x); } 398 399 template <typename _Tp> 400 _GLIBCXX_SIMD_INTRINSIC static _Tp 401 _S_log10(_Tp __x) 402 { return std::log10(__x); } 403 404 template <typename _Tp> 405 _GLIBCXX_SIMD_INTRINSIC static _Tp 406 _S_log1p(_Tp __x) 407 { return std::log1p(__x); } 408 409 template <typename _Tp> 410 _GLIBCXX_SIMD_INTRINSIC static _Tp 411 _S_log2(_Tp __x) 412 { return std::log2(__x); } 413 414 template <typename _Tp> 415 _GLIBCXX_SIMD_INTRINSIC static _Tp 416 _S_logb(_Tp __x) 417 { return std::logb(__x); } 418 419 template <typename _Tp> 420 _GLIBCXX_SIMD_INTRINSIC static _ST<int> 421 _S_ilogb(_Tp __x) 422 { return {std::ilogb(__x)}; } 423 424 template <typename _Tp> 425 _GLIBCXX_SIMD_INTRINSIC static _Tp 426 _S_pow(_Tp __x, _Tp __y) 427 { return std::pow(__x, __y); } 428 429 template <typename _Tp> 430 _GLIBCXX_SIMD_INTRINSIC static _Tp 431 _S_abs(_Tp __x) 432 { return std::abs(__x); } 433 434 template <typename _Tp> 435 _GLIBCXX_SIMD_INTRINSIC static _Tp 436 _S_fabs(_Tp __x) 437 { return std::fabs(__x); } 438 439 template <typename _Tp> 440 _GLIBCXX_SIMD_INTRINSIC static _Tp 441 _S_sqrt(_Tp __x) 442 { return std::sqrt(__x); } 443 444 template <typename _Tp> 445 _GLIBCXX_SIMD_INTRINSIC static _Tp 446 _S_cbrt(_Tp __x) 447 { return std::cbrt(__x); } 448 449 template <typename _Tp> 450 _GLIBCXX_SIMD_INTRINSIC static _Tp 451 _S_erf(_Tp __x) 452 { return std::erf(__x); } 453 454 template <typename _Tp> 455 _GLIBCXX_SIMD_INTRINSIC static _Tp 456 _S_erfc(_Tp __x) 457 { return std::erfc(__x); } 458 459 template <typename _Tp> 460 _GLIBCXX_SIMD_INTRINSIC static _Tp 461 _S_lgamma(_Tp __x) 462 { return std::lgamma(__x); } 463 464 template <typename _Tp> 465 _GLIBCXX_SIMD_INTRINSIC static _Tp 466 _S_tgamma(_Tp __x) 467 { return std::tgamma(__x); } 468 469 template <typename _Tp> 470 _GLIBCXX_SIMD_INTRINSIC static _Tp 471 _S_trunc(_Tp __x) 472 { return std::trunc(__x); } 473 474 template <typename _Tp> 475 _GLIBCXX_SIMD_INTRINSIC static _Tp 476 _S_floor(_Tp __x) 477 { return std::floor(__x); } 478 479 template <typename _Tp> 480 _GLIBCXX_SIMD_INTRINSIC static _Tp 481 _S_ceil(_Tp __x) 482 { return std::ceil(__x); } 483 484 template <typename _Tp> 485 _GLIBCXX_SIMD_INTRINSIC static _Tp 486 _S_nearbyint(_Tp __x) 487 { return std::nearbyint(__x); } 488 489 template <typename _Tp> 490 _GLIBCXX_SIMD_INTRINSIC static _Tp 491 _S_rint(_Tp __x) 492 { return std::rint(__x); } 493 494 template <typename _Tp> 495 _GLIBCXX_SIMD_INTRINSIC static _ST<long> 496 _S_lrint(_Tp __x) 497 { return {std::lrint(__x)}; } 498 499 template <typename _Tp> 500 _GLIBCXX_SIMD_INTRINSIC static _ST<long long> 501 _S_llrint(_Tp __x) 502 { return {std::llrint(__x)}; } 503 504 template <typename _Tp> 505 _GLIBCXX_SIMD_INTRINSIC static _Tp 506 _S_round(_Tp __x) 507 { return std::round(__x); } 508 509 template <typename _Tp> 510 _GLIBCXX_SIMD_INTRINSIC static _ST<long> 511 _S_lround(_Tp __x) 512 { return {std::lround(__x)}; } 513 514 template <typename _Tp> 515 _GLIBCXX_SIMD_INTRINSIC static _ST<long long> 516 _S_llround(_Tp __x) 517 { return {std::llround(__x)}; } 518 519 template <typename _Tp> 520 _GLIBCXX_SIMD_INTRINSIC static _Tp 521 _S_ldexp(_Tp __x, _ST<int> __y) 522 { return std::ldexp(__x, __y.first); } 523 524 template <typename _Tp> 525 _GLIBCXX_SIMD_INTRINSIC static _Tp 526 _S_scalbn(_Tp __x, _ST<int> __y) 527 { return std::scalbn(__x, __y.first); } 528 529 template <typename _Tp> 530 _GLIBCXX_SIMD_INTRINSIC static _Tp 531 _S_scalbln(_Tp __x, _ST<long> __y) 532 { return std::scalbln(__x, __y.first); } 533 534 template <typename _Tp> 535 _GLIBCXX_SIMD_INTRINSIC static _Tp 536 _S_fmod(_Tp __x, _Tp __y) 537 { return std::fmod(__x, __y); } 538 539 template <typename _Tp> 540 _GLIBCXX_SIMD_INTRINSIC static _Tp 541 _S_remainder(_Tp __x, _Tp __y) 542 { return std::remainder(__x, __y); } 543 544 template <typename _Tp> 545 _GLIBCXX_SIMD_INTRINSIC static _Tp 546 _S_nextafter(_Tp __x, _Tp __y) 547 { return std::nextafter(__x, __y); } 548 549 template <typename _Tp> 550 _GLIBCXX_SIMD_INTRINSIC static _Tp 551 _S_fdim(_Tp __x, _Tp __y) 552 { return std::fdim(__x, __y); } 553 554 template <typename _Tp> 555 _GLIBCXX_SIMD_INTRINSIC static _Tp 556 _S_fmax(_Tp __x, _Tp __y) 557 { return std::fmax(__x, __y); } 558 559 template <typename _Tp> 560 _GLIBCXX_SIMD_INTRINSIC static _Tp 561 _S_fmin(_Tp __x, _Tp __y) 562 { return std::fmin(__x, __y); } 563 564 template <typename _Tp> 565 _GLIBCXX_SIMD_INTRINSIC static _Tp 566 _S_fma(_Tp __x, _Tp __y, _Tp __z) 567 { return std::fma(__x, __y, __z); } 568 569 template <typename _Tp> 570 _GLIBCXX_SIMD_INTRINSIC static _Tp 571 _S_remquo(_Tp __x, _Tp __y, _ST<int>* __z) 572 { return std::remquo(__x, __y, &__z->first); } 573 574 template <typename _Tp> 575 _GLIBCXX_SIMD_INTRINSIC static constexpr _ST<int> 576 _S_fpclassify(_Tp __x) 577 { return {std::fpclassify(__x)}; } 578 579 template <typename _Tp> 580 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 581 _S_isfinite(_Tp __x) 582 { return std::isfinite(__x); } 583 584 template <typename _Tp> 585 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 586 _S_isinf(_Tp __x) 587 { return std::isinf(__x); } 588 589 template <typename _Tp> 590 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 591 _S_isnan(_Tp __x) 592 { return std::isnan(__x); } 593 594 template <typename _Tp> 595 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 596 _S_isnormal(_Tp __x) 597 { return std::isnormal(__x); } 598 599 template <typename _Tp> 600 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 601 _S_signbit(_Tp __x) 602 { return std::signbit(__x); } 603 604 template <typename _Tp> 605 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 606 _S_isgreater(_Tp __x, _Tp __y) 607 { return std::isgreater(__x, __y); } 608 609 template <typename _Tp> 610 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 611 _S_isgreaterequal(_Tp __x, _Tp __y) 612 { return std::isgreaterequal(__x, __y); } 613 614 template <typename _Tp> 615 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 616 _S_isless(_Tp __x, _Tp __y) 617 { return std::isless(__x, __y); } 618 619 template <typename _Tp> 620 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 621 _S_islessequal(_Tp __x, _Tp __y) 622 { return std::islessequal(__x, __y); } 623 624 template <typename _Tp> 625 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 626 _S_islessgreater(_Tp __x, _Tp __y) 627 { return std::islessgreater(__x, __y); } 628 629 template <typename _Tp> 630 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 631 _S_isunordered(_Tp __x, _Tp __y) 632 { return std::isunordered(__x, __y); } 633 634 // _S_increment & _S_decrement{{{2 635 template <typename _Tp> 636 _GLIBCXX_SIMD_INTRINSIC static constexpr void 637 _S_increment(_Tp& __x) 638 { ++__x; } 639 640 template <typename _Tp> 641 _GLIBCXX_SIMD_INTRINSIC static constexpr void 642 _S_decrement(_Tp& __x) 643 { --__x; } 644 645 646 // compares {{{2 647 template <typename _Tp> 648 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 649 _S_equal_to(_Tp __x, _Tp __y) 650 { return __x == __y; } 651 652 template <typename _Tp> 653 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 654 _S_not_equal_to(_Tp __x, _Tp __y) 655 { return __x != __y; } 656 657 template <typename _Tp> 658 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 659 _S_less(_Tp __x, _Tp __y) 660 { return __x < __y; } 661 662 template <typename _Tp> 663 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 664 _S_less_equal(_Tp __x, _Tp __y) 665 { return __x <= __y; } 666 667 // smart_reference access {{{2 668 template <typename _Tp, typename _Up> 669 _GLIBCXX_SIMD_INTRINSIC static constexpr void 670 _S_set(_Tp& __v, [[maybe_unused]] int __i, _Up&& __x) noexcept 671 { 672 _GLIBCXX_DEBUG_ASSERT(__i == 0); 673 __v = static_cast<_Up&&>(__x); 674 } 675 676 // _S_masked_assign {{{2 677 template <typename _Tp> 678 _GLIBCXX_SIMD_INTRINSIC static constexpr void 679 _S_masked_assign(bool __k, _Tp& __lhs, _Tp __rhs) 680 { if (__k) __lhs = __rhs; } 681 682 // _S_masked_cassign {{{2 683 template <typename _Op, typename _Tp> 684 _GLIBCXX_SIMD_INTRINSIC static constexpr void 685 _S_masked_cassign(const bool __k, _Tp& __lhs, const _Tp __rhs, _Op __op) 686 { if (__k) __lhs = __op(_SimdImplScalar{}, __lhs, __rhs); } 687 688 // _S_masked_unary {{{2 689 template <template <typename> class _Op, typename _Tp> 690 _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp 691 _S_masked_unary(const bool __k, const _Tp __v) 692 { return static_cast<_Tp>(__k ? _Op<_Tp>{}(__v) : __v); } 693 694 // }}}2 695 }; 696 697 // }}} 698 // _MaskImplScalar {{{ 699 struct _MaskImplScalar 700 { 701 // member types {{{ 702 template <typename _Tp> 703 using _TypeTag = _Tp*; 704 705 // }}} 706 // _S_broadcast {{{ 707 template <typename> 708 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 709 _S_broadcast(bool __x) 710 { return __x; } 711 712 // }}} 713 // _S_load {{{ 714 template <typename> 715 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 716 _S_load(const bool* __mem) 717 { return __mem[0]; } 718 719 // }}} 720 // _S_to_bits {{{ 721 _GLIBCXX_SIMD_INTRINSIC static constexpr _SanitizedBitMask<1> 722 _S_to_bits(bool __x) 723 { return __x; } 724 725 // }}} 726 // _S_convert {{{ 727 template <typename, bool _Sanitized> 728 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 729 _S_convert(_BitMask<1, _Sanitized> __x) 730 { return __x[0]; } 731 732 template <typename, typename _Up, typename _UAbi> 733 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 734 _S_convert(simd_mask<_Up, _UAbi> __x) 735 { return __x[0]; } 736 737 // }}} 738 // _S_from_bitmask {{{2 739 template <typename _Tp> 740 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 741 _S_from_bitmask(_SanitizedBitMask<1> __bits, _TypeTag<_Tp>) noexcept 742 { return __bits[0]; } 743 744 // _S_masked_load {{{2 745 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 746 _S_masked_load(bool __merge, bool __mask, const bool* __mem) noexcept 747 { 748 if (__mask) 749 __merge = __mem[0]; 750 return __merge; 751 } 752 753 // _S_store {{{2 754 _GLIBCXX_SIMD_INTRINSIC static constexpr void 755 _S_store(bool __v, bool* __mem) noexcept 756 { __mem[0] = __v; } 757 758 // _S_masked_store {{{2 759 _GLIBCXX_SIMD_INTRINSIC static constexpr void 760 _S_masked_store(const bool __v, bool* __mem, const bool __k) noexcept 761 { 762 if (__k) 763 __mem[0] = __v; 764 } 765 766 // logical and bitwise operators {{{2 767 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 768 _S_logical_and(bool __x, bool __y) 769 { return __x && __y; } 770 771 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 772 _S_logical_or(bool __x, bool __y) 773 { return __x || __y; } 774 775 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 776 _S_bit_not(bool __x) 777 { return !__x; } 778 779 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 780 _S_bit_and(bool __x, bool __y) 781 { return __x && __y; } 782 783 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 784 _S_bit_or(bool __x, bool __y) 785 { return __x || __y; } 786 787 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 788 _S_bit_xor(bool __x, bool __y) 789 { return __x != __y; } 790 791 // smart_reference access {{{2 792 _GLIBCXX_SIMD_INTRINSIC static constexpr void 793 _S_set(bool& __k, [[maybe_unused]] int __i, bool __x) noexcept 794 { 795 _GLIBCXX_DEBUG_ASSERT(__i == 0); 796 __k = __x; 797 } 798 799 // _S_masked_assign {{{2 800 _GLIBCXX_SIMD_INTRINSIC static constexpr void 801 _S_masked_assign(bool __k, bool& __lhs, bool __rhs) 802 { 803 if (__k) 804 __lhs = __rhs; 805 } 806 807 // }}}2 808 // _S_all_of {{{ 809 template <typename _Tp, typename _Abi> 810 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 811 _S_all_of(simd_mask<_Tp, _Abi> __k) 812 { return __k._M_data; } 813 814 // }}} 815 // _S_any_of {{{ 816 template <typename _Tp, typename _Abi> 817 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 818 _S_any_of(simd_mask<_Tp, _Abi> __k) 819 { return __k._M_data; } 820 821 // }}} 822 // _S_none_of {{{ 823 template <typename _Tp, typename _Abi> 824 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 825 _S_none_of(simd_mask<_Tp, _Abi> __k) 826 { return !__k._M_data; } 827 828 // }}} 829 // _S_some_of {{{ 830 template <typename _Tp, typename _Abi> 831 _GLIBCXX_SIMD_INTRINSIC static constexpr bool 832 _S_some_of(simd_mask<_Tp, _Abi>) 833 { return false; } 834 835 // }}} 836 // _S_popcount {{{ 837 template <typename _Tp, typename _Abi> 838 _GLIBCXX_SIMD_INTRINSIC static constexpr int 839 _S_popcount(simd_mask<_Tp, _Abi> __k) 840 { return __k._M_data; } 841 842 // }}} 843 // _S_find_first_set {{{ 844 template <typename _Tp, typename _Abi> 845 _GLIBCXX_SIMD_INTRINSIC static constexpr int 846 _S_find_first_set(simd_mask<_Tp, _Abi>) 847 { return 0; } 848 849 // }}} 850 // _S_find_last_set {{{ 851 template <typename _Tp, typename _Abi> 852 _GLIBCXX_SIMD_INTRINSIC static constexpr int 853 _S_find_last_set(simd_mask<_Tp, _Abi>) 854 { return 0; } 855 856 // }}} 857 }; 858 859 // }}} 860 861 _GLIBCXX_SIMD_END_NAMESPACE 862 #endif // __cplusplus >= 201703L 863 #endif // _GLIBCXX_EXPERIMENTAL_SIMD_SCALAR_H_ 864 865 // vim: foldmethod=marker sw=2 noet ts=8 sts=2 tw=80
Welcome to MyWebUniversity on May 18, 2025.
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2025 MyWebUniversity.com ™