Mercurial > vec
diff src/impl/x86/mmx.c @ 31:bf6ad516f1e6
Backed out changeset c6c99ab1088a
author | Paper <paper@tflc.us> |
---|---|
date | Fri, 25 Apr 2025 17:40:33 -0400 |
parents | c6c99ab1088a |
children | 99e4539f922f |
line wrap: on
line diff
--- a/src/impl/x86/mmx.c Fri Apr 25 17:40:30 2025 -0400 +++ b/src/impl/x86/mmx.c Fri Apr 25 17:40:33 2025 -0400 @@ -24,67 +24,46 @@ #include "vec/vec.h" #include "vec/impl/x86/mmx.h" +#include "vec/impl/generic.h" #include <mmintrin.h> #include <string.h> -/* ------------------------------------------------------------------------ */ +#define VEC_MMX_OPERATION_8x8(op, sign) \ + do { \ + /* unpack and multiply */ \ + union v##sign##int8x8_impl_data *vec1d = (union v##sign##int8x8_impl_data *)&vec1; \ + union v##sign##int8x8_impl_data *vec2d = (union v##sign##int8x8_impl_data *)&vec2; \ + \ + __m64 dst_even = _mm_##op##_pi16(vec1d->mmx, vec2d->mmx); \ + __m64 dst_odd = _mm_##op##_pi16(_mm_srli_pi16(vec1d->mmx, 8), _mm_srli_pi16(vec2d->mmx, 8)); \ + \ + /* repack */ \ + vec1d->mmx = _mm_or_si64( \ + _mm_slli_pi16(dst_odd, 8), \ + _mm_srli_pi16(_mm_slli_pi16(dst_even, 8), 8) \ + ); \ + return vec1d->vec; \ + } while (0) -#define VEC_MMX_MUL_8x8(sign) /* nothing */ +// shared between MMX variations +#define VEC_MMX_MUL_8x8(sign) \ + VEC_MMX_OPERATION_8x8(mullo, sign) + #define VEC_MMX_MUL_16x4(sign) \ - VEC_FUNC_IMPL v##sign##int16x4 v##sign##int16x4_mmx_mul(v##sign##int16x4 vec1, v##sign##int16x4 vec2) \ - { \ + do { \ union v##sign##int16x4_impl_data *vec1d = (union v##sign##int16x4_impl_data *)&vec1; \ union vuint16x4_impl_data *vec2d = (union vuint16x4_impl_data *)&vec2; \ \ vec1d->mmx = _mm_mullo_pi16(vec1d->mmx, vec2d->mmx); \ return vec1d->vec; \ - } -#define VEC_MMX_MUL_32x2(sign) /* nothing */ - -#define VEC_MMX_STRUCT_MUL_8x8(sign) NULL -#define VEC_MMX_STRUCT_MUL_16x4(sign) v##sign##int16x4_mmx_mul -#define VEC_MMX_STRUCT_MUL_32x8(sign) NULL - -/* ------------------------------------------------------------------------ */ -/* comparison */ + } while (0) -/* helper funcs */ -#define VEC_xMMX_CMP(name, op, sign, bits, size, first, second, VARS, TRANS1, TRANS2) \ - VEC_FUNC_IMPL v##sign##int##bits##x##size v##sign##int##bits##x##size##_mmx_##name(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ - { \ - union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ - union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ - VARS \ - \ - TRANS1 \ - \ - vec1d->mmx = _mm_##op##_pi##bits(vec##first##d->mmx, vec##second##d->mmx); \ - \ - TRANS2 \ - \ - return vec1d->vec; \ - } - -#define VEC_MMX_CMP(name, op, bits, size, first, second) \ - VEC_xMMX_CMP(name, op, /* nothing */, bits, size, first, second, /* nothing */, /* nothing */, /* nothing */) - -#define VEC_uMMX_CMP(name, op, bits, size, first, second) \ - VEC_xMMX_CMP(name, op, u, bits, size, first, second, \ - __m64 xor_val = _mm_set1_pi##bits(1u << (bits - 1)); \ - , { \ - vec1d->mmx = _mm_xor_si64(vec1d->mmx, xor_val); \ - vec2d->mmx = _mm_xor_si64(vec2d->mmx, xor_val); \ - }, \ - { \ - /* nothing */ \ - }) - -#define VEC_MMX_CMPEQ(sign, bits, size) VEC_xMMX_CMP(cmpeq, cmpeq, sign, bits, size, 1, 2, , ,) -#define VEC_MMX_CMPLT(sign, bits, size) VEC_##sign##MMX_CMP(cmplt, cmpgt, bits, size, 2, 1) -#define VEC_MMX_CMPGT(sign, bits, size) VEC_##sign##MMX_CMP(cmpgt, cmpgt, bits, size, 1, 2) - -/* ------------------------------------------------------------------------ */ +#define VEC_MMX_MUL_32x2(sign) \ + /* TODO implement this for real */ \ + do { \ + return v##sign##int32x2_generic_mul(vec1, vec2); \ + } while (0) #define VEC_MMX_DEFINE_OPERATIONS_SIGN(sign, bits, size) \ union v##sign##int##bits##x##size##_impl_data { \ @@ -95,19 +74,19 @@ VEC_STATIC_ASSERT(VEC_ALIGNOF(__m64) <= VEC_ALIGNOF(v##sign##int##bits##x##size), "vec: v" #sign "int" #bits "x" #size " alignment needs to be expanded to fit intrinsic type size"); \ VEC_STATIC_ASSERT(sizeof(__m64) <= sizeof(v##sign##int##bits##x##size), "vec: v" #sign "int" #bits "x" #size " needs to be expanded to fit intrinsic type size"); \ \ - VEC_FUNC_IMPL v##sign##int##bits##x##size v##sign##int##bits##x##size##_mmx_load_aligned(const vec_##sign##int##bits in[size]) \ + static v##sign##int##bits##x##size v##sign##int##bits##x##size##_mmx_load_aligned(const vec_##sign##int##bits in[size]) \ { \ v##sign##int##bits##x##size vec; \ memcpy(&vec, in, sizeof(vec)); \ return vec; \ } \ \ - VEC_FUNC_IMPL void v##sign##int##bits##x##size##_mmx_store_aligned(v##sign##int##bits##x##size vec, vec_##sign##int##bits out[size]) \ + static void v##sign##int##bits##x##size##_mmx_store_aligned(v##sign##int##bits##x##size vec, vec_##sign##int##bits out[size]) \ { \ memcpy(out, &vec, sizeof(vec)); \ } \ \ - VEC_FUNC_IMPL v##sign##int##bits##x##size v##sign##int##bits##x##size##_mmx_add(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ + static v##sign##int##bits##x##size v##sign##int##bits##x##size##_mmx_add(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ { \ union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ @@ -117,7 +96,7 @@ return vec1d->vec; \ } \ \ - VEC_FUNC_IMPL v##sign##int##bits##x##size v##sign##int##bits##x##size##_mmx_sub(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ + static v##sign##int##bits##x##size v##sign##int##bits##x##size##_mmx_sub(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ { \ union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ @@ -127,9 +106,12 @@ return vec1d->vec; \ } \ \ - VEC_MMX_MUL_##bits##x##size(sign) \ + static v##sign##int##bits##x##size v##sign##int##bits##x##size##_mmx_mul(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ + { \ + VEC_MMX_MUL_##bits##x##size(sign); \ + } \ \ - VEC_FUNC_IMPL v##sign##int##bits##x##size v##sign##int##bits##x##size##_mmx_and(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ + static v##sign##int##bits##x##size v##sign##int##bits##x##size##_mmx_and(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ { \ union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ @@ -139,7 +121,7 @@ return vec1d->vec; \ } \ \ - VEC_FUNC_IMPL v##sign##int##bits##x##size v##sign##int##bits##x##size##_mmx_or(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ + static v##sign##int##bits##x##size v##sign##int##bits##x##size##_mmx_or(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ { \ union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ @@ -149,7 +131,7 @@ return vec1d->vec; \ } \ \ - VEC_FUNC_IMPL v##sign##int##bits##x##size v##sign##int##bits##x##size##_mmx_xor(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ + static v##sign##int##bits##x##size v##sign##int##bits##x##size##_mmx_xor(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ { \ union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ @@ -159,22 +141,29 @@ return vec1d->vec; \ } \ \ - VEC_MMX_CMPEQ(sign, bits, size) \ - VEC_MMX_CMPLT(sign, bits, size) \ - VEC_MMX_CMPGT(sign, bits, size) \ - \ const v##sign##int##bits##x##size##_impl v##sign##int##bits##x##size##_impl_mmx = { \ - .load_aligned = v##sign##int##bits##x##size##_mmx_load_aligned, \ - .load = v##sign##int##bits##x##size##_mmx_load_aligned, \ - .store_aligned = v##sign##int##bits##x##size##_mmx_store_aligned, \ - .store = v##sign##int##bits##x##size##_mmx_store_aligned, \ - .add = v##sign##int##bits##x##size##_mmx_add, \ - .sub = v##sign##int##bits##x##size##_mmx_sub, \ - .mul = VEC_MMX_STRUCT_MUL_8x8(sign), \ - .band = v##sign##int##bits##x##size##_mmx_and, \ - .bor = v##sign##int##bits##x##size##_mmx_or, \ - .bxor = v##sign##int##bits##x##size##_mmx_xor, \ - .cmpeq = v##sign##int##bits##x##size##_mmx_cmpeq, \ + v##sign##int##bits##x##size##_generic_splat, \ + v##sign##int##bits##x##size##_mmx_load_aligned, \ + v##sign##int##bits##x##size##_mmx_load_aligned, \ + v##sign##int##bits##x##size##_mmx_store_aligned, \ + v##sign##int##bits##x##size##_mmx_store_aligned, \ + v##sign##int##bits##x##size##_mmx_add, \ + v##sign##int##bits##x##size##_mmx_sub, \ + v##sign##int##bits##x##size##_mmx_mul, \ + v##sign##int##bits##x##size##_generic_div, \ + v##sign##int##bits##x##size##_generic_avg, \ + v##sign##int##bits##x##size##_mmx_and, \ + v##sign##int##bits##x##size##_mmx_or, \ + v##sign##int##bits##x##size##_mmx_xor, \ + v##sign##int##bits##x##size##_generic_not, \ + v##sign##int##bits##x##size##_generic_lshift, \ + v##sign##int##bits##x##size##_generic_rshift, \ + v##sign##int##bits##x##size##_generic_lrshift, \ + v##sign##int##bits##x##size##_generic_cmplt, \ + v##sign##int##bits##x##size##_generic_cmple, \ + v##sign##int##bits##x##size##_generic_cmpeq, \ + v##sign##int##bits##x##size##_generic_cmpge, \ + v##sign##int##bits##x##size##_generic_cmpgt, \ }; #define VEC_MMX_DEFINE_OPERATIONS(bits, size) \