godot/thirdparty/embree/common/simd/vfloat4_sse2.h

// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#pragma once

#define vboolf
#define vboold
#define vint
#define vuint
#define vllong
#define vfloat
#define vdouble

namespace embree
{
  /* 4-wide SSE float type */
  template<>
  struct vfloat<4>
  {};

  ////////////////////////////////////////////////////////////////////////////////
  /// Load/Store
  ////////////////////////////////////////////////////////////////////////////////

  template<> struct mem<vfloat4>
  {};
    
  ////////////////////////////////////////////////////////////////////////////////
  /// Unary Operators
  ////////////////////////////////////////////////////////////////////////////////

  __forceinline vfloat4 asFloat(const vint4&   a) {}
  __forceinline vint4   asInt  (const vfloat4& a) {}
  __forceinline vuint4  asUInt (const vfloat4& a) {}

  __forceinline vint4   toInt  (const vfloat4& a) {}
  __forceinline vfloat4 toFloat(const vint4&   a) {}

  __forceinline vfloat4 operator +(const vfloat4& a) {}
#if defined(__aarch64__)
  __forceinline vfloat4 operator -(const vfloat4& a) {
    return vnegq_f32(a);
  }
#else
  __forceinline vfloat4 operator -(const vfloat4& a) {}
#endif

#if defined(__aarch64__)
  __forceinline vfloat4 abs(const vfloat4& a) { return _mm_abs_ps(a); }
#else
  __forceinline vfloat4 abs(const vfloat4& a) {}
#endif

#if defined(__AVX512VL__)
  __forceinline vfloat4 sign(const vfloat4& a) { return _mm_mask_blend_ps(_mm_cmp_ps_mask(a, vfloat4(zero), _CMP_LT_OQ), vfloat4(one), -vfloat4(one)); }
#else
  __forceinline vfloat4 sign(const vfloat4& a) {}
#endif

  __forceinline vfloat4 signmsk(const vfloat4& a) {}

  __forceinline vfloat4 rcp(const vfloat4& a)
  {}
  __forceinline vfloat4 sqr (const vfloat4& a) {}
  __forceinline vfloat4 sqrt(const vfloat4& a) {}

  __forceinline vfloat4 rsqrt(const vfloat4& a)
  {}

  __forceinline vboolf4 isnan(const vfloat4& a) {}

  ////////////////////////////////////////////////////////////////////////////////
  /// Binary Operators
  ////////////////////////////////////////////////////////////////////////////////

  __forceinline vfloat4 operator +(const vfloat4& a, const vfloat4& b) {}
  __forceinline vfloat4 operator +(const vfloat4& a, float          b) {}
  __forceinline vfloat4 operator +(float          a, const vfloat4& b) {}

  __forceinline vfloat4 operator -(const vfloat4& a, const vfloat4& b) {}
  __forceinline vfloat4 operator -(const vfloat4& a, float          b) {}
  __forceinline vfloat4 operator -(float          a, const vfloat4& b) {}

  __forceinline vfloat4 operator *(const vfloat4& a, const vfloat4& b) {}
  __forceinline vfloat4 operator *(const vfloat4& a, float          b) {}
  __forceinline vfloat4 operator *(float          a, const vfloat4& b) {}

  __forceinline vfloat4 operator /(const vfloat4& a, const vfloat4& b) {}
  __forceinline vfloat4 operator /(const vfloat4& a, float          b) {}
  __forceinline vfloat4 operator /(float          a, const vfloat4& b) {}

  __forceinline vfloat4 operator &(const vfloat4& a, const vfloat4& b) {}
  __forceinline vfloat4 operator |(const vfloat4& a, const vfloat4& b) {}
  __forceinline vfloat4 operator ^(const vfloat4& a, const vfloat4& b) {}
  __forceinline vfloat4 operator ^(const vfloat4& a, const vint4&   b) {}

  __forceinline vfloat4 min(const vfloat4& a, const vfloat4& b) {}
  __forceinline vfloat4 min(const vfloat4& a, float          b) {}
  __forceinline vfloat4 min(float          a, const vfloat4& b) {}

  __forceinline vfloat4 max(const vfloat4& a, const vfloat4& b) {}
  __forceinline vfloat4 max(const vfloat4& a, float          b) {}
  __forceinline vfloat4 max(float          a, const vfloat4& b) {}

#if defined(__SSE4_1__) || defined(__aarch64__)

    __forceinline vfloat4 mini(const vfloat4& a, const vfloat4& b) {
      const vint4 ai = _mm_castps_si128(a);
      const vint4 bi = _mm_castps_si128(b);
      const vint4 ci = _mm_min_epi32(ai,bi);
      return _mm_castsi128_ps(ci);
    }

    __forceinline vfloat4 maxi(const vfloat4& a, const vfloat4& b) {
      const vint4 ai = _mm_castps_si128(a);
      const vint4 bi = _mm_castps_si128(b);
      const vint4 ci = _mm_max_epi32(ai,bi);
      return _mm_castsi128_ps(ci);
    }

    __forceinline vfloat4 minui(const vfloat4& a, const vfloat4& b) {
      const vint4 ai = _mm_castps_si128(a);
      const vint4 bi = _mm_castps_si128(b);
      const vint4 ci = _mm_min_epu32(ai,bi);
      return _mm_castsi128_ps(ci);
    }

    __forceinline vfloat4 maxui(const vfloat4& a, const vfloat4& b) {
      const vint4 ai = _mm_castps_si128(a);
      const vint4 bi = _mm_castps_si128(b);
      const vint4 ci = _mm_max_epu32(ai,bi);
      return _mm_castsi128_ps(ci);
    }
#else
    __forceinline vfloat4 mini(const vfloat4& a, const vfloat4& b) {}

    __forceinline vfloat4 maxi(const vfloat4& a, const vfloat4& b) {}
#endif

  ////////////////////////////////////////////////////////////////////////////////
  /// Ternary Operators
  ////////////////////////////////////////////////////////////////////////////////

#if defined(__AVX2__) || defined(__ARM_NEON)
  __forceinline vfloat4 madd (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fmadd_ps(a,b,c); }
  __forceinline vfloat4 msub (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fmsub_ps(a,b,c); }
  __forceinline vfloat4 nmadd(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fnmadd_ps(a,b,c); }
  __forceinline vfloat4 nmsub(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fnmsub_ps(a,b,c); }
#else
  __forceinline vfloat4 madd (const vfloat4& a, const vfloat4& b, const vfloat4& c) {}
  __forceinline vfloat4 nmadd(const vfloat4& a, const vfloat4& b, const vfloat4& c) {}
  __forceinline vfloat4 nmsub(const vfloat4& a, const vfloat4& b, const vfloat4& c) {}
  __forceinline vfloat4 msub (const vfloat4& a, const vfloat4& b, const vfloat4& c) {}

#endif

  ////////////////////////////////////////////////////////////////////////////////
  /// Assignment Operators
  ////////////////////////////////////////////////////////////////////////////////

  __forceinline vfloat4& operator +=(vfloat4& a, const vfloat4& b) {}
  __forceinline vfloat4& operator +=(vfloat4& a, float          b) {}

  __forceinline vfloat4& operator -=(vfloat4& a, const vfloat4& b) {}
  __forceinline vfloat4& operator -=(vfloat4& a, float          b) {}

  __forceinline vfloat4& operator *=(vfloat4& a, const vfloat4& b) {}
  __forceinline vfloat4& operator *=(vfloat4& a, float          b) {}

  __forceinline vfloat4& operator /=(vfloat4& a, const vfloat4& b) {}
  __forceinline vfloat4& operator /=(vfloat4& a, float          b) {}

  ////////////////////////////////////////////////////////////////////////////////
  /// Comparison Operators + Select
  ////////////////////////////////////////////////////////////////////////////////

#if defined(__AVX512VL__)
  __forceinline vboolf4 operator ==(const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_EQ); }
  __forceinline vboolf4 operator !=(const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_NE); }
  __forceinline vboolf4 operator < (const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_LT); }
  __forceinline vboolf4 operator >=(const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_GE); }
  __forceinline vboolf4 operator > (const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_GT); }
  __forceinline vboolf4 operator <=(const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_LE); }
#else
  __forceinline vboolf4 operator ==(const vfloat4& a, const vfloat4& b) {}
  __forceinline vboolf4 operator !=(const vfloat4& a, const vfloat4& b) {}
  __forceinline vboolf4 operator < (const vfloat4& a, const vfloat4& b) {}
#if defined(__aarch64__)
  __forceinline vboolf4 operator >=(const vfloat4& a, const vfloat4& b) { return _mm_cmpge_ps (a, b); }
  __forceinline vboolf4 operator > (const vfloat4& a, const vfloat4& b) { return _mm_cmpgt_ps (a, b); }
#else
  __forceinline vboolf4 operator >=(const vfloat4& a, const vfloat4& b) {}
  __forceinline vboolf4 operator > (const vfloat4& a, const vfloat4& b) {}
#endif
  __forceinline vboolf4 operator <=(const vfloat4& a, const vfloat4& b) {}
#endif

  __forceinline vboolf4 operator ==(const vfloat4& a, float          b) {}
  __forceinline vboolf4 operator ==(float          a, const vfloat4& b) {}

  __forceinline vboolf4 operator !=(const vfloat4& a, float          b) {}
  __forceinline vboolf4 operator !=(float          a, const vfloat4& b) {}

  __forceinline vboolf4 operator < (const vfloat4& a, float          b) {}
  __forceinline vboolf4 operator < (float          a, const vfloat4& b) {}
  
  __forceinline vboolf4 operator >=(const vfloat4& a, float          b) {}
  __forceinline vboolf4 operator >=(float          a, const vfloat4& b) {}

  __forceinline vboolf4 operator > (const vfloat4& a, float          b) {}
  __forceinline vboolf4 operator > (float          a, const vfloat4& b) {}

  __forceinline vboolf4 operator <=(const vfloat4& a, float          b) {}
  __forceinline vboolf4 operator <=(float          a, const vfloat4& b) {}

  __forceinline vboolf4 eq(const vfloat4& a, const vfloat4& b) {}
  __forceinline vboolf4 ne(const vfloat4& a, const vfloat4& b) {}
  __forceinline vboolf4 lt(const vfloat4& a, const vfloat4& b) {}
  __forceinline vboolf4 ge(const vfloat4& a, const vfloat4& b) {}
  __forceinline vboolf4 gt(const vfloat4& a, const vfloat4& b) {}
  __forceinline vboolf4 le(const vfloat4& a, const vfloat4& b) {}

#if defined(__AVX512VL__)
  __forceinline vboolf4 eq(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return _mm_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_EQ); }
  __forceinline vboolf4 ne(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return _mm_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_NE); }
  __forceinline vboolf4 lt(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return _mm_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_LT); }
  __forceinline vboolf4 ge(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return _mm_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_GE); }
  __forceinline vboolf4 gt(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return _mm_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_GT); }
  __forceinline vboolf4 le(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return _mm_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_LE); }
#else
  __forceinline vboolf4 eq(const vboolf4& mask, const vfloat4& a, const vfloat4& b) {}
  __forceinline vboolf4 ne(const vboolf4& mask, const vfloat4& a, const vfloat4& b) {}
  __forceinline vboolf4 lt(const vboolf4& mask, const vfloat4& a, const vfloat4& b) {}
  __forceinline vboolf4 ge(const vboolf4& mask, const vfloat4& a, const vfloat4& b) {}
  __forceinline vboolf4 gt(const vboolf4& mask, const vfloat4& a, const vfloat4& b) {}
  __forceinline vboolf4 le(const vboolf4& mask, const vfloat4& a, const vfloat4& b) {}
#endif

  template<int mask>
    __forceinline vfloat4 select(const vfloat4& t, const vfloat4& f)
  {}

  __forceinline vfloat4 lerp(const vfloat4& a, const vfloat4& b, const vfloat4& t) {}
  
  __forceinline bool isvalid(const vfloat4& v) {}

  __forceinline bool is_finite(const vfloat4& a) {}

  __forceinline bool is_finite(const vboolf4& valid, const vfloat4& a) {}
  
  ////////////////////////////////////////////////////////////////////////////////
  /// Rounding Functions
  ////////////////////////////////////////////////////////////////////////////////

#if defined(__aarch64__)
  __forceinline vfloat4 floor(const vfloat4& a) { return vrndmq_f32(a.v); } // towards -inf
  __forceinline vfloat4 ceil (const vfloat4& a) { return vrndpq_f32(a.v); } // toward +inf
  __forceinline vfloat4 trunc(const vfloat4& a) { return vrndq_f32(a.v); } // towards 0
  __forceinline vfloat4 round(const vfloat4& a) { return vrndnq_f32(a.v); } // to nearest, ties to even. NOTE(LTE): arm clang uses vrndnq, old gcc uses vrndqn?
#elif defined (__SSE4_1__)
  __forceinline vfloat4 floor(const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF    ); }
  __forceinline vfloat4 ceil (const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_POS_INF    ); }
  __forceinline vfloat4 trunc(const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_ZERO       ); }
  __forceinline vfloat4 round(const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_NEAREST_INT); }
#else
  __forceinline vfloat4 floor(const vfloat4& a) {}
  __forceinline vfloat4 ceil (const vfloat4& a) {}
  __forceinline vfloat4 trunc(const vfloat4& a) {}
  __forceinline vfloat4 round(const vfloat4& a) {}
#endif
  __forceinline vfloat4 frac(const vfloat4& a) {}

  __forceinline vint4 floori(const vfloat4& a) {}

  ////////////////////////////////////////////////////////////////////////////////
  /// Movement/Shifting/Shuffling Functions
  ////////////////////////////////////////////////////////////////////////////////

  __forceinline vfloat4 unpacklo(const vfloat4& a, const vfloat4& b) {}
  __forceinline vfloat4 unpackhi(const vfloat4& a, const vfloat4& b) {}

#if defined(__aarch64__)
      template<int i0, int i1, int i2, int i3>
      __forceinline vfloat4 shuffle(const vfloat4& v) {
          return vreinterpretq_f32_u8(vqtbl1q_u8( (uint8x16_t)v.v, _MN_SHUFFLE(i0, i1, i2, i3)));
      }
      template<int i0, int i1, int i2, int i3>
      __forceinline vfloat4 shuffle(const vfloat4& a, const vfloat4& b) {
          return vreinterpretq_f32_u8(vqtbl2q_u8( (uint8x16x2_t){(uint8x16_t)a.v, (uint8x16_t)b.v}, _MF_SHUFFLE(i0, i1, i2, i3)));
      }
#else
  template<int i0, int i1, int i2, int i3>
  __forceinline vfloat4 shuffle(const vfloat4& v) {}

  template<int i0, int i1, int i2, int i3>
  __forceinline vfloat4 shuffle(const vfloat4& a, const vfloat4& b) {}
#endif

#if defined(__SSE3__) && !defined(__aarch64__)
  template<> __forceinline vfloat4 shuffle<0, 0, 2, 2>(const vfloat4& v) { return _mm_moveldup_ps(v); }
  template<> __forceinline vfloat4 shuffle<1, 1, 3, 3>(const vfloat4& v) { return _mm_movehdup_ps(v); }
  template<> __forceinline vfloat4 shuffle<0, 1, 0, 1>(const vfloat4& v) { return _mm_castpd_ps(_mm_movedup_pd(_mm_castps_pd(v))); }
#endif

  template<int i>
  __forceinline vfloat4 shuffle(const vfloat4& v) {}

#if defined(__aarch64__)
  template<int i> __forceinline float extract(const vfloat4& a) { return a[i]; }
#else
  template<int i> __forceinline float extract   (const vfloat4& a) {}
  template<>      __forceinline float extract<0>(const vfloat4& a) {}
#endif

#if defined (__SSE4_1__) && !defined(__aarch64__)
  template<int dst, int src, int clr> __forceinline vfloat4 insert(const vfloat4& a, const vfloat4& b) { return _mm_insert_ps(a, b, (dst << 4) | (src << 6) | clr); }
  template<int dst, int src> __forceinline vfloat4 insert(const vfloat4& a, const vfloat4& b) { return insert<dst, src, 0>(a, b); }
  template<int dst> __forceinline vfloat4 insert(const vfloat4& a, const float b) { return insert<dst, 0>(a, _mm_set_ss(b)); }
#else
  template<int dst, int src> __forceinline vfloat4 insert(const vfloat4& a, const vfloat4& b) {}
  template<int dst>  __forceinline vfloat4 insert(const vfloat4& a, float b) {}
#endif

  __forceinline float toScalar(const vfloat4& v) {}

  __forceinline vfloat4 shift_right_1(const vfloat4& x) {}

#if defined (__AVX2__)
  __forceinline vfloat4 permute(const vfloat4 &a, const __m128i &index) {
    return _mm_permutevar_ps(a,index);
  }

  __forceinline vfloat4 broadcast1f(const void* a) { return _mm_broadcast_ss((float*)a); }

#endif

#if defined(__AVX512VL__)
  template<int i>
  __forceinline vfloat4 align_shift_right(const vfloat4& a, const vfloat4& b) {
    return _mm_castsi128_ps(_mm_alignr_epi32(_mm_castps_si128(a), _mm_castps_si128(b), i));
  }  
#endif


  ////////////////////////////////////////////////////////////////////////////////
  /// Sorting Network
  ////////////////////////////////////////////////////////////////////////////////

  __forceinline vfloat4 sort_ascending(const vfloat4& v)
  {}

  __forceinline vfloat4 sort_descending(const vfloat4& v)
  {}

  ////////////////////////////////////////////////////////////////////////////////
  /// Transpose
  ////////////////////////////////////////////////////////////////////////////////

  __forceinline void transpose(const vfloat4& r0, const vfloat4& r1, const vfloat4& r2, const vfloat4& r3, vfloat4& c0, vfloat4& c1, vfloat4& c2, vfloat4& c3)
  {}

  __forceinline void transpose(const vfloat4& r0, const vfloat4& r1, const vfloat4& r2, const vfloat4& r3, vfloat4& c0, vfloat4& c1, vfloat4& c2)
  {}

  ////////////////////////////////////////////////////////////////////////////////
  /// Reductions
  ////////////////////////////////////////////////////////////////////////////////
#if defined(__aarch64__)
  __forceinline vfloat4 vreduce_min(const vfloat4& v) { float h = vminvq_f32(v); return vdupq_n_f32(h); }
  __forceinline vfloat4 vreduce_max(const vfloat4& v) { float h = vmaxvq_f32(v); return vdupq_n_f32(h); }
  __forceinline vfloat4 vreduce_add(const vfloat4& v) { float h = vaddvq_f32(v); return vdupq_n_f32(h); }
#else
  __forceinline vfloat4 vreduce_min(const vfloat4& v) {}
  __forceinline vfloat4 vreduce_max(const vfloat4& v) {}
  __forceinline vfloat4 vreduce_add(const vfloat4& v) {}
#endif

#if defined(__aarch64__)
  __forceinline float reduce_min(const vfloat4& v) { return vminvq_f32(v); }
  __forceinline float reduce_max(const vfloat4& v) { return vmaxvq_f32(v); }
  __forceinline float reduce_add(const vfloat4& v) { return vaddvq_f32(v); }
#else
  __forceinline float reduce_min(const vfloat4& v) {}
  __forceinline float reduce_max(const vfloat4& v) {}
  __forceinline float reduce_add(const vfloat4& v) {}
#endif

  __forceinline size_t select_min(const vboolf4& valid, const vfloat4& v) 
  {}
  __forceinline size_t select_max(const vboolf4& valid, const vfloat4& v) 
  {}
  
  ////////////////////////////////////////////////////////////////////////////////
  /// Euclidean Space Operators
  ////////////////////////////////////////////////////////////////////////////////

  __forceinline float dot(const vfloat4& a, const vfloat4& b) {}

  __forceinline vfloat4 cross(const vfloat4& a, const vfloat4& b)
  {}

  ////////////////////////////////////////////////////////////////////////////////
  /// Output Operators
  ////////////////////////////////////////////////////////////////////////////////

  __forceinline embree_ostream operator <<(embree_ostream cout, const vfloat4& a) {}

}

#undef vboolf
#undef vboold
#undef vint
#undef vuint
#undef vllong
#undef vfloat
#undef vdouble