#ifndef V8_COMMON_SIMD128_H_
#define V8_COMMON_SIMD128_H_
#include <cstdint>
#include "absl/strings/str_format.h"
#include "src/base/macros.h"
#include "src/common/globals.h"
namespace v8::internal {
#define FOREACH_SIMD_TYPE(V) \
V(double, float64x2, f64x2, 2) \
V(float, float32x4, f32x4, 4) \
V(int64_t, int64x2, i64x2, 2) \
V(int32_t, int32x4, i32x4, 4) \
V(int16_t, int16x8, i16x8, 8) \
V(int8_t, int8x16, i8x16, 16)
class alignas(double) Simd128 {
public:
#define DEFINE_SIMD_TYPE(cType, sType, name, kSize) \
using sType = std::array<cType, kSize>;
FOREACH_SIMD_TYPE(DEFINE_SIMD_TYPE)
#undef DEFINE_SIMD_TYPE
constexpr Simd128() = default;
#define DEFINE_SIMD_TYPE_SPECIFIC_METHODS(cType, sType, name, size) \
explicit constexpr Simd128(sType val) \
: val_(base::bit_cast<std::array<uint8_t, 16>>(val)) {} \
static constexpr Simd128 Splat(cType value) { \
sType values; \
std::fill_n(values.data(), size, value); \
return Simd128{values}; \
} \
constexpr sType to_##name() const { return base::bit_cast<sType>(val_); }
FOREACH_SIMD_TYPE(DEFINE_SIMD_TYPE_SPECIFIC_METHODS)
#undef DEFINE_SIMD_TYPE_SPECIFIC_METHODS
explicit Simd128(uint8_t* bytes) { memcpy(val_.data(), bytes, sizeof(val_)); }
bool operator==(const Simd128&) const = default;
const uint8_t* bytes() const { return val_.data(); }
template <typename Sink>
friend void AbslStringify(Sink& sink, Simd128 value) {
float64x2 f64x2 = value.to_f64x2();
float32x4 f32x4 = value.to_f32x4();
int64x2 i64x2 = value.to_i64x2();
int32x4 i32x4 = value.to_i32x4();
int16x8 i16x8 = value.to_i16x8();
int8x16 i8x16 = value.to_i8x16();
absl::Format(&sink,
"Simd128 {\n"
" f64x2: %g, %g\n"
" f32x4: %g, %g, %g, %g\n"
" i64x2: %d (0x%016x), %d (0x%016x)\n"
" i32x4: %d (0x%08x), %d (0x%08x), %d (0x%08x), %d (0x%08x)\n"
" i16x8: %d (0x%04x), %d (0x%04x), %d (0x%04x), %d (0x%04x), "
"%d (0x%04x), %d (0x%04x), %d (0x%04x), %d (0x%04x)\n"
" i8x16: %d (0x%02x), %d (0x%02x), %d (0x%02x), %d (0x%02x), "
"%d (0x%02x), %d (0x%02x), %d (0x%02x), %d (0x%02x), "
"%d (0x%02x), %d (0x%02x), %d (0x%02x), %d (0x%02x), "
"%d (0x%02x), %d (0x%02x), %d (0x%02x), %d (0x%02x)\n"
"}",
f64x2[0], f64x2[1],
f32x4[0], f32x4[1], f32x4[2], f32x4[3],
i64x2[0], i64x2[0], i64x2[1], i64x2[1],
i32x4[0], i32x4[0], i32x4[1], i32x4[1], i32x4[2], i32x4[2],
i32x4[3], i32x4[3],
i16x8[0], i16x8[0], i16x8[1], i16x8[1], i16x8[2], i16x8[2],
i16x8[3], i16x8[3], i16x8[4], i16x8[4], i16x8[5], i16x8[5],
i16x8[6], i16x8[6], i16x8[7], i16x8[7],
i8x16[0], i8x16[0], i8x16[1], i8x16[1], i8x16[2], i8x16[2],
i8x16[3], i8x16[3], i8x16[4], i8x16[4], i8x16[5], i8x16[5],
i8x16[6], i8x16[6], i8x16[7], i8x16[7], i8x16[8], i8x16[8],
i8x16[9], i8x16[9], i8x16[10], i8x16[10], i8x16[11], i8x16[11],
i8x16[12], i8x16[12], i8x16[13], i8x16[13], i8x16[14],
i8x16[14], i8x16[15], i8x16[15]);
}
private:
std::array<uint8_t, 16> val_ = {0};
};
inline std::ostream& operator<<(std::ostream& os, const Simd128& simd) {
return os << absl::StrFormat("%v", simd);
}
}
#endif