@img/sharp-libvips-dev-wasm32 1.3.0-rc.6 → 1.3.0-rc.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -23
- package/include/aom/aom_codec.h +1 -1
- package/include/aom/aom_decoder.h +4 -0
- package/include/aom/aom_encoder.h +19 -8
- package/include/aom/aom_ext_ratectrl.h +664 -0
- package/include/aom/aom_image.h +93 -30
- package/include/aom/aom_tpl.h +99 -0
- package/include/aom/aomcx.h +89 -16
- package/include/aom/aomdx.h +12 -0
- package/include/expat.h +14 -2
- package/include/expat_config.h +6 -3
- package/include/expat_external.h +3 -2
- package/include/glib-2.0/gio/gdbusconnection.h +2 -8
- package/include/glib-2.0/gio/gio-visibility.h +34 -0
- package/include/glib-2.0/gio/gioenums.h +5 -4
- package/include/glib-2.0/glib/glib-visibility.h +34 -0
- package/include/glib-2.0/glib/gmacros.h +3 -3
- package/include/glib-2.0/glib/gmarkup.h +10 -0
- package/include/glib-2.0/glib/gmem.h +4 -4
- package/include/glib-2.0/glib/gmessages.h +6 -8
- package/include/glib-2.0/glib/gsequence.h +2 -2
- package/include/glib-2.0/glib/gstrfuncs.h +190 -0
- package/include/glib-2.0/glib/gutils.h +9 -0
- package/include/glib-2.0/glib/gvarianttype.h +16 -16
- package/include/glib-2.0/glib/gversionmacros.h +22 -0
- package/include/glib-2.0/gmodule/gmodule-visibility.h +34 -0
- package/include/glib-2.0/gobject/gobject-visibility.h +34 -0
- package/include/glib-2.0/gobject/gsignal.h +5 -5
- package/include/glib-2.0/gobject/gtype.h +14 -14
- package/include/hwy/aligned_allocator.h +44 -2
- package/include/hwy/auto_tune.h +22 -6
- package/include/hwy/base.h +60 -90
- package/include/hwy/bit_set.h +410 -0
- package/include/hwy/cache_control.h +3 -2
- package/include/hwy/detect_compiler_arch.h +134 -14
- package/include/hwy/detect_targets.h +82 -36
- package/include/hwy/highway.h +15 -0
- package/include/hwy/nanobenchmark.h +12 -3
- package/include/hwy/ops/arm_neon-inl.h +96 -25
- package/include/hwy/ops/arm_sve-inl.h +250 -95
- package/include/hwy/ops/emu128-inl.h +12 -7
- package/include/hwy/ops/generic_ops-inl.h +271 -131
- package/include/hwy/ops/loongarch_lasx-inl.h +31 -9
- package/include/hwy/ops/loongarch_lsx-inl.h +33 -12
- package/include/hwy/ops/ppc_vsx-inl.h +99 -19
- package/include/hwy/ops/rvv-inl.h +239 -130
- package/include/hwy/ops/scalar-inl.h +22 -7
- package/include/hwy/ops/set_macros-inl.h +163 -107
- package/include/hwy/ops/wasm_128-inl.h +13 -22
- package/include/hwy/ops/x86_128-inl.h +223 -120
- package/include/hwy/ops/x86_256-inl.h +70 -134
- package/include/hwy/ops/x86_512-inl.h +130 -134
- package/include/hwy/print-inl.h +2 -0
- package/include/hwy/profiler.h +355 -264
- package/include/hwy/robust_statistics.h +3 -1
- package/include/hwy/timer.h +44 -0
- package/include/lcms2.h +34 -4
- package/include/libexif/exif-utils.h +1 -1
- package/include/libheif/heif.h +2 -0
- package/include/libheif/heif_color.h +127 -11
- package/include/libheif/heif_components.h +264 -0
- package/include/libheif/heif_context.h +2 -1
- package/include/libheif/heif_cxx.h +10 -10
- package/include/libheif/heif_decoding.h +51 -7
- package/include/libheif/heif_encoding.h +15 -9
- package/include/libheif/heif_error.h +9 -2
- package/include/libheif/heif_export.h +48 -0
- package/include/libheif/heif_image.h +81 -66
- package/include/libheif/heif_image_handle.h +2 -2
- package/include/libheif/heif_items.h +1 -1
- package/include/libheif/heif_library.h +8 -16
- package/include/libheif/heif_omaf.h +104 -0
- package/include/libheif/heif_plugin.h +16 -9
- package/include/libheif/heif_properties.h +250 -12
- package/include/libheif/heif_security.h +16 -4
- package/include/libheif/heif_sequences.h +86 -4
- package/include/libheif/heif_tiling.h +2 -2
- package/include/libheif/heif_uncompressed.h +44 -324
- package/include/libheif/heif_version.h +2 -2
- package/include/libpng16/png.h +7 -7
- package/include/libpng16/pngconf.h +1 -1
- package/include/libpng16/pnglibconf.h +1 -1
- package/include/png.h +7 -7
- package/include/pngconf.h +1 -1
- package/include/pnglibconf.h +1 -1
- package/include/tiffconf.h +9 -10
- package/include/tiffio.h +10 -9
- package/include/tiffvers.h +1 -1
- package/include/ultrahdr_api.h +5 -11
- package/include/vips/version.h +4 -4
- package/lib/glib-2.0/include/glibconfig.h +1 -3
- package/lib/libaom.a +0 -0
- package/lib/libcgif.a +0 -0
- package/lib/libexif.a +0 -0
- package/lib/libexif.la +1 -1
- package/lib/libexpat.a +0 -0
- package/lib/libexpat.la +3 -3
- package/lib/libffi.a +0 -0
- package/lib/libgio-2.0.a +0 -0
- package/lib/libglib-2.0.a +0 -0
- package/lib/libgmodule-2.0.a +0 -0
- package/lib/libgobject-2.0.a +0 -0
- package/lib/libgthread-2.0.a +0 -0
- package/lib/libheif.a +0 -0
- package/lib/libhwy.a +0 -0
- package/lib/libimagequant.a +0 -0
- package/lib/libjpeg.a +0 -0
- package/lib/liblcms2.a +0 -0
- package/lib/libpng.a +0 -0
- package/lib/libpng.la +2 -2
- package/lib/libpng16.a +0 -0
- package/lib/libpng16.la +2 -2
- package/lib/libresvg.a +0 -0
- package/lib/libsharpyuv.a +0 -0
- package/lib/libtiff.a +0 -0
- package/lib/libuhdr.a +0 -0
- package/lib/libvips-cpp.a +0 -0
- package/lib/libvips.a +0 -0
- package/lib/libwebp.a +0 -0
- package/lib/libwebpdecoder.a +0 -0
- package/lib/libwebpdemux.a +0 -0
- package/lib/libwebpmux.a +0 -0
- package/lib/libz.a +0 -0
- package/lib/pkgconfig/aom.pc +2 -2
- package/lib/pkgconfig/expat.pc +1 -1
- package/lib/pkgconfig/gio-2.0.pc +1 -1
- package/lib/pkgconfig/glib-2.0.pc +1 -1
- package/lib/pkgconfig/gmodule-2.0.pc +1 -1
- package/lib/pkgconfig/gmodule-export-2.0.pc +1 -1
- package/lib/pkgconfig/gmodule-no-export-2.0.pc +1 -1
- package/lib/pkgconfig/gobject-2.0.pc +1 -1
- package/lib/pkgconfig/gthread-2.0.pc +1 -1
- package/lib/pkgconfig/lcms2.pc +1 -1
- package/lib/pkgconfig/libexif.pc +1 -1
- package/lib/pkgconfig/libheif.pc +2 -2
- package/lib/pkgconfig/libhwy.pc +3 -4
- package/lib/pkgconfig/libpng.pc +1 -1
- package/lib/pkgconfig/libpng16.pc +1 -1
- package/lib/pkgconfig/libsharpyuv.pc +1 -1
- package/lib/pkgconfig/libtiff-4.pc +2 -2
- package/lib/pkgconfig/libwebp.pc +1 -1
- package/lib/pkgconfig/libwebpdecoder.pc +11 -0
- package/lib/pkgconfig/libwebpmux.pc +1 -1
- package/lib/pkgconfig/vips-cpp.pc +1 -1
- package/lib/pkgconfig/vips.pc +1 -1
- package/package.json +1 -1
- package/versions.json +12 -12
- package/include/libheif/heif_uncompressed_types.h +0 -143
- package/lib/libsharpyuv.la +0 -41
- package/lib/libtiff.la +0 -41
- package/lib/libwebp.la +0 -41
- package/lib/libwebpdemux.la +0 -41
- package/lib/libwebpmux.la +0 -41
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
// the generic implementation here if native ops are already defined.
|
|
23
23
|
|
|
24
24
|
#include "hwy/base.h"
|
|
25
|
+
#include "hwy/detect_compiler_arch.h"
|
|
25
26
|
|
|
26
27
|
// Define detail::Shuffle1230 etc, but only when viewing the current header;
|
|
27
28
|
// normally this is included via highway.h, which includes ops/*.h.
|
|
@@ -245,6 +246,22 @@ HWY_API Mask<D> MaskFalse(D d) {
|
|
|
245
246
|
|
|
246
247
|
#endif // HWY_NATIVE_MASK_FALSE
|
|
247
248
|
|
|
249
|
+
// ------------------------------ SetMask
|
|
250
|
+
#if (defined(HWY_NATIVE_SET_MASK) == defined(HWY_TARGET_TOGGLE))
|
|
251
|
+
#ifdef HWY_NATIVE_SET_MASK
|
|
252
|
+
#undef HWY_NATIVE_SET_MASK
|
|
253
|
+
#else
|
|
254
|
+
#define HWY_NATIVE_SET_MASK
|
|
255
|
+
#endif
|
|
256
|
+
|
|
257
|
+
template <class D>
|
|
258
|
+
HWY_API Mask<D> SetMask(D d, bool val) {
|
|
259
|
+
const Repartition<int32_t, decltype(d)> di32;
|
|
260
|
+
return MaskFromVec(ResizeBitCast(d, Set(di32, -static_cast<int32_t>(val))));
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
#endif // HWY_NATIVE_SET_MASK
|
|
264
|
+
|
|
248
265
|
// ------------------------------ IfNegativeThenElseZero
|
|
249
266
|
#if (defined(HWY_NATIVE_IF_NEG_THEN_ELSE_ZERO) == defined(HWY_TARGET_TOGGLE))
|
|
250
267
|
#ifdef HWY_NATIVE_IF_NEG_THEN_ELSE_ZERO
|
|
@@ -466,11 +483,11 @@ HWY_API V RotateLeft(V v) {
|
|
|
466
483
|
}
|
|
467
484
|
|
|
468
485
|
// ------------------------------ InterleaveWholeLower/InterleaveWholeUpper
|
|
469
|
-
#if (defined(
|
|
470
|
-
#ifdef
|
|
471
|
-
#undef
|
|
486
|
+
#if (defined(HWY_TOGGLE_INTERLEAVE_WHOLE) == defined(HWY_TARGET_TOGGLE))
|
|
487
|
+
#ifdef HWY_TOGGLE_INTERLEAVE_WHOLE
|
|
488
|
+
#undef HWY_TOGGLE_INTERLEAVE_WHOLE
|
|
472
489
|
#else
|
|
473
|
-
#define
|
|
490
|
+
#define HWY_TOGGLE_INTERLEAVE_WHOLE
|
|
474
491
|
#endif
|
|
475
492
|
|
|
476
493
|
#if HWY_TARGET != HWY_SCALAR || HWY_IDE
|
|
@@ -497,7 +514,7 @@ HWY_API VFromD<D> InterleaveWholeUpper(D d, VFromD<D> a, VFromD<D> b) {
|
|
|
497
514
|
// is implemented in wasm_256-inl.h.
|
|
498
515
|
#endif // HWY_TARGET != HWY_SCALAR
|
|
499
516
|
|
|
500
|
-
#endif //
|
|
517
|
+
#endif // HWY_TOGGLE_INTERLEAVE_WHOLE
|
|
501
518
|
|
|
502
519
|
#if HWY_TARGET != HWY_SCALAR || HWY_IDE
|
|
503
520
|
// The InterleaveWholeLower without the optional D parameter is generic for all
|
|
@@ -834,6 +851,38 @@ HWY_API MFromD<D> MaskedIsNaN(const M m, const V v) {
|
|
|
834
851
|
}
|
|
835
852
|
#endif // HWY_NATIVE_MASKED_COMP
|
|
836
853
|
|
|
854
|
+
// ------------------------------ Xor3
|
|
855
|
+
|
|
856
|
+
#if (defined(HWY_NATIVE_XOR3) == defined(HWY_TARGET_TOGGLE))
|
|
857
|
+
#ifdef HWY_NATIVE_XOR3
|
|
858
|
+
#undef HWY_NATIVE_XOR3
|
|
859
|
+
#else
|
|
860
|
+
#define HWY_NATIVE_XOR3
|
|
861
|
+
#endif
|
|
862
|
+
|
|
863
|
+
template <class V>
|
|
864
|
+
HWY_API V Xor3(V x1, V x2, V x3) {
|
|
865
|
+
return Xor(x1, Xor(x2, x3));
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
#endif // HWY_NATIVE_XOR3
|
|
869
|
+
|
|
870
|
+
// ------------------------------ XorAndNot
|
|
871
|
+
|
|
872
|
+
#if (defined(HWY_NATIVE_BCAX) == defined(HWY_TARGET_TOGGLE))
|
|
873
|
+
#ifdef HWY_NATIVE_BCAX
|
|
874
|
+
#undef HWY_NATIVE_BCAX
|
|
875
|
+
#else
|
|
876
|
+
#define HWY_NATIVE_BCAX
|
|
877
|
+
#endif
|
|
878
|
+
|
|
879
|
+
template <class V>
|
|
880
|
+
HWY_API V XorAndNot(const V x, const V a1, const V a2) {
|
|
881
|
+
return Xor(x, AndNot(a1, a2));
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
#endif // HWY_NATIVE_BCAX
|
|
885
|
+
|
|
837
886
|
// ------------------------------ IfNegativeThenNegOrUndefIfZero
|
|
838
887
|
|
|
839
888
|
#if (defined(HWY_NATIVE_INTEGER_IF_NEGATIVE_THEN_NEG) == \
|
|
@@ -1279,12 +1328,10 @@ HWY_API VFromD<RebindToSigned<DFromV<V>>> FloorInt(V v) {
|
|
|
1279
1328
|
template <class V, HWY_IF_FLOAT_V(V)>
|
|
1280
1329
|
HWY_API V MulByPow2(V v, VFromD<RebindToSigned<DFromV<V>>> exp) {
|
|
1281
1330
|
const DFromV<decltype(v)> df;
|
|
1282
|
-
const RebindToUnsigned<decltype(df)> du;
|
|
1283
1331
|
const RebindToSigned<decltype(df)> di;
|
|
1284
1332
|
|
|
1285
1333
|
using TF = TFromD<decltype(df)>;
|
|
1286
1334
|
using TI = TFromD<decltype(di)>;
|
|
1287
|
-
using TU = TFromD<decltype(du)>;
|
|
1288
1335
|
|
|
1289
1336
|
using VF = VFromD<decltype(df)>;
|
|
1290
1337
|
using VI = VFromD<decltype(di)>;
|
|
@@ -1306,85 +1353,43 @@ HWY_API V MulByPow2(V v, VFromD<RebindToSigned<DFromV<V>>> exp) {
|
|
|
1306
1353
|
using TExpMinMax = TI;
|
|
1307
1354
|
#endif
|
|
1308
1355
|
|
|
1309
|
-
#if HWY_TARGET == HWY_EMU128 || HWY_TARGET == HWY_SCALAR
|
|
1310
|
-
using TExpSatSub = TU;
|
|
1311
|
-
#elif HWY_TARGET <= HWY_SSE2 || HWY_TARGET == HWY_WASM || \
|
|
1312
|
-
HWY_TARGET == HWY_WASM_EMU256
|
|
1313
|
-
using TExpSatSub = If<(sizeof(TF) == 4), uint8_t, uint16_t>;
|
|
1314
|
-
#elif HWY_TARGET_IS_PPC
|
|
1315
|
-
using TExpSatSub = If<(sizeof(TF) >= 4), uint32_t, TU>;
|
|
1316
|
-
#else
|
|
1317
|
-
using TExpSatSub = If<(sizeof(TF) == 4), uint8_t, TU>;
|
|
1318
|
-
#endif
|
|
1319
|
-
|
|
1320
1356
|
static_assert(kExpBias <= static_cast<TI>(LimitsMax<TExpMinMax>() / 3),
|
|
1321
1357
|
"kExpBias <= LimitsMax<TExpMinMax>() / 3 must be true");
|
|
1322
1358
|
|
|
1323
1359
|
const Repartition<TExpMinMax, decltype(df)> d_exp_min_max;
|
|
1324
|
-
const Repartition<TExpSatSub, decltype(df)> d_sat_exp_sub;
|
|
1325
1360
|
|
|
1326
|
-
constexpr int kNumOfExpBits = ExponentBits<TF>();
|
|
1327
1361
|
constexpr int kNumOfMantBits = MantissaBits<TF>();
|
|
1328
1362
|
|
|
1329
|
-
|
|
1330
|
-
// using SaturatedSub if kZeroOutSignUsingSatSub is true.
|
|
1331
|
-
|
|
1332
|
-
// If kZeroOutSignUsingSatSub is true, then val_for_exp_sub will be bitcasted
|
|
1333
|
-
// to a vector that has a smaller lane size than TU for the SaturatedSub
|
|
1334
|
-
// operation below.
|
|
1335
|
-
constexpr bool kZeroOutSignUsingSatSub =
|
|
1336
|
-
((sizeof(TExpSatSub) * 8) == static_cast<size_t>(kNumOfExpBits));
|
|
1337
|
-
|
|
1338
|
-
// If kZeroOutSignUsingSatSub is true, then the upper
|
|
1339
|
-
// (sizeof(TU) - sizeof(TExpSatSub)) * 8 bits of kExpDecrBy1Bits will be all
|
|
1340
|
-
// ones and the lower sizeof(TExpSatSub) * 8 bits of kExpDecrBy1Bits will be
|
|
1341
|
-
// equal to 1.
|
|
1342
|
-
|
|
1343
|
-
// Otherwise, if kZeroOutSignUsingSatSub is false, kExpDecrBy1Bits will be
|
|
1344
|
-
// equal to 1.
|
|
1345
|
-
constexpr TU kExpDecrBy1Bits = static_cast<TU>(
|
|
1346
|
-
TU{1} - (static_cast<TU>(kZeroOutSignUsingSatSub) << kNumOfExpBits));
|
|
1347
|
-
|
|
1348
|
-
VF val_for_exp_sub = v;
|
|
1349
|
-
HWY_IF_CONSTEXPR(!kZeroOutSignUsingSatSub) {
|
|
1350
|
-
// If kZeroOutSignUsingSatSub is not true, zero out the sign bit of
|
|
1351
|
-
// val_for_exp_sub[i] using Abs
|
|
1352
|
-
val_for_exp_sub = Abs(val_for_exp_sub);
|
|
1353
|
-
}
|
|
1354
|
-
|
|
1355
|
-
// min_exp1_plus_min_exp2[i] is the smallest exponent such that
|
|
1356
|
-
// min_exp1_plus_min_exp2[i] >= 2 - kExpBias * 2 and
|
|
1357
|
-
// std::ldexp(v[i], min_exp1_plus_min_exp2[i]) is a normal floating-point
|
|
1358
|
-
// number if v[i] is a normal number
|
|
1359
|
-
const VI min_exp1_plus_min_exp2 = BitCast(
|
|
1360
|
-
di,
|
|
1361
|
-
Max(BitCast(
|
|
1362
|
-
d_exp_min_max,
|
|
1363
|
-
Neg(BitCast(
|
|
1364
|
-
di,
|
|
1365
|
-
SaturatedSub(
|
|
1366
|
-
BitCast(d_sat_exp_sub, ShiftRight<kNumOfMantBits>(
|
|
1367
|
-
BitCast(du, val_for_exp_sub))),
|
|
1368
|
-
BitCast(d_sat_exp_sub, Set(du, kExpDecrBy1Bits)))))),
|
|
1369
|
-
BitCast(d_exp_min_max,
|
|
1370
|
-
Set(di, static_cast<TI>(2 - kExpBias - kExpBias)))));
|
|
1363
|
+
const VI exp_bias = Set(di, kExpBias);
|
|
1371
1364
|
|
|
1372
1365
|
const VI clamped_exp =
|
|
1373
|
-
|
|
1374
|
-
Add(min_exp1_plus_min_exp2, Set(di, static_cast<TI>(1 - kExpBias))));
|
|
1366
|
+
Clamp(exp, Set(di, 3 - 3 * kExpBias), Set(di, 3 * kExpBias));
|
|
1375
1367
|
|
|
1376
|
-
const
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
BitCast(d_exp_min_max,
|
|
1380
|
-
Set(di, static_cast<TI>(kExpBias + kExpBias)))),
|
|
1381
|
-
BitCast(d_exp_min_max, min_exp1_plus_min_exp2)));
|
|
1368
|
+
const auto min_scale_factor_exp =
|
|
1369
|
+
BitCast(d_exp_min_max, Set(di, 1 - kExpBias));
|
|
1370
|
+
const auto max_scale_factor_exp = BitCast(d_exp_min_max, exp_bias);
|
|
1382
1371
|
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1372
|
+
// If clamped_exp[i] < 0, ensure that 1 - kExpBias <= exp1[i] <= 0,
|
|
1373
|
+
// 1 - kExpBias <= exp2[i] <= 0, and 1 - kExpBias <= exp3[i] <= 0 are
|
|
1374
|
+
// true.
|
|
1386
1375
|
|
|
1387
|
-
|
|
1376
|
+
// In addition, if clamped_exp[i] < 1 - kExpBias, ensure that
|
|
1377
|
+
// exp3[i] == 1 - kExpBias to ensure results are correctly rounded if the
|
|
1378
|
+
// exact value of |x[i] * factor1[i] * factor2[i] * factor3[i]| is less than
|
|
1379
|
+
// the smallest positive normal value.
|
|
1380
|
+
|
|
1381
|
+
// Otherwise, if clamped_exp[i] >= 0, ensure that 0 <= exp1[i] <= kExpBias,
|
|
1382
|
+
// 0 <= exp2[i] <= kExpBias, and 0 <= exp3[i] <= kExpBias are all true.
|
|
1383
|
+
|
|
1384
|
+
const VI exp3 =
|
|
1385
|
+
BitCast(di, Clamp(BitCast(d_exp_min_max, clamped_exp),
|
|
1386
|
+
min_scale_factor_exp, max_scale_factor_exp));
|
|
1387
|
+
|
|
1388
|
+
const VI clamped_exp_minus_exp3 = Sub(clamped_exp, exp3);
|
|
1389
|
+
const VI exp2 =
|
|
1390
|
+
BitCast(di, Clamp(BitCast(d_exp_min_max, clamped_exp_minus_exp3),
|
|
1391
|
+
min_scale_factor_exp, max_scale_factor_exp));
|
|
1392
|
+
const VI exp1 = Sub(clamped_exp_minus_exp3, exp2);
|
|
1388
1393
|
|
|
1389
1394
|
const VF factor1 =
|
|
1390
1395
|
BitCast(df, ShiftLeft<kNumOfMantBits>(Add(exp1, exp_bias)));
|
|
@@ -1393,6 +1398,37 @@ HWY_API V MulByPow2(V v, VFromD<RebindToSigned<DFromV<V>>> exp) {
|
|
|
1393
1398
|
const VF factor3 =
|
|
1394
1399
|
BitCast(df, ShiftLeft<kNumOfMantBits>(Add(exp3, exp_bias)));
|
|
1395
1400
|
|
|
1401
|
+
// If exp2[i] < 0, then clamped_exp[i] < 1 - kExpBias and
|
|
1402
|
+
// exp3[i] == 1 - kExpBias will both be true. factor3[i] will be equal to the
|
|
1403
|
+
// smallest positive normal value if exp3[i] == 1 - kExpBias.
|
|
1404
|
+
|
|
1405
|
+
// If exp2[i] >= 0, then exp1[i] >= 0 and factor1[i] * factor2[i] >= 1.
|
|
1406
|
+
|
|
1407
|
+
// If exp2[i] < 0 and the exact value of |v[i] * factor1[i] * factor2[i]| is
|
|
1408
|
+
// less than the smallest positive normal value, then the exact value of
|
|
1409
|
+
// |v[i] * factor1[i] * factor2[i] * factor3[i]| will be much smaller than
|
|
1410
|
+
// half of the smallest positive denormal value (since factor3[i] will be
|
|
1411
|
+
// equal to the smallest positive normal value in this case), resulting in a
|
|
1412
|
+
// correctly rounded result in this case.
|
|
1413
|
+
|
|
1414
|
+
// If kExpBias >= kNumOfMantBits + 3 and exp3[i] == 1 - kExpBias are both
|
|
1415
|
+
// true, then factor3[i] will be small enough such that
|
|
1416
|
+
// v[i] * factor1[i] * factor2[i] * factor3[i] will be correctly rounded,
|
|
1417
|
+
// even if the exact value of |v[i] * factor1[i] * factor2[i]| is smaller than
|
|
1418
|
+
// the smallest positive normal value.
|
|
1419
|
+
|
|
1420
|
+
// kExpBias >= kNumOfMantBits + 3 is true for the F16, F32, and F64
|
|
1421
|
+
// floating-point types.
|
|
1422
|
+
|
|
1423
|
+
// Otherwise, either exp2[i] >= 0, the exact value of
|
|
1424
|
+
// |v[i] * factor1[i] * factor2[i]| is greater than or equal to the smallest
|
|
1425
|
+
// positive normal value, or v[i] is NaN. In these cases,
|
|
1426
|
+
// v[i] * factor1[i] * factor2[i] will either be exact or overflow to
|
|
1427
|
+
// infinity (if clamped_exp[i] > 0 and v[i] is a non-zero finite value),
|
|
1428
|
+
// resulting in a correctly rounded result if the exact value of
|
|
1429
|
+
// |v[i] * factor1[i] * factor2[i] * factor3[i]| is less than the smallest
|
|
1430
|
+
// positive normal value.
|
|
1431
|
+
|
|
1396
1432
|
return Mul(Mul(Mul(v, factor1), factor2), factor3);
|
|
1397
1433
|
}
|
|
1398
1434
|
|
|
@@ -3156,8 +3192,8 @@ HWY_API VFromD<D> GatherIndexN(D d, const T* HWY_RESTRICT base,
|
|
|
3156
3192
|
|
|
3157
3193
|
template <class D, typename T = TFromD<D>>
|
|
3158
3194
|
HWY_API VFromD<D> GatherIndexNOr(VFromD<D> no, D d, const T* HWY_RESTRICT base,
|
|
3159
|
-
|
|
3160
|
-
|
|
3195
|
+
VFromD<RebindToSigned<D>> index,
|
|
3196
|
+
const size_t max_lanes_to_load) {
|
|
3161
3197
|
const RebindToSigned<D> di;
|
|
3162
3198
|
using TI = TFromD<decltype(di)>;
|
|
3163
3199
|
static_assert(sizeof(T) == sizeof(TI), "Index/lane size must match");
|
|
@@ -3178,8 +3214,8 @@ HWY_API VFromD<D> GatherIndexN(D d, const T* HWY_RESTRICT base,
|
|
|
3178
3214
|
}
|
|
3179
3215
|
template <class D, typename T = TFromD<D>>
|
|
3180
3216
|
HWY_API VFromD<D> GatherIndexNOr(VFromD<D> no, D d, const T* HWY_RESTRICT base,
|
|
3181
|
-
|
|
3182
|
-
|
|
3217
|
+
VFromD<RebindToSigned<D>> index,
|
|
3218
|
+
const size_t max_lanes_to_load) {
|
|
3183
3219
|
return MaskedGatherIndexOr(no, FirstN(d, max_lanes_to_load), d, base, index);
|
|
3184
3220
|
}
|
|
3185
3221
|
#endif // (defined(HWY_NATIVE_GATHER) == defined(HWY_TARGET_TOGGLE))
|
|
@@ -4525,43 +4561,46 @@ HWY_API V CLMulUpper(V a, V b) {
|
|
|
4525
4561
|
#define HWY_NATIVE_POPCNT
|
|
4526
4562
|
#endif
|
|
4527
4563
|
|
|
4528
|
-
|
|
4529
|
-
// for LMUL >= 2.
|
|
4530
|
-
#undef HWY_IF_POPCNT
|
|
4531
|
-
#if HWY_TARGET == HWY_RVV
|
|
4532
|
-
#define HWY_IF_POPCNT(D) \
|
|
4533
|
-
hwy::EnableIf<D().Pow2() >= 1 && D().MaxLanes() >= 16>* = nullptr
|
|
4534
|
-
#else
|
|
4535
|
-
// Other targets only have these two overloads which are mutually exclusive, so
|
|
4536
|
-
// no further conditions are required.
|
|
4537
|
-
#define HWY_IF_POPCNT(D) void* = nullptr
|
|
4538
|
-
#endif // HWY_TARGET == HWY_RVV
|
|
4539
|
-
|
|
4540
|
-
template <class V, class D = DFromV<V>, HWY_IF_U8_D(D),
|
|
4541
|
-
HWY_IF_V_SIZE_GT_D(D, 8), HWY_IF_POPCNT(D)>
|
|
4564
|
+
template <class V, class D = DFromV<V>, HWY_IF_U8_D(D)>
|
|
4542
4565
|
HWY_API V PopulationCount(V v) {
|
|
4543
4566
|
const D d;
|
|
4544
|
-
const V lookup =
|
|
4545
|
-
Dup128VecFromValues(d, 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4);
|
|
4546
|
-
const auto lo = And(v, Set(d, uint8_t{0xF}));
|
|
4547
|
-
const auto hi = ShiftRight<4>(v);
|
|
4548
|
-
return Add(TableLookupBytes(lookup, hi), TableLookupBytes(lookup, lo));
|
|
4549
|
-
}
|
|
4550
4567
|
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
template <class V, class D = DFromV<V>, HWY_IF_U8_D(D),
|
|
4555
|
-
HWY_IF_V_SIZE_LE_D(D, 8)>
|
|
4556
|
-
HWY_API V PopulationCount(V v) {
|
|
4557
|
-
const D d;
|
|
4568
|
+
#if HWY_TARGET == HWY_SSE2
|
|
4569
|
+
// TableLookupBytes is slow on SSE2
|
|
4570
|
+
|
|
4558
4571
|
// See https://arxiv.org/pdf/1611.07612.pdf, Figure 3
|
|
4559
4572
|
const V k33 = Set(d, uint8_t{0x33});
|
|
4560
4573
|
v = Sub(v, And(ShiftRight<1>(v), Set(d, uint8_t{0x55})));
|
|
4561
4574
|
v = Add(And(ShiftRight<2>(v), k33), And(v, k33));
|
|
4562
4575
|
return And(Add(v, ShiftRight<4>(v)), Set(d, uint8_t{0x0F}));
|
|
4576
|
+
#else // HWY_TARGET != HWY_SSE2
|
|
4577
|
+
|
|
4578
|
+
#if HWY_TARGET == HWY_RVV
|
|
4579
|
+
// Need at least LMUL=1 on RVV to ensure that Lanes(d_tbl) is at least 16
|
|
4580
|
+
const ScalableTag<uint8_t, HWY_MAX(HWY_POW2_D(D), 0)> d_tbl;
|
|
4581
|
+
#else
|
|
4582
|
+
const FixedTag<uint8_t, HWY_MAX(HWY_MAX_LANES_D(D), 16)> d_tbl;
|
|
4583
|
+
#endif
|
|
4584
|
+
|
|
4585
|
+
const auto lookup = Dup128VecFromValues(d_tbl, 0, 1, 1, 2, 1, 2, 2, 3, 1, 2,
|
|
4586
|
+
2, 3, 2, 3, 3, 4);
|
|
4587
|
+
const auto lo = And(v, Set(d, uint8_t{0xF}));
|
|
4588
|
+
const auto hi = ShiftRight<4>(v);
|
|
4589
|
+
|
|
4590
|
+
#if HWY_TARGET == HWY_RVV
|
|
4591
|
+
// On RVV, use TableLookupLanes to avoid unnecessary overhead
|
|
4592
|
+
const auto hi_popcnt =
|
|
4593
|
+
ResizeBitCast(d, TableLookupLanes(lookup, ResizeBitCast(d_tbl, hi)));
|
|
4594
|
+
const auto lo_popcnt =
|
|
4595
|
+
ResizeBitCast(d, TableLookupLanes(lookup, ResizeBitCast(d_tbl, lo)));
|
|
4596
|
+
#else // HWY_TARGET != HWY_RVV
|
|
4597
|
+
const auto hi_popcnt = TableLookupBytes(lookup, hi);
|
|
4598
|
+
const auto lo_popcnt = TableLookupBytes(lookup, lo);
|
|
4599
|
+
#endif // HWY_TARGET == HWY_RVV
|
|
4600
|
+
|
|
4601
|
+
return Add(hi_popcnt, lo_popcnt);
|
|
4602
|
+
#endif // HWY_TARGET == HWY_SSE2
|
|
4563
4603
|
}
|
|
4564
|
-
#endif // HWY_TARGET != HWY_RVV
|
|
4565
4604
|
|
|
4566
4605
|
template <class V, class D = DFromV<V>, HWY_IF_U16_D(D)>
|
|
4567
4606
|
HWY_API V PopulationCount(V v) {
|
|
@@ -5323,14 +5362,13 @@ HWY_INLINE V IntDiv(V a, V b) {
|
|
|
5323
5362
|
#endif // HWY_HAVE_FLOAT64
|
|
5324
5363
|
|
|
5325
5364
|
template <size_t kOrigLaneSize, class V, HWY_IF_NOT_FLOAT_NOR_SPECIAL_V(V),
|
|
5326
|
-
HWY_IF_T_SIZE_ONE_OF_V(
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
(1 << 2) | (1 << 4) | (1 << 8))>
|
|
5365
|
+
HWY_IF_T_SIZE_ONE_OF_V(
|
|
5366
|
+
V, ((HWY_TARGET <= HWY_SSE2 || HWY_TARGET == HWY_WASM ||
|
|
5367
|
+
HWY_TARGET == HWY_WASM_EMU256 || HWY_TARGET == HWY_LSX ||
|
|
5368
|
+
HWY_TARGET == HWY_LASX)
|
|
5369
|
+
? 0
|
|
5370
|
+
: (1 << 1)) |
|
|
5371
|
+
(1 << 2) | (1 << 4) | (1 << 8))>
|
|
5334
5372
|
HWY_INLINE V IntMod(V a, V b) {
|
|
5335
5373
|
return hwy::HWY_NAMESPACE::NegMulAdd(IntDiv<kOrigLaneSize>(a, b), b, a);
|
|
5336
5374
|
}
|
|
@@ -5474,17 +5512,15 @@ HWY_API V RoundingShiftRight(V v) {
|
|
|
5474
5512
|
template <class V, HWY_IF_NOT_FLOAT_NOR_SPECIAL_V(V)>
|
|
5475
5513
|
HWY_API V RoundingShiftRightSame(V v, int shift_amt) {
|
|
5476
5514
|
const DFromV<V> d;
|
|
5477
|
-
using T = TFromD<decltype(d)>;
|
|
5478
|
-
|
|
5479
|
-
const int shift_amt_is_zero_mask = -static_cast<int>(shift_amt == 0);
|
|
5480
5515
|
|
|
5516
|
+
const bool shift_amt_is_zero = (shift_amt == 0);
|
|
5481
5517
|
const auto scaled_down_v = ShiftRightSame(
|
|
5482
5518
|
v, static_cast<int>(static_cast<unsigned>(shift_amt) +
|
|
5483
|
-
static_cast<unsigned>(
|
|
5519
|
+
static_cast<unsigned>(shift_amt_is_zero) - 1u));
|
|
5484
5520
|
|
|
5485
5521
|
return AverageRound(
|
|
5486
5522
|
scaled_down_v,
|
|
5487
|
-
|
|
5523
|
+
IfThenElseZero(SetMask(d, shift_amt_is_zero), scaled_down_v));
|
|
5488
5524
|
}
|
|
5489
5525
|
|
|
5490
5526
|
template <class V, HWY_IF_NOT_FLOAT_NOR_SPECIAL_V(V)>
|
|
@@ -5531,7 +5567,7 @@ HWY_API VFromD<DF> MulOddAdd(DF df, VBF a, VBF b, VFromD<DF> c) {
|
|
|
5531
5567
|
|
|
5532
5568
|
// ------------------------------ ReorderWidenMulAccumulate (MulEvenAdd)
|
|
5533
5569
|
|
|
5534
|
-
// AVX3_SPR/ZEN4,
|
|
5570
|
+
// AVX3_SPR/ZEN4, NEON with bf16 and SVE override this.
|
|
5535
5571
|
#if (defined(HWY_NATIVE_REORDER_WIDEN_MUL_ACC_BF16) == \
|
|
5536
5572
|
defined(HWY_TARGET_TOGGLE))
|
|
5537
5573
|
#ifdef HWY_NATIVE_REORDER_WIDEN_MUL_ACC_BF16
|
|
@@ -5551,6 +5587,13 @@ HWY_API VFromD<DF> ReorderWidenMulAccumulate(DF df, VBF a, VBF b,
|
|
|
5551
5587
|
return MulEvenAdd(df, a, b, sum0);
|
|
5552
5588
|
}
|
|
5553
5589
|
|
|
5590
|
+
template <class VW, HWY_IF_FLOAT_V(VW)>
|
|
5591
|
+
HWY_API VW RearrangeToOddPlusEven(const VW sum0, const VW sum1) {
|
|
5592
|
+
// sum1 contains the odd lanes and sum0 the even, hence their sum is the
|
|
5593
|
+
// desired pairwise sum.
|
|
5594
|
+
return Add(sum0, sum1);
|
|
5595
|
+
}
|
|
5596
|
+
|
|
5554
5597
|
#endif // HWY_NATIVE_REORDER_WIDEN_MUL_ACC_BF16
|
|
5555
5598
|
|
|
5556
5599
|
// ------------------------------ WidenMulAccumulate
|
|
@@ -5562,8 +5605,7 @@ HWY_API VFromD<DF> ReorderWidenMulAccumulate(DF df, VBF a, VBF b,
|
|
|
5562
5605
|
#define HWY_NATIVE_WIDEN_MUL_ACCUMULATE
|
|
5563
5606
|
#endif
|
|
5564
5607
|
|
|
5565
|
-
template<class D, HWY_IF_INTEGER(TFromD<D>),
|
|
5566
|
-
class DN = RepartitionToNarrow<D>>
|
|
5608
|
+
template <class D, HWY_IF_INTEGER(TFromD<D>), class DN = RepartitionToNarrow<D>>
|
|
5567
5609
|
HWY_API VFromD<D> WidenMulAccumulate(D d, VFromD<DN> mul, VFromD<DN> x,
|
|
5568
5610
|
VFromD<D> low, VFromD<D>& high) {
|
|
5569
5611
|
high = MulAdd(PromoteUpperTo(d, mul), PromoteUpperTo(d, x), high);
|
|
@@ -5942,7 +5984,7 @@ HWY_API size_t CompressBitsStore(V v, const uint8_t* HWY_RESTRICT bits, D d,
|
|
|
5942
5984
|
Store(v, d, lanes);
|
|
5943
5985
|
|
|
5944
5986
|
const Simd<T, HWY_MIN(MaxLanes(d), 8), 0> d8;
|
|
5945
|
-
T*
|
|
5987
|
+
T* pos = unaligned;
|
|
5946
5988
|
|
|
5947
5989
|
HWY_ALIGN constexpr T table[2048] = {
|
|
5948
5990
|
0, 1, 2, 3, 4, 5, 6, 7, /**/ 0, 1, 2, 3, 4, 5, 6, 7, //
|
|
@@ -6074,15 +6116,40 @@ HWY_API size_t CompressBitsStore(V v, const uint8_t* HWY_RESTRICT bits, D d,
|
|
|
6074
6116
|
2, 3, 4, 5, 6, 7, 0, 1, /**/ 0, 2, 3, 4, 5, 6, 7, 1, //
|
|
6075
6117
|
1, 2, 3, 4, 5, 6, 7, 0, /**/ 0, 1, 2, 3, 4, 5, 6, 7};
|
|
6076
6118
|
|
|
6077
|
-
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
|
|
6119
|
+
size_t i = 0;
|
|
6120
|
+
HWY_LANES_CONSTEXPR size_t N = Lanes(d);
|
|
6121
|
+
constexpr bool kMaybeLt128 =
|
|
6122
|
+
(HWY_TARGET == HWY_SCALAR) || !detail::IsFull(D());
|
|
6123
|
+
// If less than 128 bit, we may not enter the main loop below, and even
|
|
6124
|
+
// the remainder loop might not write anything if bits are not set.
|
|
6125
|
+
// Ensure the output is initialized. GCC seems not to understand this is only
|
|
6126
|
+
// necessary if kMaybeLt128.
|
|
6127
|
+
HWY_IF_CONSTEXPR(kMaybeLt128 || HWY_COMPILER_GCC_ACTUAL) {
|
|
6128
|
+
StoreU(v, d, unaligned);
|
|
6129
|
+
}
|
|
6130
|
+
HWY_ASSUME(N >= 8 || kMaybeLt128);
|
|
6131
|
+
if (N >= 8) {
|
|
6132
|
+
for (; i <= N - 8; i += 8) {
|
|
6133
|
+
// Each byte worth of bits is the index of one of 256 8-byte ranges, and
|
|
6134
|
+
// its population count determines how far to advance the write position.
|
|
6135
|
+
const size_t bits8 = bits[i / 8];
|
|
6136
|
+
const auto indices = Load(d8, table + bits8 * 8);
|
|
6137
|
+
const auto compressed = TableLookupBytes(LoadU(d8, lanes + i), indices);
|
|
6138
|
+
StoreU(compressed, d8, pos);
|
|
6139
|
+
pos += PopCount(bits8);
|
|
6140
|
+
}
|
|
6085
6141
|
}
|
|
6142
|
+
// Not required if we have full vectors of >= 128 bits, because they are
|
|
6143
|
+
// multiples of 8 bytes. Inefficient loop is mainly required for safely
|
|
6144
|
+
// handling compress_test).
|
|
6145
|
+
HWY_IF_CONSTEXPR(kMaybeLt128) {
|
|
6146
|
+
for (; i < N; ++i) {
|
|
6147
|
+
if (bits[i / 8] & (1u << (i % 8))) {
|
|
6148
|
+
*pos++ = lanes[i];
|
|
6149
|
+
}
|
|
6150
|
+
}
|
|
6151
|
+
}
|
|
6152
|
+
|
|
6086
6153
|
return static_cast<size_t>(pos - unaligned);
|
|
6087
6154
|
}
|
|
6088
6155
|
|
|
@@ -6775,12 +6842,19 @@ HWY_API Vec128<T, 1> Expand(Vec128<T, 1> v, Mask128<T, 1> mask) {
|
|
|
6775
6842
|
}
|
|
6776
6843
|
|
|
6777
6844
|
// ------------------------------ LoadExpand
|
|
6845
|
+
|
|
6846
|
+
// #2957: clangd warning because x86_128-inl.h defines an overload with this
|
|
6847
|
+
// condition, so negate it here.
|
|
6848
|
+
#if !(HWY_TARGET <= HWY_AVX3 || HWY_IDE)
|
|
6849
|
+
|
|
6778
6850
|
template <class D, HWY_IF_V_SIZE_LE_D(D, 16)>
|
|
6779
6851
|
HWY_API VFromD<D> LoadExpand(MFromD<D> mask, D d,
|
|
6780
6852
|
const TFromD<D>* HWY_RESTRICT unaligned) {
|
|
6781
6853
|
return Expand(LoadU(d, unaligned), mask);
|
|
6782
6854
|
}
|
|
6783
6855
|
|
|
6856
|
+
#endif // !(HWY_TARGET <= HWY_AVX3 || HWY_IDE)
|
|
6857
|
+
|
|
6784
6858
|
#endif // HWY_NATIVE_EXPAND
|
|
6785
6859
|
|
|
6786
6860
|
// ------------------------------ TwoTablesLookupLanes
|
|
@@ -6798,6 +6872,72 @@ HWY_API VFromD<D> TwoTablesLookupLanes(D /*d*/, VFromD<D> a, VFromD<D> b,
|
|
|
6798
6872
|
}
|
|
6799
6873
|
#endif
|
|
6800
6874
|
|
|
6875
|
+
// ------------------------------ Lookup8
|
|
6876
|
+
|
|
6877
|
+
template <class D, typename T = TFromD<D>, class VI>
|
|
6878
|
+
HWY_INLINE Vec<D> Lookup8(D d, const T* HWY_RESTRICT table, VI indices) {
|
|
6879
|
+
// `di` describes the indices given - same bits per lane, but `d` determines
|
|
6880
|
+
// the actual lane count of the result and also of the table vectors, which
|
|
6881
|
+
// is relevant for adjusting the index values, see below.
|
|
6882
|
+
DFromV<VI> di;
|
|
6883
|
+
static_assert(sizeof(T) == sizeof(TFromD<decltype(di)>),
|
|
6884
|
+
"Index/vector must have same lane size");
|
|
6885
|
+
HWY_IF_CONSTEXPR(HWY_IS_DEBUG_BUILD) {
|
|
6886
|
+
// Asserting Lanes(di) >= 4 not needed since both d and di have the same
|
|
6887
|
+
// number of Lanes()
|
|
6888
|
+
HWY_DASSERT(Lanes(d) >= 4);
|
|
6889
|
+
HWY_DASSERT(AllTrue(di, Lt(indices, Set(di, 8))));
|
|
6890
|
+
}
|
|
6891
|
+
|
|
6892
|
+
HWY_IF_CONSTEXPR(!HWY_HAVE_SCALABLE) {
|
|
6893
|
+
// Fixed-size vectors: we know they are >= 128 bit, so either one or two
|
|
6894
|
+
// tables are sufficient.
|
|
6895
|
+
HWY_IF_CONSTEXPR(MaxLanes(d) >= 8) {
|
|
6896
|
+
const CappedTag<T, 8> d8;
|
|
6897
|
+
// We want to perform one lookup per index, hence cast. This has no
|
|
6898
|
+
// runtime cost; the upper lanes are unused.
|
|
6899
|
+
const Vec<D> t0 = ResizeBitCast(d, Load(d8, table));
|
|
6900
|
+
return TableLookupLanes(t0, IndicesFromVec(d, indices));
|
|
6901
|
+
}
|
|
6902
|
+
HWY_IF_CONSTEXPR(MaxLanes(d) < 8) {
|
|
6903
|
+
// Exactly 4 lanes, because we ensured >= 4 above.
|
|
6904
|
+
const Vec<D> t0 = Load(d, table);
|
|
6905
|
+
const Vec<D> t1 = Load(d, table + 4);
|
|
6906
|
+
return TwoTablesLookupLanes(d, t0, t1, IndicesFromVec(d, indices));
|
|
6907
|
+
}
|
|
6908
|
+
}
|
|
6909
|
+
|
|
6910
|
+
HWY_IF_CONSTEXPR(HWY_HAVE_SCALABLE) {
|
|
6911
|
+
// Scalable: first we must load two halves of the table into two vectors,
|
|
6912
|
+
// regardless of vector size. We always use two-vector lookups to avoid
|
|
6913
|
+
// runtime branching. Note that RVV can have U64x8 even with 128-bit
|
|
6914
|
+
// vectors (LMUL=4), hence we must use the given LMUL, not FixedTag, but we
|
|
6915
|
+
// still want to cap at 4 lanes to avoid overrunning the table.
|
|
6916
|
+
const CappedTag<T, 4, d.Pow2()> d4;
|
|
6917
|
+
|
|
6918
|
+
// We want to use native lookup instructions (more efficient on SVE than two
|
|
6919
|
+
// lookups plus a blend), hence cast. This has no runtime cost. No LoadU
|
|
6920
|
+
// required because + 4 is still aligned relative to `d4`.
|
|
6921
|
+
const Vec<D> t0 = ResizeBitCast(d, Load(d4, table));
|
|
6922
|
+
const Vec<D> t1 = ResizeBitCast(d, Load(d4, table + 4));
|
|
6923
|
+
|
|
6924
|
+
// Now ensure indices for the second half of the table point to the second
|
|
6925
|
+
// vector. Note that SVE2_128 and SVE_256 are handled by the fixed-size case
|
|
6926
|
+
// above. The adjustment factor is 0 for 128-bit SIMD, which can happen with
|
|
6927
|
+
// 128-bit SVE1 hardware, but we do not know that at compile time.
|
|
6928
|
+
using TI = TFromD<decltype(di)>;
|
|
6929
|
+
const VI adjust = Set(di, static_cast<TI>(Lanes(d) - 4));
|
|
6930
|
+
#if HWY_TARGET_IS_SVE
|
|
6931
|
+
const Mask<decltype(di)> ge_4 = detail::GeN(indices, 4);
|
|
6932
|
+
#else
|
|
6933
|
+
const Mask<decltype(di)> ge_4 = Ge(indices, Set(di, 4));
|
|
6934
|
+
#endif
|
|
6935
|
+
indices = MaskedAddOr(indices, ge_4, indices, adjust);
|
|
6936
|
+
|
|
6937
|
+
return TwoTablesLookupLanes(d, t0, t1, IndicesFromVec(d, indices));
|
|
6938
|
+
}
|
|
6939
|
+
}
|
|
6940
|
+
|
|
6801
6941
|
// ------------------------------ Reverse2, Reverse4, Reverse8 (8-bit)
|
|
6802
6942
|
|
|
6803
6943
|
#if (defined(HWY_NATIVE_REVERSE2_8) == defined(HWY_TARGET_TOGGLE)) || HWY_IDE
|
|
@@ -15,11 +15,28 @@
|
|
|
15
15
|
// 256-bit LASX vectors and operations.
|
|
16
16
|
// External include guard in highway.h - see comment there.
|
|
17
17
|
|
|
18
|
-
#include <lasxintrin.h>
|
|
19
|
-
|
|
20
18
|
#include "hwy/ops/loongarch_lsx-inl.h"
|
|
21
19
|
#include "hwy/ops/shared-inl.h"
|
|
22
20
|
|
|
21
|
+
#ifndef __loongarch_asx
|
|
22
|
+
// If LASX is to be runtime dispatched (instead of in baseline), we need
|
|
23
|
+
// to enable it *and* define __loongarch_asx or the intrinsic header will
|
|
24
|
+
// fail to compile.
|
|
25
|
+
//
|
|
26
|
+
// For consistency, the same pattern as the lsxintrin.h handling in
|
|
27
|
+
// loongarch_lsx-inl.h is used (instead of moving lasxintrin.h after
|
|
28
|
+
// HWY_BEFORE_NAMESPACE).
|
|
29
|
+
HWY_PUSH_ATTRIBUTES("lsx,lasx")
|
|
30
|
+
#define __loongarch_asx
|
|
31
|
+
#include <lasxintrin.h>
|
|
32
|
+
#undef __loongarch_asx
|
|
33
|
+
// Prevent "unused push_attribute" warning from Clang.
|
|
34
|
+
HWY_MAYBE_UNUSED static void HWY_CONCAT(hwy_lasx_dummy, __COUNTER__) () {}
|
|
35
|
+
HWY_POP_ATTRIBUTES
|
|
36
|
+
#else
|
|
37
|
+
#include <lasxintrin.h>
|
|
38
|
+
#endif
|
|
39
|
+
|
|
23
40
|
HWY_BEFORE_NAMESPACE();
|
|
24
41
|
namespace hwy {
|
|
25
42
|
namespace HWY_NAMESPACE {
|
|
@@ -372,12 +389,6 @@ HWY_API Vec256<T> Not(const Vec256<T> v) {
|
|
|
372
389
|
BitCast(du, v).raw)});
|
|
373
390
|
}
|
|
374
391
|
|
|
375
|
-
// ------------------------------ Xor3
|
|
376
|
-
template <typename T>
|
|
377
|
-
HWY_API Vec256<T> Xor3(Vec256<T> x1, Vec256<T> x2, Vec256<T> x3) {
|
|
378
|
-
return Xor(x1, Xor(x2, x3));
|
|
379
|
-
}
|
|
380
|
-
|
|
381
392
|
// ------------------------------ Or3
|
|
382
393
|
template <typename T>
|
|
383
394
|
HWY_API Vec256<T> Or3(Vec256<T> o1, Vec256<T> o2, Vec256<T> o3) {
|
|
@@ -2462,7 +2473,7 @@ HWY_API Vec256<T> TableLookupLanes(Vec256<T> v, Indices256<T> idx) {
|
|
|
2462
2473
|
// Replicate 64-bit index into upper 32 bits
|
|
2463
2474
|
const Vec256<TI> dup{__lasx_xvpackev_w(idx.raw, idx.raw)};
|
|
2464
2475
|
// For each idx64 i, idx32 are 2*i and 2*i+1.
|
|
2465
|
-
const Vec256<TI> idx32 = dup + dup + Set(di64, int64_t
|
|
2476
|
+
const Vec256<TI> idx32 = dup + dup + Set(di64, int64_t{1} << 32);
|
|
2466
2477
|
return BitCast(
|
|
2467
2478
|
d, TableLookupLanes(BitCast(di32, v), Indices256<int32_t>{idx32.raw}));
|
|
2468
2479
|
}
|
|
@@ -2515,6 +2526,17 @@ HWY_API V InterleaveOddBlocks(D d, V a, V b) {
|
|
|
2515
2526
|
return ConcatUpperUpper(d, b, a);
|
|
2516
2527
|
}
|
|
2517
2528
|
|
|
2529
|
+
// ------------------------------ InterleaveLowerBlocks
|
|
2530
|
+
template <class D, class V = VFromD<D>, HWY_IF_V_SIZE_D(D, 32)>
|
|
2531
|
+
HWY_API V InterleaveLowerBlocks(D d, V a, V b) {
|
|
2532
|
+
return InterleaveEvenBlocks(d, a, b);
|
|
2533
|
+
}
|
|
2534
|
+
// ------------------------------ InterleaveUpperBlocks
|
|
2535
|
+
template <class D, class V = VFromD<D>, HWY_IF_V_SIZE_D(D, 32)>
|
|
2536
|
+
HWY_API V InterleaveUpperBlocks(D d, V a, V b) {
|
|
2537
|
+
return InterleaveOddBlocks(d, a, b);
|
|
2538
|
+
}
|
|
2539
|
+
|
|
2518
2540
|
// ------------------------------ Reverse (RotateRight)
|
|
2519
2541
|
|
|
2520
2542
|
template <class D, HWY_IF_V_SIZE_D(D, 32), HWY_IF_T_SIZE_D(D, 4)>
|