#ifndef SSE2NEONTEST_H
#define SSE2NEONTEST_H
#include "common.h"
#define ENUM(c) it_##c,
#define STR(c) #c,
#define CASE(c)                   \
    case it_##c:                  \
        ret = test_##c(*this, i); \
        break;
#define INTRIN_FOREACH(TYPE)         \
    /* MMX */                        \
    TYPE(mm_empty)                   \
    /* SSE */                        \
    TYPE(mm_add_ps)                  \
    TYPE(mm_add_ss)                  \
    TYPE(mm_and_ps)                  \
    TYPE(mm_andnot_ps)               \
    TYPE(mm_avg_pu16)                \
    TYPE(mm_avg_pu8)                 \
    TYPE(mm_cmpeq_ps)                \
    TYPE(mm_cmpeq_ss)                \
    TYPE(mm_cmpge_ps)                \
    TYPE(mm_cmpge_ss)                \
    TYPE(mm_cmpgt_ps)                \
    TYPE(mm_cmpgt_ss)                \
    TYPE(mm_cmple_ps)                \
    TYPE(mm_cmple_ss)                \
    TYPE(mm_cmplt_ps)                \
    TYPE(mm_cmplt_ss)                \
    TYPE(mm_cmpneq_ps)               \
    TYPE(mm_cmpneq_ss)               \
    TYPE(mm_cmpnge_ps)               \
    TYPE(mm_cmpnge_ss)               \
    TYPE(mm_cmpngt_ps)               \
    TYPE(mm_cmpngt_ss)               \
    TYPE(mm_cmpnle_ps)               \
    TYPE(mm_cmpnle_ss)               \
    TYPE(mm_cmpnlt_ps)               \
    TYPE(mm_cmpnlt_ss)               \
    TYPE(mm_cmpord_ps)               \
    TYPE(mm_cmpord_ss)               \
    TYPE(mm_cmpunord_ps)             \
    TYPE(mm_cmpunord_ss)             \
    TYPE(mm_comieq_ss)               \
    TYPE(mm_comige_ss)               \
    TYPE(mm_comigt_ss)               \
    TYPE(mm_comile_ss)               \
    TYPE(mm_comilt_ss)               \
    TYPE(mm_comineq_ss)              \
    TYPE(mm_cvt_pi2ps)               \
    TYPE(mm_cvt_ps2pi)               \
    TYPE(mm_cvt_si2ss)               \
    TYPE(mm_cvt_ss2si)               \
    TYPE(mm_cvtpi16_ps)              \
    TYPE(mm_cvtpi32_ps)              \
    TYPE(mm_cvtpi32x2_ps)            \
    TYPE(mm_cvtpi8_ps)               \
    TYPE(mm_cvtps_pi16)              \
    TYPE(mm_cvtps_pi32)              \
    TYPE(mm_cvtps_pi8)               \
    TYPE(mm_cvtpu16_ps)              \
    TYPE(mm_cvtpu8_ps)               \
    TYPE(mm_cvtsi32_ss)              \
    TYPE(mm_cvtsi64_ss)              \
    TYPE(mm_cvtss_f32)               \
    TYPE(mm_cvtss_si32)              \
    TYPE(mm_cvtss_si64)              \
    TYPE(mm_cvtt_ps2pi)              \
    TYPE(mm_cvtt_ss2si)              \
    TYPE(mm_cvttps_pi32)             \
    TYPE(mm_cvttss_si32)             \
    TYPE(mm_cvttss_si64)             \
    TYPE(mm_div_ps)                  \
    TYPE(mm_div_ss)                  \
    TYPE(mm_extract_pi16)            \
    TYPE(mm_free)                    \
    TYPE(mm_get_flush_zero_mode)     \
    TYPE(mm_get_rounding_mode)       \
    TYPE(mm_getcsr)                  \
    TYPE(mm_insert_pi16)             \
    TYPE(mm_load_ps)                 \
    TYPE(mm_load_ps1)                \
    TYPE(mm_load_ss)                 \
    TYPE(mm_load1_ps)                \
    TYPE(mm_loadh_pi)                \
    TYPE(mm_loadl_pi)                \
    TYPE(mm_loadr_ps)                \
    TYPE(mm_loadu_ps)                \
    TYPE(mm_loadu_si16)              \
    TYPE(mm_loadu_si64)              \
    TYPE(mm_malloc)                  \
    TYPE(mm_maskmove_si64)           \
    TYPE(m_maskmovq)                 \
    TYPE(mm_max_pi16)                \
    TYPE(mm_max_ps)                  \
    TYPE(mm_max_pu8)                 \
    TYPE(mm_max_ss)                  \
    TYPE(mm_min_pi16)                \
    TYPE(mm_min_ps)                  \
    TYPE(mm_min_pu8)                 \
    TYPE(mm_min_ss)                  \
    TYPE(mm_move_ss)                 \
    TYPE(mm_movehl_ps)               \
    TYPE(mm_movelh_ps)               \
    TYPE(mm_movemask_pi8)            \
    TYPE(mm_movemask_ps)             \
    TYPE(mm_mul_ps)                  \
    TYPE(mm_mul_ss)                  \
    TYPE(mm_mulhi_pu16)              \
    TYPE(mm_or_ps)                   \
    TYPE(m_pavgb)                    \
    TYPE(m_pavgw)                    \
    TYPE(m_pextrw)                   \
    TYPE(m_pinsrw)                   \
    TYPE(m_pmaxsw)                   \
    TYPE(m_pmaxub)                   \
    TYPE(m_pminsw)                   \
    TYPE(m_pminub)                   \
    TYPE(m_pmovmskb)                 \
    TYPE(m_pmulhuw)                  \
    TYPE(mm_prefetch)                \
    TYPE(m_psadbw)                   \
    TYPE(m_pshufw)                   \
    TYPE(mm_rcp_ps)                  \
    TYPE(mm_rcp_ss)                  \
    TYPE(mm_rsqrt_ps)                \
    TYPE(mm_rsqrt_ss)                \
    TYPE(mm_sad_pu8)                 \
    TYPE(mm_set_flush_zero_mode)     \
    TYPE(mm_set_ps)                  \
    TYPE(mm_set_ps1)                 \
    TYPE(mm_set_rounding_mode)       \
    TYPE(mm_set_ss)                  \
    TYPE(mm_set1_ps)                 \
    TYPE(mm_setcsr)                  \
    TYPE(mm_setr_ps)                 \
    TYPE(mm_setzero_ps)              \
    TYPE(mm_sfence)                  \
    TYPE(mm_shuffle_pi16)            \
    TYPE(mm_shuffle_ps)              \
    TYPE(mm_sqrt_ps)                 \
    TYPE(mm_sqrt_ss)                 \
    TYPE(mm_store_ps)                \
    TYPE(mm_store_ps1)               \
    TYPE(mm_store_ss)                \
    TYPE(mm_store1_ps)               \
    TYPE(mm_storeh_pi)               \
    TYPE(mm_storel_pi)               \
    TYPE(mm_storer_ps)               \
    TYPE(mm_storeu_ps)               \
    TYPE(mm_storeu_si16)             \
    TYPE(mm_storeu_si64)             \
    TYPE(mm_stream_pi)               \
    TYPE(mm_stream_ps)               \
    TYPE(mm_sub_ps)                  \
    TYPE(mm_sub_ss)                  \
    TYPE(mm_ucomieq_ss)              \
    TYPE(mm_ucomige_ss)              \
    TYPE(mm_ucomigt_ss)              \
    TYPE(mm_ucomile_ss)              \
    TYPE(mm_ucomilt_ss)              \
    TYPE(mm_ucomineq_ss)             \
    TYPE(mm_undefined_ps)            \
    TYPE(mm_unpackhi_ps)             \
    TYPE(mm_unpacklo_ps)             \
    TYPE(mm_xor_ps)                  \
    /* SSE2 */                       \
    TYPE(mm_add_epi16)               \
    TYPE(mm_add_epi32)               \
    TYPE(mm_add_epi64)               \
    TYPE(mm_add_epi8)                \
    TYPE(mm_add_pd)                  \
    TYPE(mm_add_sd)                  \
    TYPE(mm_add_si64)                \
    TYPE(mm_adds_epi16)              \
    TYPE(mm_adds_epi8)               \
    TYPE(mm_adds_epu16)              \
    TYPE(mm_adds_epu8)               \
    TYPE(mm_and_pd)                  \
    TYPE(mm_and_si128)               \
    TYPE(mm_andnot_pd)               \
    TYPE(mm_andnot_si128)            \
    TYPE(mm_avg_epu16)               \
    TYPE(mm_avg_epu8)                \
    TYPE(mm_bslli_si128)             \
    TYPE(mm_bsrli_si128)             \
    TYPE(mm_castpd_ps)               \
    TYPE(mm_castpd_si128)            \
    TYPE(mm_castps_pd)               \
    TYPE(mm_castps_si128)            \
    TYPE(mm_castsi128_pd)            \
    TYPE(mm_castsi128_ps)            \
    TYPE(mm_clflush)                 \
    TYPE(mm_cmpeq_epi16)             \
    TYPE(mm_cmpeq_epi32)             \
    TYPE(mm_cmpeq_epi8)              \
    TYPE(mm_cmpeq_pd)                \
    TYPE(mm_cmpeq_sd)                \
    TYPE(mm_cmpge_pd)                \
    TYPE(mm_cmpge_sd)                \
    TYPE(mm_cmpgt_epi16)             \
    TYPE(mm_cmpgt_epi32)             \
    TYPE(mm_cmpgt_epi8)              \
    TYPE(mm_cmpgt_pd)                \
    TYPE(mm_cmpgt_sd)                \
    TYPE(mm_cmple_pd)                \
    TYPE(mm_cmple_sd)                \
    TYPE(mm_cmplt_epi16)             \
    TYPE(mm_cmplt_epi32)             \
    TYPE(mm_cmplt_epi8)              \
    TYPE(mm_cmplt_pd)                \
    TYPE(mm_cmplt_sd)                \
    TYPE(mm_cmpneq_pd)               \
    TYPE(mm_cmpneq_sd)               \
    TYPE(mm_cmpnge_pd)               \
    TYPE(mm_cmpnge_sd)               \
    TYPE(mm_cmpngt_pd)               \
    TYPE(mm_cmpngt_sd)               \
    TYPE(mm_cmpnle_pd)               \
    TYPE(mm_cmpnle_sd)               \
    TYPE(mm_cmpnlt_pd)               \
    TYPE(mm_cmpnlt_sd)               \
    TYPE(mm_cmpord_pd)               \
    TYPE(mm_cmpord_sd)               \
    TYPE(mm_cmpunord_pd)             \
    TYPE(mm_cmpunord_sd)             \
    TYPE(mm_comieq_sd)               \
    TYPE(mm_comige_sd)               \
    TYPE(mm_comigt_sd)               \
    TYPE(mm_comile_sd)               \
    TYPE(mm_comilt_sd)               \
    TYPE(mm_comineq_sd)              \
    TYPE(mm_cvtepi32_pd)             \
    TYPE(mm_cvtepi32_ps)             \
    TYPE(mm_cvtpd_epi32)             \
    TYPE(mm_cvtpd_pi32)              \
    TYPE(mm_cvtpd_ps)                \
    TYPE(mm_cvtpi32_pd)              \
    TYPE(mm_cvtps_epi32)             \
    TYPE(mm_cvtps_pd)                \
    TYPE(mm_cvtsd_f64)               \
    TYPE(mm_cvtsd_si32)              \
    TYPE(mm_cvtsd_si64)              \
    TYPE(mm_cvtsd_si64x)             \
    TYPE(mm_cvtsd_ss)                \
    TYPE(mm_cvtsi128_si32)           \
    TYPE(mm_cvtsi128_si64)           \
    TYPE(mm_cvtsi128_si64x)          \
    TYPE(mm_cvtsi32_sd)              \
    TYPE(mm_cvtsi32_si128)           \
    TYPE(mm_cvtsi64_sd)              \
    TYPE(mm_cvtsi64_si128)           \
    TYPE(mm_cvtsi64x_sd)             \
    TYPE(mm_cvtsi64x_si128)          \
    TYPE(mm_cvtss_sd)                \
    TYPE(mm_cvttpd_epi32)            \
    TYPE(mm_cvttpd_pi32)             \
    TYPE(mm_cvttps_epi32)            \
    TYPE(mm_cvttsd_si32)             \
    TYPE(mm_cvttsd_si64)             \
    TYPE(mm_cvttsd_si64x)            \
    TYPE(mm_div_pd)                  \
    TYPE(mm_div_sd)                  \
    TYPE(mm_extract_epi16)           \
    TYPE(mm_insert_epi16)            \
    TYPE(mm_lfence)                  \
    TYPE(mm_load_pd)                 \
    TYPE(mm_load_pd1)                \
    TYPE(mm_load_sd)                 \
    TYPE(mm_load_si128)              \
    TYPE(mm_load1_pd)                \
    TYPE(mm_loadh_pd)                \
    TYPE(mm_loadl_epi64)             \
    TYPE(mm_loadl_pd)                \
    TYPE(mm_loadr_pd)                \
    TYPE(mm_loadu_pd)                \
    TYPE(mm_loadu_si128)             \
    TYPE(mm_loadu_si32)              \
    TYPE(mm_madd_epi16)              \
    TYPE(mm_maskmoveu_si128)         \
    TYPE(mm_max_epi16)               \
    TYPE(mm_max_epu8)                \
    TYPE(mm_max_pd)                  \
    TYPE(mm_max_sd)                  \
    TYPE(mm_mfence)                  \
    TYPE(mm_min_epi16)               \
    TYPE(mm_min_epu8)                \
    TYPE(mm_min_pd)                  \
    TYPE(mm_min_sd)                  \
    TYPE(mm_move_epi64)              \
    TYPE(mm_move_sd)                 \
    TYPE(mm_movemask_epi8)           \
    TYPE(mm_movemask_pd)             \
    TYPE(mm_movepi64_pi64)           \
    TYPE(mm_movpi64_epi64)           \
    TYPE(mm_mul_epu32)               \
    TYPE(mm_mul_pd)                  \
    TYPE(mm_mul_sd)                  \
    TYPE(mm_mul_su32)                \
    TYPE(mm_mulhi_epi16)             \
    TYPE(mm_mulhi_epu16)             \
    TYPE(mm_mullo_epi16)             \
    TYPE(mm_or_pd)                   \
    TYPE(mm_or_si128)                \
    TYPE(mm_packs_epi16)             \
    TYPE(mm_packs_epi32)             \
    TYPE(mm_packus_epi16)            \
    TYPE(mm_pause)                   \
    TYPE(mm_sad_epu8)                \
    TYPE(mm_set_epi16)               \
    TYPE(mm_set_epi32)               \
    TYPE(mm_set_epi64)               \
    TYPE(mm_set_epi64x)              \
    TYPE(mm_set_epi8)                \
    TYPE(mm_set_pd)                  \
    TYPE(mm_set_pd1)                 \
    TYPE(mm_set_sd)                  \
    TYPE(mm_set1_epi16)              \
    TYPE(mm_set1_epi32)              \
    TYPE(mm_set1_epi64)              \
    TYPE(mm_set1_epi64x)             \
    TYPE(mm_set1_epi8)               \
    TYPE(mm_set1_pd)                 \
    TYPE(mm_setr_epi16)              \
    TYPE(mm_setr_epi32)              \
    TYPE(mm_setr_epi64)              \
    TYPE(mm_setr_epi8)               \
    TYPE(mm_setr_pd)                 \
    TYPE(mm_setzero_pd)              \
    TYPE(mm_setzero_si128)           \
    TYPE(mm_shuffle_epi32)           \
    TYPE(mm_shuffle_pd)              \
    TYPE(mm_shufflehi_epi16)         \
    TYPE(mm_shufflelo_epi16)         \
    TYPE(mm_sll_epi16)               \
    TYPE(mm_sll_epi32)               \
    TYPE(mm_sll_epi64)               \
    TYPE(mm_slli_epi16)              \
    TYPE(mm_slli_epi32)              \
    TYPE(mm_slli_epi64)              \
    TYPE(mm_slli_si128)              \
    TYPE(mm_sqrt_pd)                 \
    TYPE(mm_sqrt_sd)                 \
    TYPE(mm_sra_epi16)               \
    TYPE(mm_sra_epi32)               \
    TYPE(mm_srai_epi16)              \
    TYPE(mm_srai_epi32)              \
    TYPE(mm_srl_epi16)               \
    TYPE(mm_srl_epi32)               \
    TYPE(mm_srl_epi64)               \
    TYPE(mm_srli_epi16)              \
    TYPE(mm_srli_epi32)              \
    TYPE(mm_srli_epi64)              \
    TYPE(mm_srli_si128)              \
    TYPE(mm_store_pd)                \
    TYPE(mm_store_pd1)               \
    TYPE(mm_store_sd)                \
    TYPE(mm_store_si128)             \
    TYPE(mm_store1_pd)               \
    TYPE(mm_storeh_pd)               \
    TYPE(mm_storel_epi64)            \
    TYPE(mm_storel_pd)               \
    TYPE(mm_storer_pd)               \
    TYPE(mm_storeu_pd)               \
    TYPE(mm_storeu_si128)            \
    TYPE(mm_storeu_si32)             \
    TYPE(mm_stream_pd)               \
    TYPE(mm_stream_si128)            \
    TYPE(mm_stream_si32)             \
    TYPE(mm_stream_si64)             \
    TYPE(mm_sub_epi16)               \
    TYPE(mm_sub_epi32)               \
    TYPE(mm_sub_epi64)               \
    TYPE(mm_sub_epi8)                \
    TYPE(mm_sub_pd)                  \
    TYPE(mm_sub_sd)                  \
    TYPE(mm_sub_si64)                \
    TYPE(mm_subs_epi16)              \
    TYPE(mm_subs_epi8)               \
    TYPE(mm_subs_epu16)              \
    TYPE(mm_subs_epu8)               \
    TYPE(mm_ucomieq_sd)              \
    TYPE(mm_ucomige_sd)              \
    TYPE(mm_ucomigt_sd)              \
    TYPE(mm_ucomile_sd)              \
    TYPE(mm_ucomilt_sd)              \
    TYPE(mm_ucomineq_sd)             \
    TYPE(mm_undefined_pd)            \
    TYPE(mm_undefined_si128)         \
    TYPE(mm_unpackhi_epi16)          \
    TYPE(mm_unpackhi_epi32)          \
    TYPE(mm_unpackhi_epi64)          \
    TYPE(mm_unpackhi_epi8)           \
    TYPE(mm_unpackhi_pd)             \
    TYPE(mm_unpacklo_epi16)          \
    TYPE(mm_unpacklo_epi32)          \
    TYPE(mm_unpacklo_epi64)          \
    TYPE(mm_unpacklo_epi8)           \
    TYPE(mm_unpacklo_pd)             \
    TYPE(mm_xor_pd)                  \
    TYPE(mm_xor_si128)               \
    /* SSE3 */                       \
    TYPE(mm_addsub_pd)               \
    TYPE(mm_addsub_ps)               \
    TYPE(mm_hadd_pd)                 \
    TYPE(mm_hadd_ps)                 \
    TYPE(mm_hsub_pd)                 \
    TYPE(mm_hsub_ps)                 \
    TYPE(mm_lddqu_si128)             \
    TYPE(mm_loaddup_pd)              \
    TYPE(mm_movedup_pd)              \
    TYPE(mm_movehdup_ps)             \
    TYPE(mm_moveldup_ps)             \
    /* SSSE3 */                      \
    TYPE(mm_abs_epi16)               \
    TYPE(mm_abs_epi32)               \
    TYPE(mm_abs_epi8)                \
    TYPE(mm_abs_pi16)                \
    TYPE(mm_abs_pi32)                \
    TYPE(mm_abs_pi8)                 \
    TYPE(mm_alignr_epi8)             \
    TYPE(mm_alignr_pi8)              \
    TYPE(mm_hadd_epi16)              \
    TYPE(mm_hadd_epi32)              \
    TYPE(mm_hadd_pi16)               \
    TYPE(mm_hadd_pi32)               \
    TYPE(mm_hadds_epi16)             \
    TYPE(mm_hadds_pi16)              \
    TYPE(mm_hsub_epi16)              \
    TYPE(mm_hsub_epi32)              \
    TYPE(mm_hsub_pi16)               \
    TYPE(mm_hsub_pi32)               \
    TYPE(mm_hsubs_epi16)             \
    TYPE(mm_hsubs_pi16)              \
    TYPE(mm_maddubs_epi16)           \
    TYPE(mm_maddubs_pi16)            \
    TYPE(mm_mulhrs_epi16)            \
    TYPE(mm_mulhrs_pi16)             \
    TYPE(mm_shuffle_epi8)            \
    TYPE(mm_shuffle_pi8)             \
    TYPE(mm_sign_epi16)              \
    TYPE(mm_sign_epi32)              \
    TYPE(mm_sign_epi8)               \
    TYPE(mm_sign_pi16)               \
    TYPE(mm_sign_pi32)               \
    TYPE(mm_sign_pi8)                \
    /* SSE4.1 */                     \
    TYPE(mm_blend_epi16)             \
    TYPE(mm_blend_pd)                \
    TYPE(mm_blend_ps)                \
    TYPE(mm_blendv_epi8)             \
    TYPE(mm_blendv_pd)               \
    TYPE(mm_blendv_ps)               \
    TYPE(mm_ceil_pd)                 \
    TYPE(mm_ceil_ps)                 \
    TYPE(mm_ceil_sd)                 \
    TYPE(mm_ceil_ss)                 \
    TYPE(mm_cmpeq_epi64)             \
    TYPE(mm_cvtepi16_epi32)          \
    TYPE(mm_cvtepi16_epi64)          \
    TYPE(mm_cvtepi32_epi64)          \
    TYPE(mm_cvtepi8_epi16)           \
    TYPE(mm_cvtepi8_epi32)           \
    TYPE(mm_cvtepi8_epi64)           \
    TYPE(mm_cvtepu16_epi32)          \
    TYPE(mm_cvtepu16_epi64)          \
    TYPE(mm_cvtepu32_epi64)          \
    TYPE(mm_cvtepu8_epi16)           \
    TYPE(mm_cvtepu8_epi32)           \
    TYPE(mm_cvtepu8_epi64)           \
    TYPE(mm_dp_pd)                   \
    TYPE(mm_dp_ps)                   \
    TYPE(mm_extract_epi32)           \
    TYPE(mm_extract_epi64)           \
    TYPE(mm_extract_epi8)            \
    TYPE(mm_extract_ps)              \
    TYPE(mm_floor_pd)                \
    TYPE(mm_floor_ps)                \
    TYPE(mm_floor_sd)                \
    TYPE(mm_floor_ss)                \
    TYPE(mm_insert_epi32)            \
    TYPE(mm_insert_epi64)            \
    TYPE(mm_insert_epi8)             \
    TYPE(mm_insert_ps)               \
    TYPE(mm_max_epi32)               \
    TYPE(mm_max_epi8)                \
    TYPE(mm_max_epu16)               \
    TYPE(mm_max_epu32)               \
    TYPE(mm_min_epi32)               \
    TYPE(mm_min_epi8)                \
    TYPE(mm_min_epu16)               \
    TYPE(mm_min_epu32)               \
    TYPE(mm_minpos_epu16)            \
    TYPE(mm_mpsadbw_epu8)            \
    TYPE(mm_mul_epi32)               \
    TYPE(mm_mullo_epi32)             \
    TYPE(mm_packus_epi32)            \
    TYPE(mm_round_pd)                \
    TYPE(mm_round_ps)                \
    TYPE(mm_round_sd)                \
    TYPE(mm_round_ss)                \
    TYPE(mm_stream_load_si128)       \
    TYPE(mm_test_all_ones)           \
    TYPE(mm_test_all_zeros)          \
    TYPE(mm_test_mix_ones_zeros)     \
    TYPE(mm_testc_si128)             \
    TYPE(mm_testnzc_si128)           \
    TYPE(mm_testz_si128)             \
    /* SSE4.2 */                     \
    TYPE(mm_cmpestra)                \
    TYPE(mm_cmpestrc)                \
    TYPE(mm_cmpestri)                \
    TYPE(mm_cmpestrm)                \
    TYPE(mm_cmpestro)                \
    TYPE(mm_cmpestrs)                \
    TYPE(mm_cmpestrz)                \
    TYPE(mm_cmpgt_epi64)             \
    TYPE(mm_cmpistra)                \
    TYPE(mm_cmpistrc)                \
    TYPE(mm_cmpistri)                \
    TYPE(mm_cmpistrm)                \
    TYPE(mm_cmpistro)                \
    TYPE(mm_cmpistrs)                \
    TYPE(mm_cmpistrz)                \
    TYPE(mm_crc32_u16)               \
    TYPE(mm_crc32_u32)               \
    TYPE(mm_crc32_u64)               \
    TYPE(mm_crc32_u8)                \
    /* AES */                        \
    TYPE(mm_aesenc_si128)            \
    TYPE(mm_aesenclast_si128)        \
    TYPE(mm_aeskeygenassist_si128)   \
    /* Others */                     \
    TYPE(mm_clmulepi64_si128)        \
    TYPE(mm_get_denormals_zero_mode) \
    TYPE(mm_popcnt_u32)              \
    TYPE(mm_popcnt_u64)              \
    TYPE(mm_set_denormals_zero_mode) \
    TYPE(rdtsc)                      \
    TYPE(last) /* This indicates the end of macros */

namespace SSE2NEON
{
// The way unit tests are implemented is that 10,000 random floating point and
// integer vec4 numbers are generated as sample data.
//
// A short C implementation of every intrinsic is implemented and compared to
// the actual expected results from the corresponding SSE intrinsic against all
// of the 10,000 randomized input vectors. When running on ARM, then the results
// are compared to the NEON approximate version.
extern const char *instructionString[];
enum InstructionTest { INTRIN_FOREACH(ENUM) };

class SSE2NEONTest
{
public:
    static SSE2NEONTest *create(void);  // create the test.

    // Run test of this instruction;
    // Passed: TEST_SUCCESS (1)
    // Failed: TEST_FAIL (0)
    // Unimplemented: TEST_UNIMPL (-1)
    virtual result_t runTest(InstructionTest test) = 0;
    virtual void release(void) = 0;
};

}  // namespace SSE2NEON

#endif
