/**
 * vec - a tiny SIMD vector library in C99
 * 
 * Copyright (c) 2024-2025 Paper
 * 
 * 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.
**/

#ifndef VEC_IMPL_X86_AVX512BW_H_
#define VEC_IMPL_X86_AVX512BW_H_

#define VEC_AVX512BW_OP(SIGN, BITS, SIZE, INTLSIGN, SECONDSIGN, OP, NAME) \
	VEC_FUNC_IMPL v##SIGN##int##BITS##x##SIZE v##SIGN##int##BITS##x##SIZE##_##NAME(v##SIGN##int##BITS##x##SIZE vec1, v##SECONDSIGN##int##BITS##x##SIZE vec2) \
	{ \
		vec1.avx512f = _mm512_##OP##_ep##INTLSIGN##BITS(vec1.avx512f, vec2.avx512f); \
	\
		return vec1; \
	}

/* -- 8x64 */

#ifndef VINT8x64_MIN_DEFINED
VEC_AVX512BW_OP(, 8, 64, i, , min, min)
# define VINT8x64_MIN_DEFINED
#endif

#ifndef VINT8x64_MAX_DEFINED
VEC_AVX512BW_OP(, 8, 64, i, , max, max)
# define VINT8x64_MAX_DEFINED
#endif

#ifndef VINT8x64_ADD_DEFINED
VEC_AVX512BW_OP(, 8, 64, i, , add, add)
# define VINT8x64_ADD_DEFINED
#endif

#ifndef VINT8x64_SUB_DEFINED
VEC_AVX512BW_OP(, 8, 64, i, , sub, sub)
# define VINT8x64_SUB_DEFINED
#endif

/* -- unsigned */

#ifndef VINT8x64_MIN_DEFINED
VEC_AVX512BW_OP(u, 8, 64, u, u, min, min)
# define VINT8x64_MIN_DEFINED
#endif

#ifndef VINT8x64_MAX_DEFINED
VEC_AVX512BW_OP(u, 8, 64, u, u, max, max)
# define VINT8x64_MAX_DEFINED
#endif

#ifndef VINT8x64_ADD_DEFINED
VEC_AVX512BW_OP(u, 8, 64, i, u, add, add)
# define VINT8x64_ADD_DEFINED
#endif

#ifndef VINT8x64_SUB_DEFINED
VEC_AVX512BW_OP(u, 8, 64, i, u, sub, sub)
# define VINT8x64_SUB_DEFINED
#endif

/* -- 16x32 */

#ifndef VINT16x32_MIN_DEFINED
VEC_AVX512BW_OP(, 16, 32, i, , min, min)
# define VINT16x32_MIN_DEFINED
#endif

#ifndef VINT16x32_MAX_DEFINED
VEC_AVX512BW_OP(, 16, 32, i, , max, max)
# define VINT16x32_MAX_DEFINED
#endif

#ifndef VINT16x32_ADD_DEFINED
VEC_AVX512BW_OP(, 16, 32, i, , add, add)
# define VINT16x32_ADD_DEFINED
#endif

#ifndef VINT16x32_SUB_DEFINED
VEC_AVX512BW_OP(, 16, 32, i, , sub, sub)
# define VINT16x32_SUB_DEFINED
#endif

#ifndef VINT16x32_MUL_DEFINED
VEC_AVX512BW_OP(, 16, 32, i, , mullo, mul)
# define VINT16x32_MUL_DEFINED
#endif

#ifndef VINT16x32_LSHIFT_DEFINED
VEC_AVX512BW_OP(, 16, 32, i, u, sllv, lshift)
# define VINT16x32_LSHIFT_DEFINED
#endif

#ifndef VINT16x32_RSHIFT_DEFINED
VEC_AVX512BW_OP(, 16, 32, i, u, srav, rshift)
# define VINT16x32_RSHIFT_DEFINED
#endif

#ifndef VINT16x32_LRSHIFT_DEFINED
VEC_AVX512BW_OP(, 16, 32, i, u, srlv, lrshift)
# define VINT16x32_LRSHIFT_DEFINED
#endif

/* -- unsigned */

#ifndef VUINT16x32_MIN_DEFINED
VEC_AVX512BW_OP(u, 16, 32, u, u, min, min)
# define VUINT16x32_MIN_DEFINED
#endif

#ifndef VUINT16x32_MAX_DEFINED
VEC_AVX512BW_OP(u, 16, 32, u, u, max, max)
# define VUINT16x32_MAX_DEFINED
#endif

#ifndef VUINT16x32_ADD_DEFINED
VEC_AVX512BW_OP(u, 16, 32, i, u, add, add)
# define VUINT16x32_ADD_DEFINED
#endif

#ifndef VUINT16x32_SUB_DEFINED
VEC_AVX512BW_OP(u, 16, 32, i, u, sub, sub)
# define VUINT16x32_SUB_DEFINED
#endif

#ifndef VUINT16x32_MUL_DEFINED
VEC_AVX512BW_OP(u, 16, 32, i, u, mullo, mul)
# define VUINT16x32_MUL_DEFINED
#endif

#ifndef VUINT16x32_LSHIFT_DEFINED
VEC_AVX512BW_OP(u, 16, 32, i, u, sllv, lshift)
# define VUINT16x32_LSHIFT_DEFINED
#endif

#ifndef VUINT16x32_RSHIFT_DEFINED
VEC_AVX512BW_OP(u, 16, 32, i, u, srlv, rshift)
# define VUINT16x32_RSHIFT_DEFINED
#endif

#ifndef VUINT16x32_LRSHIFT_DEFINED
VEC_AVX512BW_OP(u, 16, 32, i, u, srlv, lrshift)
# define VUINT16x32_LRSHIFT_DEFINED
#endif

/* no mul for 8-bit */

#endif /* VEC_IMPL_X86_AVX512BW_H_ */