1/*!
2 * \copy
3 *     Copyright (c)  2013, Cisco Systems
4 *     All rights reserved.
5 *
6 *     Redistribution and use in source and binary forms, with or without
7 *     modification, are permitted provided that the following conditions
8 *     are met:
9 *
10 *        * Redistributions of source code must retain the above copyright
11 *          notice, this list of conditions and the following disclaimer.
12 *
13 *        * Redistributions in binary form must reproduce the above copyright
14 *          notice, this list of conditions and the following disclaimer in
15 *          the documentation and/or other materials provided with the
16 *          distribution.
17 *
18 *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 *     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 *     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 *     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 *     COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 *     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 *     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 *     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 *     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 *     POSSIBILITY OF SUCH DAMAGE.
30 *
31 */
32
33#ifdef HAVE_NEON
34#include "arm_arch_common_macro.S"
35
36
37 //The data sequence will be used
38.macro GET_8BYTE_DATA_L0 arg0, arg1, arg2
39    vld1.8 {\arg0[0]}, [\arg1], \arg2
40    vld1.8 {\arg0[1]}, [\arg1], \arg2
41    vld1.8 {\arg0[2]}, [\arg1], \arg2
42    vld1.8 {\arg0[3]}, [\arg1], \arg2
43    vld1.8 {\arg0[4]}, [\arg1], \arg2
44    vld1.8 {\arg0[5]}, [\arg1], \arg2
45    vld1.8 {\arg0[6]}, [\arg1], \arg2
46    vld1.8 {\arg0[7]}, [\arg1], \arg2
47.endm
48
49.macro HDM_TRANSFORM_4X4_L0 arg0, arg1, arg2,arg3, arg4, arg5, arg6, arg7, arg8
50
51    //Do the vertical transform
52    vaddl.u8 q0, \arg0, \arg1 //{0,4,8,12,1,5,9,13}
53    vsubl.u8 q1, \arg0, \arg1 //{2,6,10,14,3,7,11,15}
54    vswp  d1, d2
55    vadd.s16 q2, q0, q1 //{0,1,2,3,4,5,6,7}
56    vsub.s16 q1, q0, q1 //{12,13,14,15,8,9,10,11}
57
58    //Do the horizontal transform
59    vtrn.32 q2, q1
60    vadd.s16 q0, q2, q1
61    vsub.s16 q1, q2, q1
62
63    vtrn.16 q0, q1
64    vadd.s16 q2, q0, q1
65    vsub.s16 q1, q0, q1
66
67    vmov.s16 d0, d4
68    vmov.s16 d1, d2
69
70    vabs.s16 d3, d3
71
72    //16x16_v
73    vtrn.32 d0, d1 //{0,1,3,2}
74    vaba.s16 \arg5, d0, \arg2 //16x16_v
75    vaba.s16 \arg5, d1, \arg8
76    vaba.s16 \arg5, d5, \arg8
77    vadd.u16 \arg5, d3
78
79    //16x16_h
80    vtrn.16 d4, d5 //{0,4,12,8}
81    vaba.s16 \arg6, d4, \arg3 //16x16_h
82    vabs.s16 d2, d2
83    vabs.s16 d5, d5
84    vadd.u16 d2, d3
85    vadd.u16 d2, d5
86    vadd.u16 \arg6, d2
87
88    //16x16_dc_both
89    vaba.s16 \arg7, d4, \arg4 //16x16_dc_both
90    vadd.u16 \arg7, d2
91.endm
92
93WELS_ASM_FUNC_BEGIN WelsIntra16x16Combined3Satd_neon
94    stmdb sp!, {r4-r7, lr}
95    vpush {q4-q7}
96
97    //Get the top line data to 'q15'(16 bytes)
98    sub  r7, r0, r1
99    vld1.8 {q15}, [r7]
100
101    //Get the left colume data to 'q14' (16 bytes)
102    sub  r7, r0, #1
103    GET_8BYTE_DATA_L0 d28, r7, r1
104    GET_8BYTE_DATA_L0 d29, r7, r1
105
106    //Calculate the mean value and save to 'q13->d27(reserve the d26)' (2 bytes)
107    //Calculate the 16x16_dc_both mode SATD
108    vaddl.u8 q0, d30, d31
109    vaddl.u8 q1, d28, d29
110    vadd.u16 q0, q1
111    vadd.u16 d0, d1
112    vpaddl.u16 d0, d0
113    vpaddl.u32 d0, d0
114
115    //Calculate the mean value
116    vrshr.u16  d0, #5
117    vshl.u16   d27, d0, #4
118
119
120    //Calculate the 16x16_v mode SATD and save to "q11, 12"
121    vshll.u8 q0, d30, #2
122    vshll.u8 q1, d31, #2
123    vtrn.32  q0, q1
124    vadd.s16 q2, q0, q1
125    vsub.s16 q1, q0, q1
126    vtrn.16  q2, q1
127    vadd.s16 q12, q2, q1
128    vsub.s16 q11, q2, q1
129    vtrn.32  q12, q11 //{0,1,3,2, 4,5,7,6} q12
130                      //{8,9,11,10, 12,13,15,14} q11
131    //Calculate the 16x16_h mode SATD and save to "q9, q10"
132    vshll.u8 q0, d28, #2
133    vshll.u8 q1, d29, #2
134    vtrn.32  q0, q1
135    vadd.s16 q2, q0, q1
136    vsub.s16 q1, q0, q1
137    vtrn.16  q2, q1
138    vadd.s16 q10, q2, q1
139    vsub.s16 q9,  q2, q1
140    vtrn.32  q10, q9  //{0,1,3,2, 4,5,7,6} q10
141                      //{8,9,11,10, 12,13,15,14} q9
142
143    vmov.i32 d17, #0//Save the SATD of DC_BOTH
144    vmov.i32 d16, #0//Save the SATD of H
145    vmov.i32 d15, #0//Save the SATD of V
146    vmov.i32 d14, #0//For zero D register
147    //Load the p_enc data and save to "q3 ~ q6"--- 16X4 bytes
148    vld1.32  {q3}, [r2], r3
149    vld1.32  {q4}, [r2], r3
150    vld1.32  {q5}, [r2], r3
151    vld1.32  {q6}, [r2], r3
152    vtrn.32  q3, q4
153    vtrn.32  q5, q6
154
155    HDM_TRANSFORM_4X4_L0 d6, d10, d24, d20, d27, d15, d16, d17, d14
156    HDM_TRANSFORM_4X4_L0 d7, d11, d22, d20, d27, d15, d16, d17, d14
157    HDM_TRANSFORM_4X4_L0 d8, d12, d25, d20, d27, d15, d16, d17, d14
158    HDM_TRANSFORM_4X4_L0 d9, d13, d23, d20, d27, d15, d16, d17, d14
159
160    //Load the p_enc data and save to "q3 ~ q6"--- 16X4 bytes
161    vld1.32  {q3}, [r2], r3
162    vld1.32  {q4}, [r2], r3
163    vld1.32  {q5}, [r2], r3
164    vld1.32  {q6}, [r2], r3
165    vtrn.32  q3, q4
166    vtrn.32  q5, q6
167
168    HDM_TRANSFORM_4X4_L0 d6, d10, d24, d21, d27, d15, d16, d17, d14
169    HDM_TRANSFORM_4X4_L0 d7, d11, d22, d21, d27, d15, d16, d17, d14
170    HDM_TRANSFORM_4X4_L0 d8, d12, d25, d21, d27, d15, d16, d17, d14
171    HDM_TRANSFORM_4X4_L0 d9, d13, d23, d21, d27, d15, d16, d17, d14
172
173    //Load the p_enc data and save to "q3 ~ q6"--- 16X4 bytes
174    vld1.32  {q3}, [r2], r3
175    vld1.32  {q4}, [r2], r3
176    vld1.32  {q5}, [r2], r3
177    vld1.32  {q6}, [r2], r3
178    vtrn.32  q3, q4
179    vtrn.32  q5, q6
180
181    HDM_TRANSFORM_4X4_L0 d6, d10, d24, d18, d27, d15, d16, d17, d14
182    HDM_TRANSFORM_4X4_L0 d7, d11, d22, d18, d27, d15, d16, d17, d14
183    HDM_TRANSFORM_4X4_L0 d8, d12, d25, d18, d27, d15, d16, d17, d14
184    HDM_TRANSFORM_4X4_L0 d9, d13, d23, d18, d27, d15, d16, d17, d14
185
186    //Load the p_enc data and save to "q3 ~ q6"--- 16X4 bytes
187    vld1.32  {q3}, [r2], r3
188    vld1.32  {q4}, [r2], r3
189    vld1.32  {q5}, [r2], r3
190    vld1.32  {q6}, [r2], r3
191    vtrn.32  q3, q4
192    vtrn.32  q5, q6
193
194    HDM_TRANSFORM_4X4_L0 d6, d10, d24, d19, d27, d15, d16, d17, d14
195    HDM_TRANSFORM_4X4_L0 d7, d11, d22, d19, d27, d15, d16, d17, d14
196    HDM_TRANSFORM_4X4_L0 d8, d12, d25, d19, d27, d15, d16, d17, d14
197    HDM_TRANSFORM_4X4_L0 d9, d13, d23, d19, d27, d15, d16, d17, d14
198
199    //Get the data from stack
200    ldr r5, [sp, #84] //the addr of Best_mode
201    ldr r6, [sp, #88] //the value of i_lambda
202
203    //vadd.u16   d24, d25
204    vrshr.u16  d15, #1
205    vpaddl.u16 d15, d15
206    vpaddl.u32 d15, d15
207    vmov.u32   r0, d15[0]
208
209    //vadd.u16   d22, d23
210    vrshr.u16  d16, #1
211    vpaddl.u16 d16, d16
212    vpaddl.u32 d16, d16
213    vmov.u32   r1, d16[0]
214    add  r1, r1, r6, lsl #1
215
216    //vadd.u16   d20, d21
217    vrshr.u16  d17, #1
218    vpaddl.u16 d17, d17
219    vpaddl.u32 d17, d17
220    vmov.u32   r2, d17[0]
221    add  r2, r2, r6, lsl #1
222
223    mov r4, #0
224    cmp r1, r0
225    movcc r0, r1
226    movcc r4, #1
227    cmp r2, r0
228    movcc r0, r2
229    movcc r4, #2
230
231    str r4, [r5]
232
233    vpop {q4-q7}
234    ldmia sp!, {r4-r7, lr}
235WELS_ASM_FUNC_END
236
237
238WELS_ASM_FUNC_BEGIN WelsIntra16x16Combined3Sad_neon
239    stmdb sp!, {r4-r7, lr}
240
241    //Get the top line data to 'q15'(16 bytes)
242    sub  r4, r0, r1
243    vld1.8 {q15}, [r4]
244
245    //Get the left colume data to 'q14' (16 bytes)
246    sub  r4, r0, #1
247    GET_8BYTE_DATA_L0 d28, r4, r1
248    GET_8BYTE_DATA_L0 d29, r4, r1
249
250    //Calculate the mean value and save to 'q13' (8 bytes)
251    //Calculate the 16x16_dc_both mode SATD
252    vaddl.u8 q0, d30, d31
253    vaddl.u8 q1, d28, d29
254    vadd.u16 q0, q1
255    vadd.u16 d0, d1
256    vpaddl.u16 d0, d0
257    vpaddl.u32 d0, d0
258
259    //Calculate the mean value
260    vrshr.u16  d0, d0, #5
261    vdup.8     q13, d0[0]
262
263    sub  r4, r0, #1
264
265    vmov.i32 q12, #0//Save the SATD of DC_BOTH
266    vmov.i32 q11, #0//Save the SATD of H
267    vmov.i32 q10, #0//Save the SATD of V
268
269    mov lr, #16
270sad_intra_16x16_x3_opt_loop0:
271    //Get the left colume data to 'd0' (16 bytes)
272    vld1.8 {d0[]}, [r4], r1
273
274    //Load the p_enc data and save to "q1 ~ q2"--- 16X4 bytes
275    vld1.8  {q1}, [r2], r3
276
277    subs lr, #1
278    //Do the SAD for top colume
279    vabal.u8  q12, d30, d2
280    vabal.u8  q12, d31, d3
281
282    //Do the SAD for left colume
283    vabal.u8  q11, d0, d2
284    vabal.u8  q11, d0, d3
285
286    //Do the SAD for mean value
287    vabal.u8  q10, d26, d2
288    vabal.u8  q10, d26, d3
289
290    bne sad_intra_16x16_x3_opt_loop0
291
292    //Get the data from stack
293    ldr r5, [sp, #20] //the addr of Best_mode
294    ldr r6, [sp, #24] //the value of i_lambda
295
296    vadd.u16   d24, d25
297    vpaddl.u16 d24, d24
298    vpaddl.u32 d24, d24
299    vmov.u32   r0, d24[0]
300
301    vadd.u16   d22, d23
302    vpaddl.u16 d22, d22
303    vpaddl.u32 d22, d22
304    vmov.u32   r1, d22[0]
305    add  r1, r1, r6, lsl #1
306
307    vadd.u16   d20, d21
308    vpaddl.u16 d20, d20
309    vpaddl.u32 d20, d20
310    vmov.u32   r2, d20[0]
311    add  r2, r2, r6, lsl #1
312
313    mov r4, #0
314    cmp r1, r0
315    movcc r0, r1
316    movcc r4, #1
317    cmp r2, r0
318    movcc r0, r2
319    movcc r4, #2
320
321    str r4, [r5]
322
323    ldmia sp!, {r4-r7, lr}
324WELS_ASM_FUNC_END
325
326
327WELS_ASM_FUNC_BEGIN WelsIntra8x8Combined3Sad_neon
328    stmdb sp!, {r4-r7, lr}
329
330    //Get the data from stack
331    ldr r4, [sp, #32] //p_dec_cr
332    ldr r5, [sp, #36] //p_enc_cr
333
334    //Get the left colume data to 'd28(cb), d30(cr)' (16 bytes)
335    sub  r6, r0, #1
336    GET_8BYTE_DATA_L0 d28, r6, r1
337    sub  r6, r4, #1
338    GET_8BYTE_DATA_L0 d30, r6, r1
339
340    //Get the top line data to 'd29(cb), d31(cr)'(16 bytes)
341    sub  r6, r0, r1
342    vld1.8 {d29}, [r6]
343    sub  r6, r4, r1
344    vld1.8 {d31}, [r6]
345
346    //Calculate the sum of left column and top row
347    vmov.i32   q0, q14
348    vpaddl.u8  q0, q0
349    vpaddl.u16 q0, q0
350    vadd.u32   d2, d0, d1 //'m1' save to d2
351    vrshr.u32  q0, q0, #2 //calculate 'm2','m3'
352    vrshr.u32  d2, d2, #3 //calculate 'm4'
353
354    //duplicate the 'mx' to a vector line
355    vdup.8     d27, d2[0]
356    vdup.8     d26, d1[4]
357    vtrn.32    d27, d26
358
359    vdup.8     d26, d0[4]
360    vdup.8     d25, d2[4]
361    vtrn.32    d26, d25   //Save to "d27, d26"
362
363    vmov.i32   q0, q15
364    vpaddl.u8  q0, q0
365    vpaddl.u16 q0, q0
366    vadd.u32   d2, d0, d1 //'m1' save to d2
367    vrshr.u32  q0, q0, #2 //calculate 'm2','m3'
368    vrshr.u32  d2, d2, #3 //calculate 'm4'
369
370    //duplicate the 'mx' to a vector line
371    vdup.8     d25, d2[0]
372    vdup.8     d24, d1[4]
373    vtrn.32    d25, d24
374
375    vdup.8     d24, d0[4]
376    vdup.8     d23, d2[4]
377    vtrn.32    d24, d23   //Save to "d25, d24"
378
379    vmov.i32 q11, #0//Save the SATD of DC_BOTH
380    vmov.i32 q10, #0//Save the SATD of H
381    vmov.i32 q9 , #0//Save the SATD of V
382    sub  r6, r0, #1
383    sub  r7, r4, #1
384    mov lr, #4
385sad_intra_8x8_x3_opt_loop0:
386
387    //Load the p_enc data and save to "q1 ~ q2"--- 16X4 bytes
388    vld1.8  {d0}, [r2], r3
389    vld1.8  {d1}, [r5], r3
390
391    //Get the left colume data to 'd0' (16 bytes)
392    vld1.8 {d2[]}, [r6], r1
393    vld1.8 {d3[]}, [r7], r1
394
395    subs lr, #1
396
397
398    //Do the SAD for top colume
399    vabal.u8  q11, d29, d0
400    vabal.u8  q11, d31, d1
401
402    //Do the SAD for left colume
403    vabal.u8  q10, d2, d0
404    vabal.u8  q10, d3, d1
405
406    //Do the SAD for mean value
407    vabal.u8  q9, d27, d0
408    vabal.u8  q9, d25, d1
409
410
411    bne sad_intra_8x8_x3_opt_loop0
412
413    mov lr, #4
414sad_intra_8x8_x3_opt_loop1:
415
416    //Load the p_enc data and save to "q1 ~ q2"--- 16X4 bytes
417    vld1.8  {d0}, [r2], r3
418    vld1.8  {d1}, [r5], r3
419
420    //Get the left colume data to 'd0' (16 bytes)
421    vld1.8 {d2[]}, [r6], r1
422    vld1.8 {d3[]}, [r7], r1
423
424    subs lr, #1
425
426
427    //Do the SAD for top colume
428    vabal.u8  q11, d29, d0
429    vabal.u8  q11, d31, d1
430
431    //Do the SAD for left colume
432    vabal.u8  q10, d2, d0
433    vabal.u8  q10, d3, d1
434
435    //Do the SAD for mean value
436    vabal.u8  q9, d26, d0
437    vabal.u8  q9, d24, d1
438
439
440    bne sad_intra_8x8_x3_opt_loop1
441    //Get the data from stack
442    ldr r5, [sp, #20] //the addr of Best_mode
443    ldr r6, [sp, #24] //the value of i_lambda
444
445    vadd.u16   d22, d23
446    vpaddl.u16 d22, d22
447    vpaddl.u32 d22, d22
448    vmov.u32   r0, d22[0]
449    add  r0, r0, r6, lsl #1
450
451    vadd.u16   d20, d21
452    vpaddl.u16 d20, d20
453    vpaddl.u32 d20, d20
454    vmov.u32   r1, d20[0]
455    add  r1, r1, r6, lsl #1
456
457    vadd.u16   d18, d19
458    vpaddl.u16 d18, d18
459    vpaddl.u32 d18, d18
460    vmov.u32   r2, d18[0]
461
462    mov r4, #2
463    cmp r1, r0
464    movcc r0, r1
465    movcc r4, #1
466    cmp r2, r0
467    movcc r0, r2
468    movcc r4, #0
469
470    str r4, [r5]
471
472    ldmia sp!, {r4-r7, lr}
473WELS_ASM_FUNC_END
474
475
476WELS_ASM_FUNC_BEGIN WelsIntra8x8Combined3Satd_neon
477    stmdb sp!, {r4-r7, lr}
478    vpush {q4-q7}
479
480    //Get the data from stack
481    ldr r4, [sp, #96] //p_dec_cr
482    ldr r5, [sp, #100] //p_enc_cr
483
484    //Get the top line data to 'd29(cb), d31(cr)'(16 bytes)
485    sub  r6, r0, r1
486    vld1.8 {d29}, [r6]
487    sub  r6, r4, r1
488    vld1.8 {d31}, [r6]
489
490    //Get the left colume data to 'd28(cb), d30(cr)' (16 bytes)
491    sub  r6, r0, #1
492    GET_8BYTE_DATA_L0 d28, r6, r1
493    sub  r6, r4, #1
494    GET_8BYTE_DATA_L0 d30, r6, r1
495
496    //Calculate the 16x16_v mode SATD and save to "q12, 13"
497    vshll.u8 q0, d29, #2
498    vshll.u8 q1, d31, #2
499    vtrn.32  q0, q1
500    vadd.s16 q2, q0, q1
501    vsub.s16 q1, q0, q1
502    vtrn.16  q2, q1
503    vadd.s16 q13, q2, q1
504    vsub.s16 q12, q2, q1
505    vtrn.32  q13, q12 //{0,1,3,2, 4,5,7,6} q13
506                      //{8,9,11,10, 12,13,15,14} q12
507    //Calculate the 16x16_h mode SATD and save to "q10, q11"
508    vshll.u8 q0, d28, #2
509    vshll.u8 q1, d30, #2
510    vtrn.32  q0, q1
511    vadd.s16 q2, q0, q1
512    vsub.s16 q1, q0, q1
513    vtrn.16  q2, q1
514    vadd.s16 q11, q2, q1
515    vsub.s16 q10,  q2, q1
516    vtrn.32  q11, q10  //{0,1,3,2, 4,5,7,6} q11
517                       //{8,9,11,10, 12,13,15,14} q10
518
519    //Calculate the sum of left column and top row
520    //vmov.i32   q0, q14
521    vpaddl.u8  q0, q14
522    vpaddl.u16 q0, q0
523    vadd.u32   d2, d0, d1
524
525    vpaddl.u8  q2, q15
526    vpaddl.u16 q2, q2
527    vadd.u32   d3, d4, d5
528
529    vtrn.32    q0, q2
530    vrshr.u32  q1, #3
531    vrshr.u32  q2, #2
532    vshll.u32  q9, d4, #4 // {2cb, 2cr} q9
533    vshll.u32  q8, d5, #4 // {1cb, 1cr} q8
534    vshll.u32  q7, d2, #4 // {0cb, 3cb} q7
535    vshll.u32  q6, d3, #4 // {0cr, 3cr} q6
536
537
538    vmov.i32 d28, #0//Save the SATD of DC_BOTH
539    vmov.i32 d10, #0//Save the SATD of H
540    vmov.i32 d11, #0//Save the SATD of V
541    vmov.i32 d30, #0//For zero D register
542    //Load the p_enc data and save to "q3 ~ q6"--- 16X4 bytes
543    vld1.32  {d6}, [r2], r3
544    vld1.32  {d7}, [r2], r3
545    vld1.32  {d8}, [r2], r3
546    vld1.32  {d9}, [r2], r3
547    vtrn.32  d6, d7
548    vtrn.32  d8, d9
549    HDM_TRANSFORM_4X4_L0 d6, d8, d26, d22, d14, d11, d10, d28, d30
550    HDM_TRANSFORM_4X4_L0 d7, d9, d27, d22, d16, d11, d10, d28, d30
551
552    vld1.32  {d6}, [r5], r3
553    vld1.32  {d7}, [r5], r3
554    vld1.32  {d8}, [r5], r3
555    vld1.32  {d9}, [r5], r3
556    vtrn.32  d6, d7
557    vtrn.32  d8, d9
558    HDM_TRANSFORM_4X4_L0 d6, d8, d24, d20, d12, d11, d10, d28, d30
559    HDM_TRANSFORM_4X4_L0 d7, d9, d25, d20, d17, d11, d10, d28, d30
560
561    //Load the p_enc data and save to "q3 ~ q6"--- 16X4 bytes
562    vld1.32  {d6}, [r2], r3
563    vld1.32  {d7}, [r2], r3
564    vld1.32  {d8}, [r2], r3
565    vld1.32  {d9}, [r2], r3
566    vtrn.32  d6, d7
567    vtrn.32  d8, d9
568    HDM_TRANSFORM_4X4_L0 d6, d8, d26, d23, d18, d11, d10, d28, d30
569    HDM_TRANSFORM_4X4_L0 d7, d9, d27, d23, d15, d11, d10, d28, d30
570
571    vld1.32  {d6}, [r5], r3
572    vld1.32  {d7}, [r5], r3
573    vld1.32  {d8}, [r5], r3
574    vld1.32  {d9}, [r5], r3
575    vtrn.32  d6, d7
576    vtrn.32  d8, d9
577    HDM_TRANSFORM_4X4_L0 d6, d8, d24, d21, d19, d11, d10, d28, d30
578    HDM_TRANSFORM_4X4_L0 d7, d9, d25, d21, d13, d11, d10, d28, d30
579
580    //Get the data from stack
581    ldr r5, [sp, #84] //the addr of Best_mode
582    ldr r6, [sp, #88] //the value of i_lambda
583
584    vrshr.u16  d11, #1
585    vpaddl.u16 d11, d11
586    vpaddl.u32 d11, d11
587    vmov.u32   lr, d11[0]
588    add  lr, lr, r6, lsl #1
589
590    vrshr.u16  d10, #1
591    vpaddl.u16 d10, d10
592    vpaddl.u32 d10, d10
593    vmov.u32   r3, d10[0]
594    add  r3, r3, r6, lsl #1
595
596    vrshr.u16  d28, #1
597    vpaddl.u16 d28, d28
598    vpaddl.u32 d28, d28
599    vmov.u32   r2, d28[0]
600
601    mov r6, #2
602    cmp r3, lr
603    movcc lr, r3
604    movcc r6, #1
605    cmp r2, lr
606    movcc lr, r2
607    movcc r6, #0
608
609    str r6, [r5]
610    mov r0, lr
611
612    vpop {q4-q7}
613    ldmia sp!, {r4-r7, lr}
614WELS_ASM_FUNC_END
615
616
617WELS_ASM_FUNC_BEGIN WelsIntra4x4Combined3Satd_neon
618    stmdb sp!, {r4-r7, lr}
619
620    //Get the top line data to 'd31[0~3]'(4 bytes)
621    sub  r7, r0, r1
622    vld1.32 {d31[0]}, [r7]
623
624    //Get the left colume data to 'd31[4~7]' (4 bytes)
625    sub  r7, r0, #1
626    vld1.8 {d31[4]}, [r7], r1
627    vld1.8 {d31[5]}, [r7], r1
628    vld1.8 {d31[6]}, [r7], r1
629    vld1.8 {d31[7]}, [r7], r1
630
631    //Calculate the mean value and save to 'd30' (2 bytes)
632    vpaddl.u8 d0, d31
633    vpaddl.u16 d0, d0
634    vpaddl.u32 d0, d0
635    //Calculate the mean value
636    vrshr.u16  d0, #3
637    vshl.u16   d30, d0, #4
638
639    //Calculate the 16x16_v mode SATD and save to "d29"
640    //Calculate the 16x16_h mode SATD and save to "d28"
641    vshll.u8 q0, d31, #2
642    vtrn.32  d0, d1
643    vadd.s16 d2, d0, d1
644    vsub.s16 d1, d0, d1
645    vtrn.16  d2, d1
646    vadd.s16 d29, d2, d1
647    vsub.s16 d28, d2, d1
648    vtrn.32  d29, d28 //{0,1,3,2 top} d29
649                      //{0,1,3,2 left} d28
650
651    vmov.i32 d27, #0//Save the SATD of DC_BOTH
652    vmov.i32 d26, #0//Save the SATD of H
653    vmov.i32 d25, #0//Save the SATD of V
654    vmov.i32 d24, #0//For zero D register
655
656    //Load the p_enc data and save to "d22,d23"--- 4X4 bytes
657    vld1.32  {d23[0]}, [r2], r3
658    vld1.32  {d23[1]}, [r2], r3
659    vld1.32  {d22[0]}, [r2], r3
660    vld1.32  {d22[1]}, [r2], r3
661
662    HDM_TRANSFORM_4X4_L0 d23, d22, d29, d28, d30, d25, d26, d27, d24
663
664    //Get the data from stack
665    ldr r5, [sp, #28] //the value of lambda2
666    ldr r6, [sp, #32] //the value of lambda1
667    ldr r7, [sp, #36] //the value of lambda0
668
669    vrshr.u16  d25, #1
670    vpaddl.u16 d25, d25
671    vpaddl.u32 d25, d25
672    vmov.u32   r0, d25[0]
673    add  r0, r7
674
675    vrshr.u16  d26, #1
676    vpaddl.u16 d26, d26
677    vpaddl.u32 d26, d26
678    vmov.u32   r1, d26[0]
679    add  r1, r6
680
681    vrshr.u16  d27, #1
682    vpaddl.u16 d27, d27
683    vpaddl.u32 d27, d27
684    vmov.u32   r2, d27[0]
685    add  r2, r5
686
687    ldr r5, [sp, #20] //p_dst
688    ldr r6, [sp, #24] //the addr of Best_mode
689
690    mov r4, r0
691    cmp r1, r4
692    movcc r4, r1
693    cmp r2, r4
694    movcc r4, r2
695
696    //The compare sequence affect the resule
697    cmp r4, r2
698    bne satd_intra_4x4_x3_opt_jump0
699    mov r0, #2
700    str r0, [r6]
701    vshr.u32  d0, d30, #4 // {2cb, 2cr} q9
702    vdup.8 q1, d0[0]
703    vst1.8 {q1}, [r5]
704    //...
705    bl satd_intra_4x4_x3_opt_end
706satd_intra_4x4_x3_opt_jump0:
707
708    cmp r4, r1
709    bne satd_intra_4x4_x3_opt_jump1
710    mov r0, #1
711    str r0, [r6]
712    vdup.8 d0, d31[4]
713    vdup.8 d1, d31[5]
714    vdup.8 d2, d31[6]
715    vdup.8 d3, d31[7]
716    vst4.32 {d0[0],d1[0],d2[0],d3[0]}, [r5]
717
718    bl satd_intra_4x4_x3_opt_end
719satd_intra_4x4_x3_opt_jump1:
720
721    mov r0, #0
722    str r0, [r6]
723    vst1.32 {d31[0]}, [r5]!
724    vst1.32 {d31[0]}, [r5]!
725    vst1.32 {d31[0]}, [r5]!
726    vst1.32 {d31[0]}, [r5]!
727
728
729satd_intra_4x4_x3_opt_end:
730    mov r0, r4
731
732    ldmia sp!, {r4-r7, lr}
733WELS_ASM_FUNC_END
734
735#endif
736