/* SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * Copyright:
 *   2020      Evan Nemerson <evan@nemerson.com>
 *   2020      Himanshi Mathur <himanshi18037@iiitd.ac.in>
 */

#define SIMDE_TEST_X86_AVX512_INSN negate

#include <test/x86/avx512/test-avx512.h>
#include <simde/x86/avx512/negate.h>

static int
test_simde_x_mm512_negate_ps (SIMDE_MUNIT_TEST_ARGS) {
#if 1
  static const struct {
    const simde_float32 a[16];
    const simde_float32 r[16];
  } test_vec[] = {
    { { SIMDE_FLOAT32_C(   447.12), SIMDE_FLOAT32_C(  -523.97), SIMDE_FLOAT32_C(  -986.50), SIMDE_FLOAT32_C(   215.70),
        SIMDE_FLOAT32_C(  -620.53), SIMDE_FLOAT32_C(  -551.80), SIMDE_FLOAT32_C(   527.48), SIMDE_FLOAT32_C(  -998.22),
        SIMDE_FLOAT32_C(   113.44), SIMDE_FLOAT32_C(  -366.28), SIMDE_FLOAT32_C(   857.01), SIMDE_FLOAT32_C(  -561.75),
        SIMDE_FLOAT32_C(  -685.47), SIMDE_FLOAT32_C(   121.91), SIMDE_FLOAT32_C(  -767.64), SIMDE_FLOAT32_C(   638.60) },
      { SIMDE_FLOAT32_C(  -447.12), SIMDE_FLOAT32_C(   523.97), SIMDE_FLOAT32_C(   986.50), SIMDE_FLOAT32_C(  -215.70),
        SIMDE_FLOAT32_C(   620.53), SIMDE_FLOAT32_C(   551.80), SIMDE_FLOAT32_C(  -527.48), SIMDE_FLOAT32_C(   998.22),
        SIMDE_FLOAT32_C(  -113.44), SIMDE_FLOAT32_C(   366.28), SIMDE_FLOAT32_C(  -857.01), SIMDE_FLOAT32_C(   561.75),
        SIMDE_FLOAT32_C(   685.47), SIMDE_FLOAT32_C(  -121.91), SIMDE_FLOAT32_C(   767.64), SIMDE_FLOAT32_C(  -638.60) } },
    { { SIMDE_FLOAT32_C(  -616.86), SIMDE_FLOAT32_C(  -616.09), SIMDE_FLOAT32_C(   561.55), SIMDE_FLOAT32_C(   555.86),
        SIMDE_FLOAT32_C(  -361.77), SIMDE_FLOAT32_C(   375.95), SIMDE_FLOAT32_C(   150.28), SIMDE_FLOAT32_C(   812.25),
        SIMDE_FLOAT32_C(  -808.22), SIMDE_FLOAT32_C(  -841.08), SIMDE_FLOAT32_C(   575.36), SIMDE_FLOAT32_C(  -396.66),
        SIMDE_FLOAT32_C(   938.55), SIMDE_FLOAT32_C(  -369.15), SIMDE_FLOAT32_C(  -777.21), SIMDE_FLOAT32_C(   385.67) },
      { SIMDE_FLOAT32_C(   616.86), SIMDE_FLOAT32_C(   616.09), SIMDE_FLOAT32_C(  -561.55), SIMDE_FLOAT32_C(  -555.86),
        SIMDE_FLOAT32_C(   361.77), SIMDE_FLOAT32_C(  -375.95), SIMDE_FLOAT32_C(  -150.28), SIMDE_FLOAT32_C(  -812.25),
        SIMDE_FLOAT32_C(   808.22), SIMDE_FLOAT32_C(   841.08), SIMDE_FLOAT32_C(  -575.36), SIMDE_FLOAT32_C(   396.66),
        SIMDE_FLOAT32_C(  -938.55), SIMDE_FLOAT32_C(   369.15), SIMDE_FLOAT32_C(   777.21), SIMDE_FLOAT32_C(  -385.67) } },
    { { SIMDE_FLOAT32_C(   106.88), SIMDE_FLOAT32_C(  -763.71), SIMDE_FLOAT32_C(  -398.63), SIMDE_FLOAT32_C(   486.35),
        SIMDE_FLOAT32_C(  -315.51), SIMDE_FLOAT32_C(  -871.16), SIMDE_FLOAT32_C(   488.13), SIMDE_FLOAT32_C(   797.93),
        SIMDE_FLOAT32_C(  -237.43), SIMDE_FLOAT32_C(   345.14), SIMDE_FLOAT32_C(  -763.82), SIMDE_FLOAT32_C(    77.10),
        SIMDE_FLOAT32_C(  -532.95), SIMDE_FLOAT32_C(  -531.46), SIMDE_FLOAT32_C(  -284.30), SIMDE_FLOAT32_C(  -149.81) },
      { SIMDE_FLOAT32_C(  -106.88), SIMDE_FLOAT32_C(   763.71), SIMDE_FLOAT32_C(   398.63), SIMDE_FLOAT32_C(  -486.35),
        SIMDE_FLOAT32_C(   315.51), SIMDE_FLOAT32_C(   871.16), SIMDE_FLOAT32_C(  -488.13), SIMDE_FLOAT32_C(  -797.93),
        SIMDE_FLOAT32_C(   237.43), SIMDE_FLOAT32_C(  -345.14), SIMDE_FLOAT32_C(   763.82), SIMDE_FLOAT32_C(   -77.10),
        SIMDE_FLOAT32_C(   532.95), SIMDE_FLOAT32_C(   531.46), SIMDE_FLOAT32_C(   284.30), SIMDE_FLOAT32_C(   149.81) } },
    { { SIMDE_FLOAT32_C(  -147.55), SIMDE_FLOAT32_C(  -722.75), SIMDE_FLOAT32_C(  -593.95), SIMDE_FLOAT32_C(   490.68),
        SIMDE_FLOAT32_C(   653.20), SIMDE_FLOAT32_C(   556.33), SIMDE_FLOAT32_C(   302.93), SIMDE_FLOAT32_C(   844.97),
        SIMDE_FLOAT32_C(   715.24), SIMDE_FLOAT32_C(  -121.71), SIMDE_FLOAT32_C(  -551.69), SIMDE_FLOAT32_C(   653.79),
        SIMDE_FLOAT32_C(   509.14), SIMDE_FLOAT32_C(  -328.89), SIMDE_FLOAT32_C(    39.46), SIMDE_FLOAT32_C(  -383.98) },
      { SIMDE_FLOAT32_C(   147.55), SIMDE_FLOAT32_C(   722.75), SIMDE_FLOAT32_C(   593.95), SIMDE_FLOAT32_C(  -490.68),
        SIMDE_FLOAT32_C(  -653.20), SIMDE_FLOAT32_C(  -556.33), SIMDE_FLOAT32_C(  -302.93), SIMDE_FLOAT32_C(  -844.97),
        SIMDE_FLOAT32_C(  -715.24), SIMDE_FLOAT32_C(   121.71), SIMDE_FLOAT32_C(   551.69), SIMDE_FLOAT32_C(  -653.79),
        SIMDE_FLOAT32_C(  -509.14), SIMDE_FLOAT32_C(   328.89), SIMDE_FLOAT32_C(   -39.46), SIMDE_FLOAT32_C(   383.98) } },
    { { SIMDE_FLOAT32_C(   -92.60), SIMDE_FLOAT32_C(   640.83), SIMDE_FLOAT32_C(  -897.63), SIMDE_FLOAT32_C(   591.90),
        SIMDE_FLOAT32_C(   769.67), SIMDE_FLOAT32_C(   590.51), SIMDE_FLOAT32_C(   389.83), SIMDE_FLOAT32_C(  -467.76),
        SIMDE_FLOAT32_C(   -64.35), SIMDE_FLOAT32_C(   626.00), SIMDE_FLOAT32_C(   609.34), SIMDE_FLOAT32_C(   402.70),
        SIMDE_FLOAT32_C(  -905.45), SIMDE_FLOAT32_C(  -674.96), SIMDE_FLOAT32_C(  -747.11), SIMDE_FLOAT32_C(   -53.00) },
      { SIMDE_FLOAT32_C(    92.60), SIMDE_FLOAT32_C(  -640.83), SIMDE_FLOAT32_C(   897.63), SIMDE_FLOAT32_C(  -591.90),
        SIMDE_FLOAT32_C(  -769.67), SIMDE_FLOAT32_C(  -590.51), SIMDE_FLOAT32_C(  -389.83), SIMDE_FLOAT32_C(   467.76),
        SIMDE_FLOAT32_C(    64.35), SIMDE_FLOAT32_C(  -626.00), SIMDE_FLOAT32_C(  -609.34), SIMDE_FLOAT32_C(  -402.70),
        SIMDE_FLOAT32_C(   905.45), SIMDE_FLOAT32_C(   674.96), SIMDE_FLOAT32_C(   747.11), SIMDE_FLOAT32_C(    53.00) } },
    { { SIMDE_FLOAT32_C(  -397.72), SIMDE_FLOAT32_C(  -341.07), SIMDE_FLOAT32_C(  -562.32), SIMDE_FLOAT32_C(  -744.52),
        SIMDE_FLOAT32_C(  -784.74), SIMDE_FLOAT32_C(   740.61), SIMDE_FLOAT32_C(  -899.55), SIMDE_FLOAT32_C(   930.50),
        SIMDE_FLOAT32_C(  -381.10), SIMDE_FLOAT32_C(  -451.23), SIMDE_FLOAT32_C(   584.30), SIMDE_FLOAT32_C(  -871.96),
        SIMDE_FLOAT32_C(   219.87), SIMDE_FLOAT32_C(  -376.24), SIMDE_FLOAT32_C(  -255.94), SIMDE_FLOAT32_C(  -872.72) },
      { SIMDE_FLOAT32_C(   397.72), SIMDE_FLOAT32_C(   341.07), SIMDE_FLOAT32_C(   562.32), SIMDE_FLOAT32_C(   744.52),
        SIMDE_FLOAT32_C(   784.74), SIMDE_FLOAT32_C(  -740.61), SIMDE_FLOAT32_C(   899.55), SIMDE_FLOAT32_C(  -930.50),
        SIMDE_FLOAT32_C(   381.10), SIMDE_FLOAT32_C(   451.23), SIMDE_FLOAT32_C(  -584.30), SIMDE_FLOAT32_C(   871.96),
        SIMDE_FLOAT32_C(  -219.87), SIMDE_FLOAT32_C(   376.24), SIMDE_FLOAT32_C(   255.94), SIMDE_FLOAT32_C(   872.72) } },
    { { SIMDE_FLOAT32_C(  -735.42), SIMDE_FLOAT32_C(  -153.57), SIMDE_FLOAT32_C(   719.17), SIMDE_FLOAT32_C(  -965.75),
        SIMDE_FLOAT32_C(  -563.06), SIMDE_FLOAT32_C(   109.00), SIMDE_FLOAT32_C(  -433.51), SIMDE_FLOAT32_C(   372.59),
        SIMDE_FLOAT32_C(  -265.00), SIMDE_FLOAT32_C(  -824.17), SIMDE_FLOAT32_C(  -224.72), SIMDE_FLOAT32_C(  -170.45),
        SIMDE_FLOAT32_C(  -499.13), SIMDE_FLOAT32_C(    28.17), SIMDE_FLOAT32_C(   776.55), SIMDE_FLOAT32_C(   103.15) },
      { SIMDE_FLOAT32_C(   735.42), SIMDE_FLOAT32_C(   153.57), SIMDE_FLOAT32_C(  -719.17), SIMDE_FLOAT32_C(   965.75),
        SIMDE_FLOAT32_C(   563.06), SIMDE_FLOAT32_C(  -109.00), SIMDE_FLOAT32_C(   433.51), SIMDE_FLOAT32_C(  -372.59),
        SIMDE_FLOAT32_C(   265.00), SIMDE_FLOAT32_C(   824.17), SIMDE_FLOAT32_C(   224.72), SIMDE_FLOAT32_C(   170.45),
        SIMDE_FLOAT32_C(   499.13), SIMDE_FLOAT32_C(   -28.17), SIMDE_FLOAT32_C(  -776.55), SIMDE_FLOAT32_C(  -103.15) } },
    { { SIMDE_FLOAT32_C(   687.10), SIMDE_FLOAT32_C(  -785.77), SIMDE_FLOAT32_C(   358.63), SIMDE_FLOAT32_C(   902.36),
        SIMDE_FLOAT32_C(   954.84), SIMDE_FLOAT32_C(   459.09), SIMDE_FLOAT32_C(   832.87), SIMDE_FLOAT32_C(  -426.26),
        SIMDE_FLOAT32_C(  -992.15), SIMDE_FLOAT32_C(   417.17), SIMDE_FLOAT32_C(  -298.23), SIMDE_FLOAT32_C(   227.73),
        SIMDE_FLOAT32_C(  -959.08), SIMDE_FLOAT32_C(   445.83), SIMDE_FLOAT32_C(   355.00), SIMDE_FLOAT32_C(  -694.49) },
      { SIMDE_FLOAT32_C(  -687.10), SIMDE_FLOAT32_C(   785.77), SIMDE_FLOAT32_C(  -358.63), SIMDE_FLOAT32_C(  -902.36),
        SIMDE_FLOAT32_C(  -954.84), SIMDE_FLOAT32_C(  -459.09), SIMDE_FLOAT32_C(  -832.87), SIMDE_FLOAT32_C(   426.26),
        SIMDE_FLOAT32_C(   992.15), SIMDE_FLOAT32_C(  -417.17), SIMDE_FLOAT32_C(   298.23), SIMDE_FLOAT32_C(  -227.73),
        SIMDE_FLOAT32_C(   959.08), SIMDE_FLOAT32_C(  -445.83), SIMDE_FLOAT32_C(  -355.00), SIMDE_FLOAT32_C(   694.49) } }
  };

  for (size_t i = 0 ; i < (sizeof(test_vec) / sizeof(test_vec[0])) ; i++) {
    simde__m512 a = simde_mm512_loadu_ps(test_vec[i].a);
    simde__m512 r = simde_x_mm512_negate_ps(a);
    simde_test_x86_assert_equal_f32x16(r, simde_mm512_loadu_ps(test_vec[i].r), 1);
  }

  return 0;
#else
  fputc('\n', stdout);
  for (int i = 0 ; i < 8 ; i++) {
    simde__m512 a = simde_test_x86_random_f32x16(SIMDE_FLOAT32_C(-1000.0), SIMDE_FLOAT32_C(1000.0));
    simde__m512 r = simde_x_mm512_negate_ps(a);

    simde_test_x86_write_f32x16(2, a, SIMDE_TEST_VEC_POS_FIRST);
    simde_test_x86_write_f32x16(2, r, SIMDE_TEST_VEC_POS_LAST);
  }
  return 1;
#endif
}

static int
test_simde_x_mm512_negate_pd (SIMDE_MUNIT_TEST_ARGS) {
#if 1
  static const struct {
    const simde_float64 a[8];
    const simde_float64 r[8];
  } test_vec[] = {
    { { SIMDE_FLOAT64_C(  -707.74), SIMDE_FLOAT64_C(    74.18), SIMDE_FLOAT64_C(  -660.24), SIMDE_FLOAT64_C(  -270.80),
        SIMDE_FLOAT64_C(  -816.83), SIMDE_FLOAT64_C(   -93.75), SIMDE_FLOAT64_C(  -898.21), SIMDE_FLOAT64_C(   -81.83) },
      { SIMDE_FLOAT64_C(   707.74), SIMDE_FLOAT64_C(   -74.18), SIMDE_FLOAT64_C(   660.24), SIMDE_FLOAT64_C(   270.80),
        SIMDE_FLOAT64_C(   816.83), SIMDE_FLOAT64_C(    93.75), SIMDE_FLOAT64_C(   898.21), SIMDE_FLOAT64_C(    81.83) } },
    { { SIMDE_FLOAT64_C(    82.08), SIMDE_FLOAT64_C(  -122.93), SIMDE_FLOAT64_C(   747.72), SIMDE_FLOAT64_C(   582.95),
        SIMDE_FLOAT64_C(   905.24), SIMDE_FLOAT64_C(   524.27), SIMDE_FLOAT64_C(  -313.90), SIMDE_FLOAT64_C(   592.34) },
      { SIMDE_FLOAT64_C(   -82.08), SIMDE_FLOAT64_C(   122.93), SIMDE_FLOAT64_C(  -747.72), SIMDE_FLOAT64_C(  -582.95),
        SIMDE_FLOAT64_C(  -905.24), SIMDE_FLOAT64_C(  -524.27), SIMDE_FLOAT64_C(   313.90), SIMDE_FLOAT64_C(  -592.34) } },
    { { SIMDE_FLOAT64_C(   738.50), SIMDE_FLOAT64_C(  -955.26), SIMDE_FLOAT64_C(   494.71), SIMDE_FLOAT64_C(   693.34),
        SIMDE_FLOAT64_C(   503.82), SIMDE_FLOAT64_C(   327.58), SIMDE_FLOAT64_C(  -732.92), SIMDE_FLOAT64_C(   511.68) },
      { SIMDE_FLOAT64_C(  -738.50), SIMDE_FLOAT64_C(   955.26), SIMDE_FLOAT64_C(  -494.71), SIMDE_FLOAT64_C(  -693.34),
        SIMDE_FLOAT64_C(  -503.82), SIMDE_FLOAT64_C(  -327.58), SIMDE_FLOAT64_C(   732.92), SIMDE_FLOAT64_C(  -511.68) } },
    { { SIMDE_FLOAT64_C(  -255.26), SIMDE_FLOAT64_C(   -31.15), SIMDE_FLOAT64_C(  -260.59), SIMDE_FLOAT64_C(  -214.33),
        SIMDE_FLOAT64_C(  -585.32), SIMDE_FLOAT64_C(  -905.59), SIMDE_FLOAT64_C(    91.17), SIMDE_FLOAT64_C(  -293.05) },
      { SIMDE_FLOAT64_C(   255.26), SIMDE_FLOAT64_C(    31.15), SIMDE_FLOAT64_C(   260.59), SIMDE_FLOAT64_C(   214.33),
        SIMDE_FLOAT64_C(   585.32), SIMDE_FLOAT64_C(   905.59), SIMDE_FLOAT64_C(   -91.17), SIMDE_FLOAT64_C(   293.05) } },
    { { SIMDE_FLOAT64_C(   168.59), SIMDE_FLOAT64_C(   430.93), SIMDE_FLOAT64_C(   436.15), SIMDE_FLOAT64_C(   351.76),
        SIMDE_FLOAT64_C(  -662.82), SIMDE_FLOAT64_C(   537.93), SIMDE_FLOAT64_C(  -730.06), SIMDE_FLOAT64_C(   419.27) },
      { SIMDE_FLOAT64_C(  -168.59), SIMDE_FLOAT64_C(  -430.93), SIMDE_FLOAT64_C(  -436.15), SIMDE_FLOAT64_C(  -351.76),
        SIMDE_FLOAT64_C(   662.82), SIMDE_FLOAT64_C(  -537.93), SIMDE_FLOAT64_C(   730.06), SIMDE_FLOAT64_C(  -419.27) } },
    { { SIMDE_FLOAT64_C(  -585.00), SIMDE_FLOAT64_C(  -982.34), SIMDE_FLOAT64_C(     2.22), SIMDE_FLOAT64_C(  -679.76),
        SIMDE_FLOAT64_C(   541.93), SIMDE_FLOAT64_C(   688.32), SIMDE_FLOAT64_C(   912.59), SIMDE_FLOAT64_C(   280.44) },
      { SIMDE_FLOAT64_C(   585.00), SIMDE_FLOAT64_C(   982.34), SIMDE_FLOAT64_C(    -2.22), SIMDE_FLOAT64_C(   679.76),
        SIMDE_FLOAT64_C(  -541.93), SIMDE_FLOAT64_C(  -688.32), SIMDE_FLOAT64_C(  -912.59), SIMDE_FLOAT64_C(  -280.44) } },
    { { SIMDE_FLOAT64_C(   733.06), SIMDE_FLOAT64_C(   407.30), SIMDE_FLOAT64_C(   -26.22), SIMDE_FLOAT64_C(   236.89),
        SIMDE_FLOAT64_C(  -265.13), SIMDE_FLOAT64_C(   240.86), SIMDE_FLOAT64_C(  -251.44), SIMDE_FLOAT64_C(   479.62) },
      { SIMDE_FLOAT64_C(  -733.06), SIMDE_FLOAT64_C(  -407.30), SIMDE_FLOAT64_C(    26.22), SIMDE_FLOAT64_C(  -236.89),
        SIMDE_FLOAT64_C(   265.13), SIMDE_FLOAT64_C(  -240.86), SIMDE_FLOAT64_C(   251.44), SIMDE_FLOAT64_C(  -479.62) } },
    { { SIMDE_FLOAT64_C(  -790.29), SIMDE_FLOAT64_C(   487.97), SIMDE_FLOAT64_C(  -734.72), SIMDE_FLOAT64_C(  -375.60),
        SIMDE_FLOAT64_C(   582.38), SIMDE_FLOAT64_C(   356.45), SIMDE_FLOAT64_C(   331.34), SIMDE_FLOAT64_C(  -249.03) },
      { SIMDE_FLOAT64_C(   790.29), SIMDE_FLOAT64_C(  -487.97), SIMDE_FLOAT64_C(   734.72), SIMDE_FLOAT64_C(   375.60),
        SIMDE_FLOAT64_C(  -582.38), SIMDE_FLOAT64_C(  -356.45), SIMDE_FLOAT64_C(  -331.34), SIMDE_FLOAT64_C(   249.03) } }
  };

  for (size_t i = 0 ; i < (sizeof(test_vec) / sizeof(test_vec[0])) ; i++) {
    simde__m512d a = simde_mm512_loadu_pd(test_vec[i].a);
    simde__m512d r = simde_x_mm512_negate_pd(a);
    simde_test_x86_assert_equal_f64x8(r, simde_mm512_loadu_pd(test_vec[i].r), 1);
  }

  return 0;
#else
  fputc('\n', stdout);
  for (int i = 0 ; i < 8 ; i++) {
    simde__m512d a = simde_test_x86_random_f64x8(SIMDE_FLOAT64_C(-1000.0), SIMDE_FLOAT64_C(1000.0));
    simde__m512d r = simde_x_mm512_negate_pd(a);

    simde_test_x86_write_f64x8(2, a, SIMDE_TEST_VEC_POS_FIRST);
    simde_test_x86_write_f64x8(2, r, SIMDE_TEST_VEC_POS_LAST);
  }
  return 1;
#endif
}

SIMDE_TEST_FUNC_LIST_BEGIN
  SIMDE_TEST_FUNC_LIST_ENTRY(x_mm512_negate_ps)
  SIMDE_TEST_FUNC_LIST_ENTRY(x_mm512_negate_pd)
SIMDE_TEST_FUNC_LIST_END

#include <test/x86/avx512/test-avx512-footer.h>
