2 * Copyright (c) 2022 The WebM project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
12 #include "./vpx_dsp_rtcd.h"
13 #include "vpx_util/loongson_intrinsics.h"
15 static void copy_width8_lsx(const uint8_t *src, int32_t src_stride,
16 uint8_t *dst, int32_t dst_stride, int32_t height) {
18 uint64_t out0, out1, out2, out3, out4, out5, out6, out7;
19 __m128i src0, src1, src2, src3, src4, src5, src6, src7;
20 int32_t src_stride2 = src_stride << 1;
21 int32_t src_stride3 = src_stride2 + src_stride;
22 int32_t src_stride4 = src_stride2 << 1;
24 if ((height % 12) == 0) {
25 for (cnt = (height / 12); cnt--;) {
26 src0 = __lsx_vld(src, 0);
27 DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3,
28 src, src_stride4, src1, src2, src3, src4);
30 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src5, src6);
32 src7 = __lsx_vldx(src, src_stride);
35 __lsx_vstelm_d(src0, dst, 0, 0);
37 __lsx_vstelm_d(src1, dst, 0, 0);
39 __lsx_vstelm_d(src2, dst, 0, 0);
41 __lsx_vstelm_d(src3, dst, 0, 0);
44 __lsx_vstelm_d(src4, dst, 0, 0);
46 __lsx_vstelm_d(src5, dst, 0, 0);
48 __lsx_vstelm_d(src6, dst, 0, 0);
50 __lsx_vstelm_d(src7, dst, 0, 0);
53 src0 = __lsx_vld(src, 0);
54 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2);
55 src3 = __lsx_vldx(src, src_stride3);
58 __lsx_vstelm_d(src0, dst, 0, 0);
60 __lsx_vstelm_d(src1, dst, 0, 0);
62 __lsx_vstelm_d(src2, dst, 0, 0);
64 __lsx_vstelm_d(src3, dst, 0, 0);
67 } else if ((height % 8) == 0) {
68 for (cnt = height >> 3; cnt--;) {
69 src0 = __lsx_vld(src, 0);
70 DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3,
71 src, src_stride4, src1, src2, src3, src4);
73 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src5, src6);
75 src7 = __lsx_vldx(src, src_stride);
78 __lsx_vstelm_d(src0, dst, 0, 0);
80 __lsx_vstelm_d(src1, dst, 0, 0);
82 __lsx_vstelm_d(src2, dst, 0, 0);
84 __lsx_vstelm_d(src3, dst, 0, 0);
87 __lsx_vstelm_d(src4, dst, 0, 0);
89 __lsx_vstelm_d(src5, dst, 0, 0);
91 __lsx_vstelm_d(src6, dst, 0, 0);
93 __lsx_vstelm_d(src7, dst, 0, 0);
96 } else if ((height % 4) == 0) {
97 for (cnt = (height / 4); cnt--;) {
98 src0 = __lsx_vld(src, 0);
99 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2);
100 src3 = __lsx_vldx(src, src_stride3);
103 __lsx_vstelm_d(src0, dst, 0, 0);
105 __lsx_vstelm_d(src1, dst, 0, 0);
107 __lsx_vstelm_d(src2, dst, 0, 0);
109 __lsx_vstelm_d(src3, dst, 0, 0);
112 } else if ((height % 2) == 0) {
113 for (cnt = (height / 2); cnt--;) {
114 src0 = __lsx_vld(src, 0);
115 src1 = __lsx_vldx(src, src_stride);
118 __lsx_vstelm_d(src0, dst, 0, 0);
120 __lsx_vstelm_d(src1, dst, 0, 0);
126 static void copy_16multx8mult_lsx(const uint8_t *src, int32_t src_stride,
127 uint8_t *dst, int32_t dst_stride,
128 int32_t height, int32_t width) {
129 int32_t cnt, loop_cnt;
132 __m128i src0, src1, src2, src3, src4, src5, src6, src7;
133 int32_t src_stride2 = src_stride << 1;
134 int32_t src_stride3 = src_stride2 + src_stride;
135 int32_t src_stride4 = src_stride2 << 1;
137 for (cnt = (width >> 4); cnt--;) {
138 src_tmp = (uint8_t *)src;
141 for (loop_cnt = (height >> 3); loop_cnt--;) {
142 src0 = __lsx_vld(src_tmp, 0);
143 DUP4_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src_tmp,
144 src_stride3, src_tmp, src_stride4, src1, src2, src3, src4);
145 src_tmp += src_stride4;
146 DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src5,
148 src_tmp += src_stride2;
149 src7 = __lsx_vldx(src_tmp, src_stride);
150 src_tmp += src_stride2;
152 __lsx_vst(src0, dst_tmp, 0);
153 dst_tmp += dst_stride;
154 __lsx_vst(src1, dst_tmp, 0);
155 dst_tmp += dst_stride;
156 __lsx_vst(src2, dst_tmp, 0);
157 dst_tmp += dst_stride;
158 __lsx_vst(src3, dst_tmp, 0);
159 dst_tmp += dst_stride;
160 __lsx_vst(src4, dst_tmp, 0);
161 dst_tmp += dst_stride;
162 __lsx_vst(src5, dst_tmp, 0);
163 dst_tmp += dst_stride;
164 __lsx_vst(src6, dst_tmp, 0);
165 dst_tmp += dst_stride;
166 __lsx_vst(src7, dst_tmp, 0);
167 dst_tmp += dst_stride;
174 static void copy_width16_lsx(const uint8_t *src, int32_t src_stride,
175 uint8_t *dst, int32_t dst_stride, int32_t height) {
177 __m128i src0, src1, src2, src3, src4, src5, src6, src7;
178 int32_t src_stride2 = src_stride << 1;
179 int32_t src_stride3 = src_stride2 + src_stride;
180 int32_t src_stride4 = src_stride2 << 1;
182 if ((height % 12) == 0) {
183 for (cnt = (height / 12); cnt--;) {
184 src0 = __lsx_vld(src, 0);
185 DUP4_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src, src_stride3,
186 src, src_stride4, src1, src2, src3, src4);
188 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src5, src6);
190 src7 = __lsx_vldx(src, src_stride);
193 __lsx_vst(src0, dst, 0);
195 __lsx_vst(src1, dst, 0);
197 __lsx_vst(src2, dst, 0);
199 __lsx_vst(src3, dst, 0);
201 __lsx_vst(src4, dst, 0);
203 __lsx_vst(src5, dst, 0);
205 __lsx_vst(src6, dst, 0);
207 __lsx_vst(src7, dst, 0);
210 src0 = __lsx_vld(src, 0);
211 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2);
212 src3 = __lsx_vldx(src, src_stride3);
215 __lsx_vst(src0, dst, 0);
217 __lsx_vst(src1, dst, 0);
219 __lsx_vst(src2, dst, 0);
221 __lsx_vst(src3, dst, 0);
224 } else if ((height % 8) == 0) {
225 copy_16multx8mult_lsx(src, src_stride, dst, dst_stride, height, 16);
226 } else if ((height % 4) == 0) {
227 for (cnt = (height >> 2); cnt--;) {
228 src0 = __lsx_vld(src, 0);
229 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2);
230 src3 = __lsx_vldx(src, src_stride3);
233 __lsx_vst(src0, dst, 0);
235 __lsx_vst(src1, dst, 0);
237 __lsx_vst(src2, dst, 0);
239 __lsx_vst(src3, dst, 0);
245 static void copy_width32_lsx(const uint8_t *src, int32_t src_stride,
246 uint8_t *dst, int32_t dst_stride, int32_t height) {
250 __m128i src0, src1, src2, src3, src4, src5, src6, src7;
251 int32_t src_stride2 = src_stride << 1;
252 int32_t src_stride3 = src_stride2 + src_stride;
253 int32_t src_stride4 = src_stride2 << 1;
255 if ((height % 12) == 0) {
256 for (cnt = (height / 12); cnt--;) {
257 src0 = __lsx_vld(src, 0);
258 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2);
259 src3 = __lsx_vldx(src, src_stride3);
261 src_tmp = (uint8_t *)src + 16;
262 src4 = __lsx_vld(src_tmp, 0);
263 DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src5,
265 src7 = __lsx_vldx(src_tmp, src_stride3);
268 __lsx_vst(src0, dst, 0);
270 __lsx_vst(src1, dst, 0);
272 __lsx_vst(src2, dst, 0);
274 __lsx_vst(src3, dst, 0);
278 __lsx_vst(src4, dst_tmp, 0);
279 dst_tmp += dst_stride;
280 __lsx_vst(src5, dst_tmp, 0);
281 dst_tmp += dst_stride;
282 __lsx_vst(src6, dst_tmp, 0);
283 dst_tmp += dst_stride;
284 __lsx_vst(src7, dst_tmp, 0);
285 dst_tmp += dst_stride;
287 src0 = __lsx_vld(src, 0);
288 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2);
289 src3 = __lsx_vldx(src, src_stride3);
291 src_tmp = (uint8_t *)src + 16;
292 src4 = __lsx_vld(src_tmp, 0);
293 DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src5,
295 src7 = __lsx_vldx(src_tmp, src_stride3);
298 __lsx_vst(src0, dst, 0);
300 __lsx_vst(src1, dst, 0);
302 __lsx_vst(src2, dst, 0);
304 __lsx_vst(src3, dst, 0);
308 __lsx_vst(src4, dst_tmp, 0);
309 dst_tmp += dst_stride;
310 __lsx_vst(src5, dst_tmp, 0);
311 dst_tmp += dst_stride;
312 __lsx_vst(src6, dst_tmp, 0);
313 dst_tmp += dst_stride;
314 __lsx_vst(src7, dst_tmp, 0);
315 dst_tmp += dst_stride;
317 src0 = __lsx_vld(src, 0);
318 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2);
319 src3 = __lsx_vldx(src, src_stride3);
321 src_tmp = (uint8_t *)src + 16;
322 src4 = __lsx_vld(src_tmp, 0);
323 DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src5,
325 src7 = __lsx_vldx(src_tmp, src_stride3);
328 __lsx_vst(src0, dst, 0);
330 __lsx_vst(src1, dst, 0);
332 __lsx_vst(src2, dst, 0);
334 __lsx_vst(src3, dst, 0);
338 __lsx_vst(src4, dst_tmp, 0);
339 dst_tmp += dst_stride;
340 __lsx_vst(src5, dst_tmp, 0);
341 dst_tmp += dst_stride;
342 __lsx_vst(src6, dst_tmp, 0);
343 dst_tmp += dst_stride;
344 __lsx_vst(src7, dst_tmp, 0);
345 dst_tmp += dst_stride;
347 } else if ((height % 8) == 0) {
348 copy_16multx8mult_lsx(src, src_stride, dst, dst_stride, height, 32);
349 } else if ((height % 4) == 0) {
350 for (cnt = (height >> 2); cnt--;) {
351 src0 = __lsx_vld(src, 0);
352 DUP2_ARG2(__lsx_vldx, src, src_stride, src, src_stride2, src1, src2);
353 src3 = __lsx_vldx(src, src_stride3);
355 src_tmp = (uint8_t *)src + 16;
356 src4 = __lsx_vld(src_tmp, 0);
357 DUP2_ARG2(__lsx_vldx, src_tmp, src_stride, src_tmp, src_stride2, src5,
359 src7 = __lsx_vldx(src_tmp, src_stride3);
362 __lsx_vst(src0, dst, 0);
364 __lsx_vst(src1, dst, 0);
366 __lsx_vst(src2, dst, 0);
368 __lsx_vst(src3, dst, 0);
372 __lsx_vst(src4, dst_tmp, 0);
373 dst_tmp += dst_stride;
374 __lsx_vst(src5, dst_tmp, 0);
375 dst_tmp += dst_stride;
376 __lsx_vst(src6, dst_tmp, 0);
377 dst_tmp += dst_stride;
378 __lsx_vst(src7, dst_tmp, 0);
379 dst_tmp += dst_stride;
384 static void copy_width64_lsx(const uint8_t *src, int32_t src_stride,
385 uint8_t *dst, int32_t dst_stride, int32_t height) {
386 copy_16multx8mult_lsx(src, src_stride, dst, dst_stride, height, 64);
389 void vpx_convolve_copy_lsx(const uint8_t *src, ptrdiff_t src_stride,
390 uint8_t *dst, ptrdiff_t dst_stride,
391 const InterpKernel *filter, int x0_q4,
392 int32_t x_step_q4, int y0_q4, int32_t y_step_q4,
393 int32_t w, int32_t h) {
404 for (cnt = h; cnt--;) {
405 tmp = __lsx_vldrepl_w(src, 0);
406 __lsx_vstelm_w(tmp, dst, 0, 0);
413 copy_width8_lsx(src, src_stride, dst, dst_stride, h);
417 copy_width16_lsx(src, src_stride, dst, dst_stride, h);
421 copy_width32_lsx(src, src_stride, dst, dst_stride, h);
425 copy_width64_lsx(src, src_stride, dst, dst_stride, h);
430 for (cnt = h; cnt--;) {