Coverage Report

Created: 2026-09-07 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/aom/aom_dsp/x86/fwd_txfm_sse2.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
3
 *
4
 * This source code is subject to the terms of the BSD 2 Clause License and
5
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6
 * was not distributed with this source code in the LICENSE file, you can
7
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8
 * Media Patent License 1.0 was not distributed with this source code in the
9
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10
 */
11
12
#ifndef AOM_AOM_DSP_X86_FWD_TXFM_SSE2_H_
13
#define AOM_AOM_DSP_X86_FWD_TXFM_SSE2_H_
14
15
#ifdef __cplusplus
16
extern "C" {
17
#endif
18
19
0
static inline __m128i k_madd_epi32(__m128i a, __m128i b) {
20
0
  __m128i buf0, buf1;
21
0
  buf0 = _mm_mul_epu32(a, b);
22
0
  a = _mm_srli_epi64(a, 32);
23
0
  b = _mm_srli_epi64(b, 32);
24
0
  buf1 = _mm_mul_epu32(a, b);
25
0
  return _mm_add_epi64(buf0, buf1);
26
0
}
27
28
0
static inline __m128i k_packs_epi64(__m128i a, __m128i b) {
29
0
  __m128i buf0 = _mm_shuffle_epi32(a, _MM_SHUFFLE(0, 0, 2, 0));
30
0
  __m128i buf1 = _mm_shuffle_epi32(b, _MM_SHUFFLE(0, 0, 2, 0));
31
0
  return _mm_unpacklo_epi64(buf0, buf1);
32
0
}
33
34
static inline int check_epi16_overflow_x2(const __m128i *preg0,
35
0
                                          const __m128i *preg1) {
36
0
  const __m128i max_overflow = _mm_set1_epi16(0x7fff);
37
0
  const __m128i min_overflow = _mm_set1_epi16((short)0x8000);
38
0
  __m128i cmp0 = _mm_or_si128(_mm_cmpeq_epi16(*preg0, max_overflow),
39
0
                              _mm_cmpeq_epi16(*preg0, min_overflow));
40
0
  __m128i cmp1 = _mm_or_si128(_mm_cmpeq_epi16(*preg1, max_overflow),
41
0
                              _mm_cmpeq_epi16(*preg1, min_overflow));
42
0
  cmp0 = _mm_or_si128(cmp0, cmp1);
43
0
  return _mm_movemask_epi8(cmp0);
44
0
}
45
46
static inline int check_epi16_overflow_x4(const __m128i *preg0,
47
                                          const __m128i *preg1,
48
                                          const __m128i *preg2,
49
0
                                          const __m128i *preg3) {
50
0
  const __m128i max_overflow = _mm_set1_epi16(0x7fff);
51
0
  const __m128i min_overflow = _mm_set1_epi16((short)0x8000);
52
0
  __m128i cmp0 = _mm_or_si128(_mm_cmpeq_epi16(*preg0, max_overflow),
53
0
                              _mm_cmpeq_epi16(*preg0, min_overflow));
54
0
  __m128i cmp1 = _mm_or_si128(_mm_cmpeq_epi16(*preg1, max_overflow),
55
0
                              _mm_cmpeq_epi16(*preg1, min_overflow));
56
0
  __m128i cmp2 = _mm_or_si128(_mm_cmpeq_epi16(*preg2, max_overflow),
57
0
                              _mm_cmpeq_epi16(*preg2, min_overflow));
58
0
  __m128i cmp3 = _mm_or_si128(_mm_cmpeq_epi16(*preg3, max_overflow),
59
0
                              _mm_cmpeq_epi16(*preg3, min_overflow));
60
0
  cmp0 = _mm_or_si128(_mm_or_si128(cmp0, cmp1), _mm_or_si128(cmp2, cmp3));
61
0
  return _mm_movemask_epi8(cmp0);
62
0
}
63
64
static inline int check_epi16_overflow_x8(
65
    const __m128i *preg0, const __m128i *preg1, const __m128i *preg2,
66
    const __m128i *preg3, const __m128i *preg4, const __m128i *preg5,
67
0
    const __m128i *preg6, const __m128i *preg7) {
68
0
  int res0, res1;
69
0
  res0 = check_epi16_overflow_x4(preg0, preg1, preg2, preg3);
70
0
  res1 = check_epi16_overflow_x4(preg4, preg5, preg6, preg7);
71
0
  return res0 + res1;
72
0
}
73
74
static inline int check_epi16_overflow_x12(
75
    const __m128i *preg0, const __m128i *preg1, const __m128i *preg2,
76
    const __m128i *preg3, const __m128i *preg4, const __m128i *preg5,
77
    const __m128i *preg6, const __m128i *preg7, const __m128i *preg8,
78
0
    const __m128i *preg9, const __m128i *preg10, const __m128i *preg11) {
79
0
  int res0, res1;
80
0
  res0 = check_epi16_overflow_x4(preg0, preg1, preg2, preg3);
81
0
  res1 = check_epi16_overflow_x4(preg4, preg5, preg6, preg7);
82
0
  if (!res0) res0 = check_epi16_overflow_x4(preg8, preg9, preg10, preg11);
83
0
  return res0 + res1;
84
0
}
85
86
static inline int check_epi16_overflow_x16(
87
    const __m128i *preg0, const __m128i *preg1, const __m128i *preg2,
88
    const __m128i *preg3, const __m128i *preg4, const __m128i *preg5,
89
    const __m128i *preg6, const __m128i *preg7, const __m128i *preg8,
90
    const __m128i *preg9, const __m128i *preg10, const __m128i *preg11,
91
    const __m128i *preg12, const __m128i *preg13, const __m128i *preg14,
92
0
    const __m128i *preg15) {
93
0
  int res0, res1;
94
0
  res0 = check_epi16_overflow_x4(preg0, preg1, preg2, preg3);
95
0
  res1 = check_epi16_overflow_x4(preg4, preg5, preg6, preg7);
96
0
  if (!res0) {
97
0
    res0 = check_epi16_overflow_x4(preg8, preg9, preg10, preg11);
98
0
    if (!res1) res1 = check_epi16_overflow_x4(preg12, preg13, preg14, preg15);
99
0
  }
100
0
  return res0 + res1;
101
0
}
102
103
static inline int check_epi16_overflow_x32(
104
    const __m128i *preg0, const __m128i *preg1, const __m128i *preg2,
105
    const __m128i *preg3, const __m128i *preg4, const __m128i *preg5,
106
    const __m128i *preg6, const __m128i *preg7, const __m128i *preg8,
107
    const __m128i *preg9, const __m128i *preg10, const __m128i *preg11,
108
    const __m128i *preg12, const __m128i *preg13, const __m128i *preg14,
109
    const __m128i *preg15, const __m128i *preg16, const __m128i *preg17,
110
    const __m128i *preg18, const __m128i *preg19, const __m128i *preg20,
111
    const __m128i *preg21, const __m128i *preg22, const __m128i *preg23,
112
    const __m128i *preg24, const __m128i *preg25, const __m128i *preg26,
113
    const __m128i *preg27, const __m128i *preg28, const __m128i *preg29,
114
0
    const __m128i *preg30, const __m128i *preg31) {
115
0
  int res0, res1;
116
0
  res0 = check_epi16_overflow_x4(preg0, preg1, preg2, preg3);
117
0
  res1 = check_epi16_overflow_x4(preg4, preg5, preg6, preg7);
118
0
  if (!res0) {
119
0
    res0 = check_epi16_overflow_x4(preg8, preg9, preg10, preg11);
120
0
    if (!res1) {
121
0
      res1 = check_epi16_overflow_x4(preg12, preg13, preg14, preg15);
122
0
      if (!res0) {
123
0
        res0 = check_epi16_overflow_x4(preg16, preg17, preg18, preg19);
124
0
        if (!res1) {
125
0
          res1 = check_epi16_overflow_x4(preg20, preg21, preg22, preg23);
126
0
          if (!res0) {
127
0
            res0 = check_epi16_overflow_x4(preg24, preg25, preg26, preg27);
128
0
            if (!res1)
129
0
              res1 = check_epi16_overflow_x4(preg28, preg29, preg30, preg31);
130
0
          }
131
0
        }
132
0
      }
133
0
    }
134
0
  }
135
0
  return res0 + res1;
136
0
}
137
138
0
static inline void store_output(const __m128i *poutput, tran_low_t *dst_ptr) {
139
0
  const __m128i zero = _mm_setzero_si128();
140
0
  const __m128i sign_bits = _mm_cmplt_epi16(*poutput, zero);
141
0
  __m128i out0 = _mm_unpacklo_epi16(*poutput, sign_bits);
142
0
  __m128i out1 = _mm_unpackhi_epi16(*poutput, sign_bits);
143
0
  _mm_store_si128((__m128i *)(dst_ptr), out0);
144
0
  _mm_store_si128((__m128i *)(dst_ptr + 4), out1);
145
0
}
146
147
0
static inline void storeu_output(const __m128i *poutput, tran_low_t *dst_ptr) {
148
0
  const __m128i zero = _mm_setzero_si128();
149
0
  const __m128i sign_bits = _mm_cmplt_epi16(*poutput, zero);
150
0
  __m128i out0 = _mm_unpacklo_epi16(*poutput, sign_bits);
151
0
  __m128i out1 = _mm_unpackhi_epi16(*poutput, sign_bits);
152
0
  _mm_storeu_si128((__m128i *)(dst_ptr), out0);
153
0
  _mm_storeu_si128((__m128i *)(dst_ptr + 4), out1);
154
0
}
155
156
#ifdef __cplusplus
157
}  // extern "C"
158
#endif
159
160
#endif  // AOM_AOM_DSP_X86_FWD_TXFM_SSE2_H_