1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Copyright (C) 2013 Xiaolei Yu <dreifachstein@gmail.com>
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * This file is part of FFmpeg.
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
10cabdff1aSopenharmony_ci *
11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14cabdff1aSopenharmony_ci * Lesser General Public License for more details.
15cabdff1aSopenharmony_ci *
16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19cabdff1aSopenharmony_ci */
20cabdff1aSopenharmony_ci
21cabdff1aSopenharmony_ci#include "libavutil/arm/asm.S"
22cabdff1aSopenharmony_ci
23cabdff1aSopenharmony_ci.macro alias name, tgt, set=1
24cabdff1aSopenharmony_ci.if \set != 0
25cabdff1aSopenharmony_ci    \name   .req    \tgt
26cabdff1aSopenharmony_ci.else
27cabdff1aSopenharmony_ci    .unreq  \name
28cabdff1aSopenharmony_ci.endif
29cabdff1aSopenharmony_ci.endm
30cabdff1aSopenharmony_ci
31cabdff1aSopenharmony_ci.altmacro
32cabdff1aSopenharmony_ci
33cabdff1aSopenharmony_ci.macro alias_dw_all qw, dw_l, dw_h
34cabdff1aSopenharmony_ci    alias   q\qw\()_l, d\dw_l
35cabdff1aSopenharmony_ci    alias   q\qw\()_h, d\dw_h
36cabdff1aSopenharmony_ci    .if \qw < 15
37cabdff1aSopenharmony_ci        alias_dw_all  %(\qw + 1), %(\dw_l + 2), %(\dw_h + 2)
38cabdff1aSopenharmony_ci    .endif
39cabdff1aSopenharmony_ci.endm
40cabdff1aSopenharmony_ci
41cabdff1aSopenharmony_cialias_dw_all    0, 0, 1
42cabdff1aSopenharmony_ci
43cabdff1aSopenharmony_ci.noaltmacro
44cabdff1aSopenharmony_ci
45cabdff1aSopenharmony_ci.macro alias_qw     name, qw, set=1
46cabdff1aSopenharmony_ci    alias   \name\(), \qw, \set
47cabdff1aSopenharmony_ci    alias   \name\()_l, \qw\()_l, \set
48cabdff1aSopenharmony_ci    alias   \name\()_h, \qw\()_h, \set
49cabdff1aSopenharmony_ci.endm
50cabdff1aSopenharmony_ci
51cabdff1aSopenharmony_ci.macro prologue
52cabdff1aSopenharmony_ci    push            {r4-r12, lr}
53cabdff1aSopenharmony_ci    vpush           {q4-q7}
54cabdff1aSopenharmony_ci.endm
55cabdff1aSopenharmony_ci
56cabdff1aSopenharmony_ci.macro epilogue
57cabdff1aSopenharmony_ci    vpop            {q4-q7}
58cabdff1aSopenharmony_ci    pop             {r4-r12, pc}
59cabdff1aSopenharmony_ci.endm
60cabdff1aSopenharmony_ci
61cabdff1aSopenharmony_ci.macro  load_arg    reg, ix
62cabdff1aSopenharmony_ci    ldr     \reg,   [sp, #((10 * 4 + 4 * 16) + (\ix - 4) * 4)]
63cabdff1aSopenharmony_ci.endm
64cabdff1aSopenharmony_ci
65cabdff1aSopenharmony_ci
66cabdff1aSopenharmony_ci/* ()_to_()_neon(const uint8_t *src, uint8_t *y, uint8_t *chroma
67cabdff1aSopenharmony_ci *                  int width, int height,
68cabdff1aSopenharmony_ci *                  int y_stride, int c_stride, int src_stride,
69cabdff1aSopenharmony_ci *                  int32_t coeff_table[9]);
70cabdff1aSopenharmony_ci */
71cabdff1aSopenharmony_ci.macro  alias_loop_420sp set=1
72cabdff1aSopenharmony_ci    alias   src,        r0, \set
73cabdff1aSopenharmony_ci    alias   src0,       src, \set
74cabdff1aSopenharmony_ci    alias   y,          r1, \set
75cabdff1aSopenharmony_ci    alias   y0,         y, \set
76cabdff1aSopenharmony_ci    alias   chroma,     r2, \set
77cabdff1aSopenharmony_ci    alias   width,      r3, \set
78cabdff1aSopenharmony_ci    alias   header,     width, \set
79cabdff1aSopenharmony_ci
80cabdff1aSopenharmony_ci    alias   height,     r4, \set
81cabdff1aSopenharmony_ci    alias   y_stride,   r5, \set
82cabdff1aSopenharmony_ci    alias   c_stride,   r6, \set
83cabdff1aSopenharmony_ci    alias   c_padding,  c_stride, \set
84cabdff1aSopenharmony_ci    alias   src_stride, r7, \set
85cabdff1aSopenharmony_ci
86cabdff1aSopenharmony_ci    alias   y0_end,     r8, \set
87cabdff1aSopenharmony_ci
88cabdff1aSopenharmony_ci    alias   src_padding,r9, \set
89cabdff1aSopenharmony_ci    alias   y_padding,  r10, \set
90cabdff1aSopenharmony_ci
91cabdff1aSopenharmony_ci    alias   src1,       r11, \set
92cabdff1aSopenharmony_ci    alias   y1,         r12, \set
93cabdff1aSopenharmony_ci
94cabdff1aSopenharmony_ci    alias   coeff_table,r12, \set
95cabdff1aSopenharmony_ci.endm
96cabdff1aSopenharmony_ci
97cabdff1aSopenharmony_ci
98cabdff1aSopenharmony_ci.macro  loop_420sp s_fmt, d_fmt, init, kernel, precision
99cabdff1aSopenharmony_ci
100cabdff1aSopenharmony_cifunction \s_fmt\()_to_\d_fmt\()_neon_\precision, export=1
101cabdff1aSopenharmony_ci    prologue
102cabdff1aSopenharmony_ci
103cabdff1aSopenharmony_ci    alias_loop_420sp
104cabdff1aSopenharmony_ci
105cabdff1aSopenharmony_ci    load_arg    height,         4
106cabdff1aSopenharmony_ci    load_arg    y_stride,       5
107cabdff1aSopenharmony_ci    load_arg    c_stride,       6
108cabdff1aSopenharmony_ci    load_arg    src_stride,     7
109cabdff1aSopenharmony_ci    load_arg    coeff_table,    8
110cabdff1aSopenharmony_ci
111cabdff1aSopenharmony_ci    \init       coeff_table
112cabdff1aSopenharmony_ci
113cabdff1aSopenharmony_ci    sub         y_padding,      y_stride,       width
114cabdff1aSopenharmony_ci    sub         c_padding,      c_stride,       width
115cabdff1aSopenharmony_ci    sub         src_padding,    src_stride,     width, LSL #2
116cabdff1aSopenharmony_ci
117cabdff1aSopenharmony_ci    add         y0_end,         y0,             width
118cabdff1aSopenharmony_ci    and         header,         width,          #15
119cabdff1aSopenharmony_ci
120cabdff1aSopenharmony_ci    add         y1,             y0,             y_stride
121cabdff1aSopenharmony_ci    add         src1,           src0,           src_stride
122cabdff1aSopenharmony_ci
123cabdff1aSopenharmony_ci0:
124cabdff1aSopenharmony_ci    cmp         header,     #0
125cabdff1aSopenharmony_ci    beq         1f
126cabdff1aSopenharmony_ci
127cabdff1aSopenharmony_ci    \kernel     \s_fmt, \d_fmt, src0, src1, y0, y1, chroma, header
128cabdff1aSopenharmony_ci
129cabdff1aSopenharmony_ci1:
130cabdff1aSopenharmony_ci    \kernel     \s_fmt, \d_fmt, src0, src1, y0, y1, chroma
131cabdff1aSopenharmony_ci
132cabdff1aSopenharmony_ci    cmp         y0,         y0_end
133cabdff1aSopenharmony_ci    blt         1b
134cabdff1aSopenharmony_ci2:
135cabdff1aSopenharmony_ci    add         y0,         y1,         y_padding
136cabdff1aSopenharmony_ci    add         y0_end,     y1,         y_stride
137cabdff1aSopenharmony_ci    add         chroma,     chroma,     c_padding
138cabdff1aSopenharmony_ci    add         src0,       src1,       src_padding
139cabdff1aSopenharmony_ci
140cabdff1aSopenharmony_ci    add         y1,         y0,         y_stride
141cabdff1aSopenharmony_ci    add         src1,       src0,       src_stride
142cabdff1aSopenharmony_ci
143cabdff1aSopenharmony_ci    subs        height,     height,     #2
144cabdff1aSopenharmony_ci
145cabdff1aSopenharmony_ci    bgt         0b
146cabdff1aSopenharmony_ci
147cabdff1aSopenharmony_ci    epilogue
148cabdff1aSopenharmony_ci
149cabdff1aSopenharmony_ci    alias_loop_420sp 0
150cabdff1aSopenharmony_ci
151cabdff1aSopenharmony_ciendfunc
152cabdff1aSopenharmony_ci.endm
153cabdff1aSopenharmony_ci
154cabdff1aSopenharmony_ci.macro downsample
155cabdff1aSopenharmony_ci    vpaddl.u8   r16x8,  r8x16
156cabdff1aSopenharmony_ci    vpaddl.u8   g16x8,  g8x16
157cabdff1aSopenharmony_ci    vpaddl.u8   b16x8,  b8x16
158cabdff1aSopenharmony_ci.endm
159cabdff1aSopenharmony_ci
160cabdff1aSopenharmony_ci
161cabdff1aSopenharmony_ci/* acculumate and right shift by 2 */
162cabdff1aSopenharmony_ci.macro downsample_ars2
163cabdff1aSopenharmony_ci    vpadal.u8   r16x8,  r8x16
164cabdff1aSopenharmony_ci    vpadal.u8   g16x8,  g8x16
165cabdff1aSopenharmony_ci    vpadal.u8   b16x8,  b8x16
166cabdff1aSopenharmony_ci
167cabdff1aSopenharmony_ci    vrshr.u16   r16x8,  r16x8,  #2
168cabdff1aSopenharmony_ci    vrshr.u16   g16x8,  g16x8,  #2
169cabdff1aSopenharmony_ci    vrshr.u16   b16x8,  b16x8,  #2
170cabdff1aSopenharmony_ci.endm
171cabdff1aSopenharmony_ci
172cabdff1aSopenharmony_ci.macro store_y8_16x1            dst, count
173cabdff1aSopenharmony_ci.ifc "\count",""
174cabdff1aSopenharmony_ci    vstmia      \dst!,  {y8x16}
175cabdff1aSopenharmony_ci.else
176cabdff1aSopenharmony_ci    vstmia      \dst,   {y8x16}
177cabdff1aSopenharmony_ci    add         \dst,   \dst,           \count
178cabdff1aSopenharmony_ci.endif
179cabdff1aSopenharmony_ci.endm
180cabdff1aSopenharmony_ci
181cabdff1aSopenharmony_ci.macro store_chroma_nv12_8x1    dst, count
182cabdff1aSopenharmony_ci.ifc "\count",""
183cabdff1aSopenharmony_ci    vst2.i8     {u8x8, v8x8},   [\dst]!
184cabdff1aSopenharmony_ci.else
185cabdff1aSopenharmony_ci    vst2.i8     {u8x8, v8x8},   [\dst], \count
186cabdff1aSopenharmony_ci.endif
187cabdff1aSopenharmony_ci.endm
188cabdff1aSopenharmony_ci
189cabdff1aSopenharmony_ci.macro store_chroma_nv21_8x1    dst, count
190cabdff1aSopenharmony_ci.ifc "\count",""
191cabdff1aSopenharmony_ci    vst2.i8     {v8x8, u8x8},   [\dst]!
192cabdff1aSopenharmony_ci.else
193cabdff1aSopenharmony_ci    vst2.i8     {v8x8, u8x8},   [\dst], \count
194cabdff1aSopenharmony_ci.endif
195cabdff1aSopenharmony_ci.endm
196cabdff1aSopenharmony_ci
197cabdff1aSopenharmony_ci.macro load_8888_16x1   a, b, c, d, src, count
198cabdff1aSopenharmony_ci.ifc "\count",""
199cabdff1aSopenharmony_ci    vld4.8      {\a\()8x16_l, \b\()8x16_l, \c\()8x16_l, \d\()8x16_l},  [\src]!
200cabdff1aSopenharmony_ci    vld4.8      {\a\()8x16_h, \b\()8x16_h, \c\()8x16_h, \d\()8x16_h},  [\src]!
201cabdff1aSopenharmony_ci.else
202cabdff1aSopenharmony_ci    vld4.8      {\a\()8x16_l, \b\()8x16_l, \c\()8x16_l, \d\()8x16_l},  [\src]!
203cabdff1aSopenharmony_ci    vld4.8      {\a\()8x16_h, \b\()8x16_h, \c\()8x16_h, \d\()8x16_h},  [\src]
204cabdff1aSopenharmony_ci    sub         \src,   \src,   #32
205cabdff1aSopenharmony_ci    add         \src,   \src,   \count, LSL #2
206cabdff1aSopenharmony_ci.endif
207cabdff1aSopenharmony_ci.endm
208cabdff1aSopenharmony_ci
209cabdff1aSopenharmony_ci.macro load_rgbx_16x1   src, count
210cabdff1aSopenharmony_ci    load_8888_16x1  r, g, b, x, \src, \count
211cabdff1aSopenharmony_ci.endm
212cabdff1aSopenharmony_ci
213cabdff1aSopenharmony_ci.macro load_bgrx_16x1   src, count
214cabdff1aSopenharmony_ci    load_8888_16x1  b, g, r, x, \src, \count
215cabdff1aSopenharmony_ci.endm
216cabdff1aSopenharmony_ci
217cabdff1aSopenharmony_ci.macro alias_src_rgbx   set=1
218cabdff1aSopenharmony_ci    alias_src_8888  r, g, b, x, \set
219cabdff1aSopenharmony_ci.endm
220cabdff1aSopenharmony_ci
221cabdff1aSopenharmony_ci.macro alias_src_bgrx   set=1
222cabdff1aSopenharmony_ci    alias_src_8888  b, g, r, x, \set
223cabdff1aSopenharmony_ci.endm
224cabdff1aSopenharmony_ci
225cabdff1aSopenharmony_ci.macro alias_dst_nv12   set=1
226cabdff1aSopenharmony_ci    alias   u8x8, c8x8x2_l, \set
227cabdff1aSopenharmony_ci    alias   v8x8, c8x8x2_h, \set
228cabdff1aSopenharmony_ci.endm
229cabdff1aSopenharmony_ci
230cabdff1aSopenharmony_ci.macro alias_dst_nv21   set=1
231cabdff1aSopenharmony_ci    alias   v8x8, c8x8x2_l, \set
232cabdff1aSopenharmony_ci    alias   u8x8, c8x8x2_h, \set
233cabdff1aSopenharmony_ci.endm
234cabdff1aSopenharmony_ci
235cabdff1aSopenharmony_ci
236cabdff1aSopenharmony_ci// common aliases
237cabdff1aSopenharmony_ci
238cabdff1aSopenharmony_cialias   CO_R    d0
239cabdff1aSopenharmony_ciCO_RY   .dn     d0.s16[0]
240cabdff1aSopenharmony_ciCO_RU   .dn     d0.s16[1]
241cabdff1aSopenharmony_ciCO_RV   .dn     d0.s16[2]
242cabdff1aSopenharmony_ci
243cabdff1aSopenharmony_cialias   CO_G    d1
244cabdff1aSopenharmony_ciCO_GY   .dn     d1.s16[0]
245cabdff1aSopenharmony_ciCO_GU   .dn     d1.s16[1]
246cabdff1aSopenharmony_ciCO_GV   .dn     d1.s16[2]
247cabdff1aSopenharmony_ci
248cabdff1aSopenharmony_cialias   CO_B    d2
249cabdff1aSopenharmony_ciCO_BY   .dn     d2.s16[0]
250cabdff1aSopenharmony_ciCO_BU   .dn     d2.s16[1]
251cabdff1aSopenharmony_ciCO_BV   .dn     d2.s16[2]
252cabdff1aSopenharmony_ci
253cabdff1aSopenharmony_cialias   BIAS_U, d3
254cabdff1aSopenharmony_cialias   BIAS_V, BIAS_U
255cabdff1aSopenharmony_ci
256cabdff1aSopenharmony_cialias   BIAS_Y, q2
257cabdff1aSopenharmony_ci
258cabdff1aSopenharmony_ci
259cabdff1aSopenharmony_ci/* q3-q6 R8G8B8X8 x16 */
260cabdff1aSopenharmony_ci
261cabdff1aSopenharmony_ci.macro alias_src_8888   a, b, c, d, set
262cabdff1aSopenharmony_ci    alias_qw  \a\()8x16, q3, \set
263cabdff1aSopenharmony_ci    alias_qw  \b\()8x16, q4, \set
264cabdff1aSopenharmony_ci    alias_qw  \c\()8x16, q5, \set
265cabdff1aSopenharmony_ci    alias_qw  \d\()8x16, q6, \set
266cabdff1aSopenharmony_ci.endm
267cabdff1aSopenharmony_ci
268cabdff1aSopenharmony_ci.macro kernel_420_16x2  rgb_fmt, yuv_fmt, rgb0, rgb1, y0, y1, chroma, count
269cabdff1aSopenharmony_ci    alias_src_\rgb_fmt
270cabdff1aSopenharmony_ci    alias_dst_\yuv_fmt
271cabdff1aSopenharmony_ci
272cabdff1aSopenharmony_ci    load_\rgb_fmt\()_16x1   \rgb0, \count
273cabdff1aSopenharmony_ci
274cabdff1aSopenharmony_ci    downsample
275cabdff1aSopenharmony_ci    compute_y_16x1
276cabdff1aSopenharmony_ci    store_y8_16x1   \y0, \count
277cabdff1aSopenharmony_ci
278cabdff1aSopenharmony_ci
279cabdff1aSopenharmony_ci    load_\rgb_fmt\()_16x1   \rgb1, \count
280cabdff1aSopenharmony_ci    downsample_ars2
281cabdff1aSopenharmony_ci    compute_y_16x1
282cabdff1aSopenharmony_ci    store_y8_16x1   \y1, \count
283cabdff1aSopenharmony_ci
284cabdff1aSopenharmony_ci    compute_chroma_8x1  u, U
285cabdff1aSopenharmony_ci    compute_chroma_8x1  v, V
286cabdff1aSopenharmony_ci
287cabdff1aSopenharmony_ci    store_chroma_\yuv_fmt\()_8x1 \chroma, \count
288cabdff1aSopenharmony_ci
289cabdff1aSopenharmony_ci    alias_dst_\yuv_fmt 0
290cabdff1aSopenharmony_ci    alias_src_\rgb_fmt 0
291cabdff1aSopenharmony_ci.endm
292