ih264_weighted_bi_pred_av8.s revision 8d3d303c7942ced6a987a52db8977d768dc3605f
1//******************************************************************************
2//*
3//* Copyright (C) 2015 The Android Open Source Project
4//*
5//* Licensed under the Apache License, Version 2.0 (the "License");
6//* you may not use this file except in compliance with the License.
7//* You may obtain a copy of the License at:
8//*
9//* http://www.apache.org/licenses/LICENSE-2.0
10//*
11//* Unless required by applicable law or agreed to in writing, software
12//* distributed under the License is distributed on an "AS IS" BASIS,
13//* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14//* See the License for the specific language governing permissions and
15//* limitations under the License.
16//*
17//*****************************************************************************
18//* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19//*/
20///**
21//******************************************************************************
22//* @file
23//*  ih264_weighted_bi_pred_av8.s
24//*
25//* @brief
26//*  Contains function definitions for weighted biprediction.
27//* Functions are coded using NEON intrinsics and can be compiled using ARM RVCT
28//*
29//* @author
30//*  Kaushik Senthoor R
31//*
32//* @par List of Functions:
33//*
34//*  - ih264_weighted_bi_pred_luma_av8()
35//*  - ih264_weighted_bi_pred_chroma_av8()
36//*
37//* @remarks
38//*  None
39//*
40//*******************************************************************************
41//*/
42//*******************************************************************************
43//* @function
44//*  ih264_weighted_bi_pred_luma_av8()
45//*
46//* @brief
47//*  This routine performs the default weighted prediction as described in sec
48//* 8.4.2.3.2 titled "Weighted sample prediction process" for luma.
49//*
50//* @par Description:
51//*  This function gets two ht x wd blocks, calculates the weighted samples,
52//* rounds off, adds offset and stores it in the destination block.
53//*
54//* @param[in] puc_src1
55//*  UWORD8 Pointer to the buffer containing the input block 1.
56//*
57//* @param[in] puc_src2
58//*  UWORD8 Pointer to the buffer containing the input block 2.
59//*
60//* @param[out] puc_dst
61//*  UWORD8 pointer to the destination where the output block is stored.
62//*
63//* @param[in] src_strd1
64//*  Stride of the input buffer 1
65//*
66//* @param[in] src_strd2
67//*  Stride of the input buffer 2
68//*
69//* @param[in] dst_strd
70//*  Stride of the destination buffer
71//*
72//* @param[in] log_WD
73//*  number of bits to be rounded off
74//*
75//* @param[in] wt1
76//*  weight for the weighted prediction
77//*
78//* @param[in] wt2
79//*  weight for the weighted prediction
80//*
81//* @param[in] ofst1
82//*  offset 1 used after rounding off
83//*
84//* @param[in] ofst2
85//*  offset 2 used after rounding off
86//*
87//* @param[in] ht
88//*  integer height of the array
89//*
90//* @param[in] wd
91//*  integer width of the array
92//*
93//* @returns
94//*  None
95//*
96//* @remarks
97//*  (ht,wd) can be (4,4), (4,8), (8,4), (8,8), (8,16), (16,8) or (16,16).
98//*
99//*******************************************************************************
100//*/
101//void ih264_weighted_bi_pred_luma_av8(UWORD8 *puc_src1,
102//                                     UWORD8 *puc_src2,
103//                                     UWORD8 *puc_dst,
104//                                     WORD32 src_strd1,
105//                                     WORD32 src_strd2,
106//                                     WORD32 dst_strd,
107//                                     UWORD16 log_WD,
108//                                     UWORD32 wt1,
109//                                     UWORD32 wt2,
110//                                     UWORD16 ofst1,
111//                                     UWORD16 ofst2,
112//                                     UWORD8 ht,
113//                                     UWORD8 wd)
114//
115//**************Variables Vs Registers*****************************************
116//    x0      => puc_src1
117//    x1      => puc_src2
118//    x2      => puc_dst
119//    x3      => src_strd1
120//    [sp]    => src_strd2 (x4)
121//    [sp+4]  => dst_strd  (x5)
122//    [sp+8]  => log_WD    (x6)
123//    [sp+12] => wt1       (x7)
124//   [sp+16] => wt2       (x8)
125//   [sp+20] => ofst1     (x9)
126//   [sp+24] => ofst2     (x10)
127//    [sp+28] => ht        (x11)
128//    [sp+32] => wd        (x12)
129//
130.text
131.p2align 2
132.include "ih264_neon_macros.s"
133
134
135
136    .global ih264_weighted_bi_pred_luma_av8
137
138ih264_weighted_bi_pred_luma_av8:
139
140    // STMFD sp!, {x4-x12,x14}                //stack stores the values of the arguments
141    push_v_regs
142    stp       x19, x20, [sp, #-16]!
143    ldr       x8, [sp, #80]             //Load wt2 in x8
144    ldr       x9, [sp, #88]             //Load ofst1 in x9
145    add       x6, x6, #1                //x6  = log_WD + 1
146    sub       x20, x6, #0               //x13 = -(log_WD + 1)
147    neg       x10, x20
148    dup       v0.8h, w10                //Q0  = -(log_WD + 1) (32-bit)
149    ldr       x10, [sp, #96]            //Load ofst2 in x10
150    ldr       x11, [sp, #104]           //Load ht in x11
151    ldr       x12, [sp, #112]           //Load wd in x12
152    add       x9, x9, #1                //x9 = ofst1 + 1
153    add       x9, x9, x10               //x9 = ofst1 + ofst2 + 1
154    mov       v2.s[0], w7
155    mov       v2.s[1], w8               //D2 = {wt1(32-bit), wt2(32-bit)}
156    asr       x9, x9, #1                //x9 = ofst = (ofst1 + ofst2 + 1) >> 1
157    dup       v3.8b, w9                 //D3 = ofst (8-bit)
158    cmp       w12, #16
159    beq       loop_16                   //branch if wd is 16
160    cmp       w12, #8                   //check if wd is 8
161    beq       loop_8                    //branch if wd is 8
162
163loop_4:                                 //each iteration processes four rows
164
165    ld1       {v4.s}[0], [x0], x3       //load row 1 in source 1
166    ld1       {v4.s}[1], [x0], x3       //load row 2 in source 1
167    ld1       {v6.s}[0], [x1], x4       //load row 1 in source 2
168    ld1       {v6.s}[1], [x1], x4       //load row 2 in source 2
169    uxtl      v4.8h, v4.8b              //converting rows 1,2 in source 1 to 16-bit
170    ld1       {v8.s}[0], [x0], x3       //load row 3 in source 1
171    ld1       {v8.s}[1], [x0], x3       //load row 4 in source 1
172    uxtl      v6.8h, v6.8b              //converting rows 1,2 in source 2 to 16-bit
173    ld1       {v10.s}[0], [x1], x4      //load row 3 in source 2
174    ld1       {v10.s}[1], [x1], x4      //load row 4 in source 2
175    uxtl      v8.8h, v8.8b              //converting rows 3,4 in source 1 to 16-bit
176    uxtl      v10.8h, v10.8b            //converting rows 3,4 in source 2 to 16-bit
177    mul       v4.8h, v4.8h , v2.4h[0]   //weight 1 mult. for rows 1,2
178    mla       v4.8h, v6.8h , v2.4h[2]   //weight 2 mult. for rows 1,2
179    mul       v8.8h, v8.8h , v2.4h[0]   //weight 1 mult. for rows 3,4
180    mla       v8.8h, v10.8h , v2.4h[2]  //weight 2 mult. for rows 3,4
181    subs      w11, w11, #4              //decrement ht by 4
182    srshl     v4.8h, v4.8h , v0.8h      //rounds off the weighted samples from rows 1,2
183    srshl     v8.8h, v8.8h , v0.8h      //rounds off the weighted samples from rows 3,4
184    saddw     v4.8h, v4.8h , v3.8b      //adding offset for rows 1,2
185    saddw     v8.8h, v8.8h , v3.8b      //adding offset for rows 3,4
186    sqxtun    v4.8b, v4.8h              //saturating rows 1,2 to unsigned 8-bit
187    sqxtun    v8.8b, v8.8h              //saturating rows 3,4 to unsigned 8-bit
188    st1       {v4.s}[0], [x2], x5       //store row 1 in destination
189    st1       {v4.s}[1], [x2], x5       //store row 2 in destination
190    st1       {v8.s}[0], [x2], x5       //store row 3 in destination
191    st1       {v8.s}[1], [x2], x5       //store row 4 in destination
192    bgt       loop_4                    //if greater than 0 repeat the loop again
193    b         end_loops
194
195loop_8:                                 //each iteration processes four rows
196
197    ld1       {v4.8b}, [x0], x3         //load row 1 in source 1
198    ld1       {v6.8b}, [x1], x4         //load row 1 in source 2
199    ld1       {v8.8b}, [x0], x3         //load row 2 in source 1
200    ld1       {v10.8b}, [x1], x4        //load row 2 in source 2
201    uxtl      v4.8h, v4.8b              //converting row 1 in source 1 to 16-bit
202    ld1       {v12.8b}, [x0], x3        //load row 3 in source 1
203    ld1       {v14.8b}, [x1], x4        //load row 3 in source 2
204    uxtl      v6.8h, v6.8b              //converting row 1 in source 2 to 16-bit
205    ld1       {v16.8b}, [x0], x3        //load row 4 in source 1
206    ld1       {v18.8b}, [x1], x4        //load row 4 in source 2
207    uxtl      v8.8h, v8.8b              //converting row 2 in source 1 to 16-bit
208    uxtl      v10.8h, v10.8b            //converting row 2 in source 2 to 16-bit
209    mul       v4.8h, v4.8h , v2.4h[0]   //weight 1 mult. for row 1
210    mla       v4.8h, v6.8h , v2.4h[2]   //weight 2 mult. for row 1
211    uxtl      v12.8h, v12.8b            //converting row 3 in source 1 to 16-bit
212    uxtl      v14.8h, v14.8b            //converting row 3 in source 2 to 16-bit
213    mul       v8.8h, v8.8h , v2.4h[0]   //weight 1 mult. for row 2
214    mla       v8.8h, v10.8h , v2.4h[2]  //weight 2 mult. for row 2
215    uxtl      v16.8h, v16.8b            //converting row 4 in source 1 to 16-bit
216    uxtl      v18.8h, v18.8b            //converting row 4 in source 2 to 16-bit
217    mul       v12.8h, v12.8h , v2.4h[0] //weight 1 mult. for row 3
218    mla       v12.8h, v14.8h , v2.4h[2] //weight 2 mult. for row 3
219    mul       v16.8h, v16.8h , v2.4h[0] //weight 1 mult. for row 4
220    mla       v16.8h, v18.8h , v2.4h[2] //weight 2 mult. for row 4
221    srshl     v4.8h, v4.8h , v0.8h      //rounds off the weighted samples from row 1
222    srshl     v8.8h, v8.8h , v0.8h      //rounds off the weighted samples from row 2
223    srshl     v12.8h, v12.8h , v0.8h    //rounds off the weighted samples from row 3
224    saddw     v4.8h, v4.8h , v3.8b      //adding offset for row 1
225    srshl     v16.8h, v16.8h , v0.8h    //rounds off the weighted samples from row 4
226    saddw     v8.8h, v8.8h , v3.8b      //adding offset for row 2
227    saddw     v12.8h, v12.8h , v3.8b    //adding offset for row 3
228    sqxtun    v4.8b, v4.8h              //saturating row 1 to unsigned 8-bit
229    saddw     v16.8h, v16.8h , v3.8b    //adding offset for row 4
230    sqxtun    v8.8b, v8.8h              //saturating row 2 to unsigned 8-bit
231    sqxtun    v12.8b, v12.8h            //saturating row 3 to unsigned 8-bit
232    sqxtun    v16.8b, v16.8h            //saturating row 4 to unsigned 8-bit
233    st1       {v4.8b}, [x2], x5         //store row 1 in destination
234    st1       {v8.8b}, [x2], x5         //store row 2 in destination
235    subs      w11, w11, #4              //decrement ht by 4
236    st1       {v12.8b}, [x2], x5        //store row 3 in destination
237    st1       {v16.8b}, [x2], x5        //store row 4 in destination
238    bgt       loop_8                    //if greater than 0 repeat the loop again
239    b         end_loops
240
241loop_16:                                //each iteration processes two rows
242
243    ld1       {v4.8b, v5.8b}, [x0], x3  //load row 1 in source 1
244    ld1       {v6.8b, v7.8b}, [x1], x4  //load row 1 in source 2
245    ld1       {v8.8b, v9.8b}, [x0], x3  //load row 2 in source 1
246    ld1       {v10.8b, v11.8b}, [x1], x4 //load row 2 in source 2
247    uxtl      v20.8h, v4.8b             //converting row 1L in source 1 to 16-bit
248    ld1       {v12.8b, v13.8b}, [x0], x3 //load row 3 in source 1
249    ld1       {v14.8b, v15.8b}, [x1], x4 //load row 3 in source 2
250    uxtl      v22.8h, v6.8b             //converting row 1L in source 2 to 16-bit
251    ld1       {v16.8b, v17.8b}, [x0], x3 //load row 4 in source 1
252    ld1       {v18.8b, v19.8b}, [x1], x4 //load row 4 in source 2
253    uxtl      v4.8h, v5.8b              //converting row 1H in source 1 to 16-bit
254    uxtl      v6.8h, v7.8b              //converting row 1H in source 2 to 16-bit
255    mul       v20.8h, v20.8h , v2.4h[0] //weight 1 mult. for row 1L
256    mla       v20.8h, v22.8h , v2.4h[2] //weight 2 mult. for row 1L
257    uxtl      v24.8h, v8.8b             //converting row 2L in source 1 to 16-bit
258    uxtl      v26.8h, v10.8b            //converting row 2L in source 2 to 16-bit
259    mul       v4.8h, v4.8h , v2.4h[0]   //weight 1 mult. for row 1H
260    mla       v4.8h, v6.8h , v2.4h[2]   //weight 2 mult. for row 1H
261    uxtl      v8.8h, v9.8b              //converting row 2H in source 1 to 16-bit
262    uxtl      v10.8h, v11.8b            //converting row 2H in source 2 to 16-bit
263    mul       v24.8h, v24.8h , v2.4h[0] //weight 1 mult. for row 2L
264    mla       v24.8h, v26.8h , v2.4h[2] //weight 2 mult. for row 2L
265    uxtl      v28.8h, v12.8b            //converting row 3L in source 1 to 16-bit
266    uxtl      v30.8h, v14.8b            //converting row 3L in source 2 to 16-bit
267    mul       v8.8h, v8.8h , v2.4h[0]   //weight 1 mult. for row 2H
268    mla       v8.8h, v10.8h , v2.4h[2]  //weight 2 mult. for row 2H
269    uxtl      v12.8h, v13.8b            //converting row 3H in source 1 to 16-bit
270    uxtl      v14.8h, v15.8b            //converting row 3H in source 2 to 16-bit
271    mul       v28.8h, v28.8h , v2.4h[0] //weight 1 mult. for row 3L
272    mla       v28.8h, v30.8h , v2.4h[2] //weight 2 mult. for row 3L
273    uxtl      v22.8h, v16.8b            //converting row 4L in source 1 to 16-bit
274    uxtl      v6.8h, v18.8b             //converting row 4L in source 2 to 16-bit
275    mul       v12.8h, v12.8h , v2.4h[0] //weight 1 mult. for row 3H
276    mla       v12.8h, v14.8h , v2.4h[2] //weight 2 mult. for row 3H
277    uxtl      v16.8h, v17.8b            //converting row 4H in source 1 to 16-bit
278    uxtl      v18.8h, v19.8b            //converting row 4H in source 2 to 16-bit
279    mul       v22.8h, v22.8h , v2.4h[0] //weight 1 mult. for row 4L
280    mla       v22.8h, v6.8h , v2.4h[2]  //weight 2 mult. for row 4L
281    srshl     v20.8h, v20.8h , v0.8h    //rounds off the weighted samples from row 1L
282    mul       v16.8h, v16.8h , v2.4h[0] //weight 1 mult. for row 4H
283    mla       v16.8h, v18.8h , v2.4h[2] //weight 2 mult. for row 4H
284    srshl     v4.8h, v4.8h , v0.8h      //rounds off the weighted samples from row 1H
285    srshl     v24.8h, v24.8h , v0.8h    //rounds off the weighted samples from row 2L
286    saddw     v20.8h, v20.8h , v3.8b    //adding offset for row 1L
287    srshl     v8.8h, v8.8h , v0.8h      //rounds off the weighted samples from row 2H
288    saddw     v4.8h, v4.8h , v3.8b      //adding offset for row 1H
289    srshl     v28.8h, v28.8h , v0.8h    //rounds off the weighted samples from row 3L
290    saddw     v24.8h, v24.8h , v3.8b    //adding offset for row 2L
291    srshl     v12.8h, v12.8h , v0.8h    //rounds off the weighted samples from row 3H
292    saddw     v8.8h, v8.8h , v3.8b      //adding offset for row 2H
293    srshl     v22.8h, v22.8h , v0.8h    //rounds off the weighted samples from row 4L
294    saddw     v28.8h, v28.8h , v3.8b    //adding offset for row 3L
295    srshl     v16.8h, v16.8h , v0.8h    //rounds off the weighted samples from row 4H
296    saddw     v12.8h, v12.8h , v3.8b    //adding offset for row 3H
297    sqxtun    v26.8b, v20.8h            //saturating row 1L to unsigned 8-bit
298    saddw     v22.8h, v22.8h , v3.8b    //adding offset for row 4L
299    sqxtun    v27.8b, v4.8h             //saturating row 1H to unsigned 8-bit
300    saddw     v16.8h, v16.8h , v3.8b    //adding offset for row 4H
301    sqxtun    v10.8b, v24.8h            //saturating row 2L to unsigned 8-bit
302    sqxtun    v11.8b, v8.8h             //saturating row 2H to unsigned 8-bit
303    sqxtun    v30.8b, v28.8h            //saturating row 3L to unsigned 8-bit
304    sqxtun    v31.8b, v12.8h            //saturating row 3H to unsigned 8-bit
305    st1       {v26.8b, v27.8b}, [x2], x5 //store row 1 in destination
306    sqxtun    v14.8b, v22.8h            //saturating row 4L to unsigned 8-bit
307    sqxtun    v15.8b, v16.8h            //saturating row 4H to unsigned 8-bit
308    st1       {v10.8b, v11.8b}, [x2], x5 //store row 2 in destination
309    subs      w11, w11, #4              //decrement ht by 4
310    st1       {v30.8b, v31.8b}, [x2], x5 //store row 3 in destination
311    st1       {v14.8b, v15.8b}, [x2], x5 //store row 4 in destination
312    bgt       loop_16                   //if greater than 0 repeat the loop again
313
314end_loops:
315
316    // LDMFD sp!,{x4-x12,x15}                //Reload the registers from sp
317    ldp       x19, x20, [sp], #16
318    pop_v_regs
319    ret
320
321
322//*******************************************************************************
323//* @function
324//*  ih264_weighted_bi_pred_chroma_av8()
325//*
326//* @brief
327//*  This routine performs the default weighted prediction as described in sec
328//* 8.4.2.3.2 titled "Weighted sample prediction process" for chroma.
329//*
330//* @par Description:
331//*  This function gets two ht x wd blocks, calculates the weighted samples,
332//* rounds off, adds offset and stores it in the destination block for U and V.
333//*
334//* @param[in] puc_src1
335//*  UWORD8 Pointer to the buffer containing the input block 1.
336//*
337//* @param[in] puc_src2
338//*  UWORD8 Pointer to the buffer containing the input block 2.
339//*
340//* @param[out] puc_dst
341//*  UWORD8 pointer to the destination where the output block is stored.
342//*
343//* @param[in] src_strd1
344//*  Stride of the input buffer 1
345//*
346//* @param[in] src_strd2
347//*  Stride of the input buffer 2
348//*
349//* @param[in] dst_strd
350//*  Stride of the destination buffer
351//*
352//* @param[in] log_WD
353//*  number of bits to be rounded off
354//*
355//* @param[in] wt1
356//*  weights for the weighted prediction in U and V
357//*
358//* @param[in] wt2
359//*  weights for the weighted prediction in U and V
360//*
361//* @param[in] ofst1
362//*  offset 1 used after rounding off for U an dV
363//*
364//* @param[in] ofst2
365//*  offset 2 used after rounding off for U and V
366//*
367//* @param[in] ht
368//*  integer height of the array
369//*
370//* @param[in] wd
371//*  integer width of the array
372//*
373//* @returns
374//*  None
375//*
376//* @remarks
377//*  (ht,wd) can be (2,2), (2,4), (4,2), (4,4), (4,8), (8,4) or (8,8).
378//*
379//*******************************************************************************
380//*/
381//void ih264_weighted_bi_pred_chroma_av8(UWORD8 *puc_src1,
382//                                       UWORD8 *puc_src2,
383//                                       UWORD8 *puc_dst,
384//                                       WORD32 src_strd1,
385//                                       WORD32 src_strd2,
386//                                       WORD32 dst_strd,
387//                                       UWORD16 log_WD,
388//                                       UWORD32 wt1,
389//                                       UWORD32 wt2,
390//                                       UWORD16 ofst1,
391//                                       UWORD16 ofst2,
392//                                       UWORD8 ht,
393//                                       UWORD8 wd)
394//
395//**************Variables Vs Registers*****************************************
396//    x0      => puc_src1
397//    x1      => puc_src2
398//    x2      => puc_dst
399//    x3      => src_strd1
400//    [sp]    => src_strd2 (x4)
401//    [sp+4]  => dst_strd  (x5)
402//    [sp+8]  => log_WD    (x6)
403//    [sp+12] => wt1       (x7)
404//   [sp+16] => wt2       (x8)
405//   [sp+20] => ofst1     (x9)
406//   [sp+24] => ofst2     (x10)
407//    [sp+28] => ht        (x11)
408//    [sp+32] => wd        (x12)
409//
410
411
412
413
414
415    .global ih264_weighted_bi_pred_chroma_av8
416
417ih264_weighted_bi_pred_chroma_av8:
418
419    // STMFD sp!, {x4-x12,x14}                //stack stores the values of the arguments
420    push_v_regs
421    stp       x19, x20, [sp, #-16]!
422
423
424    ldr       x8, [sp, #80]             //Load wt2 in x8
425    dup       v4.4s, w8                 //Q2 = (wt2_u, wt2_v) (32-bit)
426    dup       v2.4s, w7                 //Q1 = (wt1_u, wt1_v) (32-bit)
427    add       x6, x6, #1                //x6  = log_WD + 1
428    ldr       w9, [sp, #88]             //Load ofst1 in x9
429    sxtw      x9, w9
430    ldr       w10, [sp, #96]            //Load ofst2 in x10
431    sxtw      x10, w10
432    sub       x20, x6, #0               //x12 = -(log_WD + 1)
433    neg       x20, x20
434    dup       v0.8h, w20                //Q0  = -(log_WD + 1) (16-bit)
435    ldr       w11, [sp, #104]           //Load ht in x11
436    ldr       w12, [sp, #112]           //Load wd in x12
437    sxtw      x11, w11
438    sxtw      x12, w12
439    dup       v20.8h, w9                //0ffset1
440    dup       v21.8h, w10               //0ffset2
441    srhadd    v6.8b, v20.8b, v21.8b
442    sxtl      v6.8h, v6.8b
443    cmp       w12, #8                   //check if wd is 8
444    beq       loop_8_uv                 //branch if wd is 8
445    cmp       w12, #4                   //check if wd is 4
446    beq       loop_4_uv                 //branch if wd is 4
447
448loop_2_uv:                              //each iteration processes two rows
449
450    ld1       {v8.s}[0], [x0], x3       //load row 1 in source 1
451    ld1       {v8.s}[1], [x0], x3       //load row 2 in source 1
452    ld1       {v10.s}[0], [x1], x4      //load row 1 in source 2
453    ld1       {v10.s}[1], [x1], x4      //load row 2 in source 2
454    uxtl      v8.8h, v8.8b              //converting rows 1,2 in source 1 to 16-bit
455    uxtl      v10.8h, v10.8b            //converting rows 1,2 in source 2 to 16-bit
456    mul       v8.8h, v8.8h , v2.8h      //weight 1 mult. for rows 1,2
457    mla       v8.8h, v10.8h , v4.8h     //weight 2 mult. for rows 1,2
458    srshl     v8.8h, v8.8h , v0.8h      //rounds off the weighted samples from rows 1,2
459    add       v8.8h, v8.8h , v6.8h      //adding offset for rows 1,2
460    sqxtun    v8.8b, v8.8h              //saturating rows 1,2 to unsigned 8-bit/
461    st1       {v8.s}[0], [x2], x5       //store row 1 in destination
462    st1       {v8.s}[1], [x2], x5       //store row 2 in destination
463    subs      w11, w11, #2              //decrement ht by 2
464    bgt       loop_2_uv                 //if greater than 0 repeat the loop again
465    b         end_loops_uv
466
467loop_4_uv:                              //each iteration processes two rows
468
469    ld1       {v8.8b}, [x0], x3         //load row 1 in source 1
470    ld1       {v10.8b}, [x1], x4        //load row 1 in source 2
471    uxtl      v8.8h, v8.8b              //converting row 1 in source 1 to 16-bit
472    ld1       {v12.8b}, [x0], x3        //load row 2 in source 1
473    uxtl      v10.8h, v10.8b            //converting row 1 in source 2 to 16-bit
474    ld1       {v14.8b}, [x1], x4        //load row 2 in source 2
475    uxtl      v12.8h, v12.8b            //converting row 2 in source 1 to 16-bit
476    mul       v8.8h, v8.8h , v2.8h      //weight 1 mult. for row 1
477    mla       v8.8h, v10.8h , v4.8h     //weight 2 mult. for row 1
478    uxtl      v14.8h, v14.8b            //converting row 2 in source 2 to 16-bit
479    mul       v12.8h, v12.8h , v2.8h    //weight 1 mult. for row 2
480    mla       v12.8h, v14.8h , v4.8h    //weight 2 mult. for row 2
481    subs      w11, w11, #2              //decrement ht by 2
482    srshl     v8.8h, v8.8h , v0.8h      //rounds off the weighted samples from row 1
483    srshl     v12.8h, v12.8h , v0.8h    //rounds off the weighted samples from row 2
484    add       v8.8h, v8.8h , v6.8h      //adding offset for row 1
485    add       v12.8h, v12.8h , v6.8h    //adding offset for row 2
486    sqxtun    v8.8b, v8.8h              //saturating row 1 to unsigned 8-bit
487    sqxtun    v12.8b, v12.8h            //saturating row 2 to unsigned 8-bit
488    st1       {v8.8b}, [x2], x5         //store row 1 in destination
489    st1       {v12.8b}, [x2], x5        //store row 2 in destination
490    bgt       loop_4_uv                 //if greater than 0 repeat the loop again
491    b         end_loops_uv
492
493loop_8_uv:                              //each iteration processes two rows
494
495    ld1       {v8.8b, v9.8b}, [x0], x3  //load row 1 in source 1
496    ld1       {v10.8b, v11.8b}, [x1], x4 //load row 1 in source 2
497    ld1       {v12.8b, v13.8b}, [x0], x3 //load row 2 in source 1
498    ld1       {v14.8b, v15.8b}, [x1], x4 //load row 2 in source 2
499    uxtl      v24.8h, v8.8b             //converting row 1L in source 1 to 16-bit
500    ld1       {v16.8b, v17.8b}, [x0], x3 //load row 3 in source 1
501    ld1       {v18.8b, v19.8b}, [x1], x4 //load row 3 in source 2
502    uxtl      v26.8h, v10.8b            //converting row 1L in source 2 to 16-bit
503    ld1       {v20.8b, v21.8b}, [x0], x3 //load row 4 in source 1
504    ld1       {v22.8b, v23.8b}, [x1], x4 //load row 4 in source 2
505    uxtl      v8.8h, v9.8b              //converting row 1H in source 1 to 16-bit
506    uxtl      v10.8h, v11.8b            //converting row 1H in source 2 to 16-bit
507    mul       v24.8h, v24.8h , v2.8h    //weight 1 mult. for row 1L
508    mla       v24.8h, v26.8h , v4.8h    //weight 2 mult. for row 1L
509    uxtl      v28.8h, v12.8b            //converting row 2L in source 1 to 16-bit
510    uxtl      v30.8h, v14.8b            //converting row 2L in source 2 to 16-bit
511    mul       v8.8h, v8.8h , v2.8h      //weight 1 mult. for row 1H
512    mla       v8.8h, v10.8h , v4.8h     //weight 2 mult. for row 1H
513    uxtl      v12.8h, v13.8b            //converting row 2H in source 1 to 16-bit
514    uxtl      v14.8h, v15.8b            //converting row 2H in source 2 to 16-bit
515    mul       v28.8h, v28.8h , v2.8h    //weight 1 mult. for row 2L
516    mla       v28.8h, v30.8h , v4.8h    //weight 2 mult. for row 2L
517    uxtl      v26.8h, v16.8b            //converting row 3L in source 1 to 16-bit
518    uxtl      v10.8h, v18.8b            //converting row 3L in source 2 to 16-bit
519    mul       v12.8h, v12.8h , v2.8h    //weight 1 mult. for row 2H
520    mla       v12.8h, v14.8h , v4.8h    //weight 2 mult. for row 2H
521    uxtl      v16.8h, v17.8b            //converting row 3H in source 1 to 16-bit
522    uxtl      v18.8h, v19.8b            //converting row 3H in source 2 to 16-bit
523    mul       v26.8h, v26.8h , v2.8h    //weight 1 mult. for row 3L
524    mla       v26.8h, v10.8h , v4.8h    //weight 2 mult. for row 3L
525    uxtl      v30.8h, v20.8b            //converting row 4L in source 1 to 16-bit
526    uxtl      v14.8h, v22.8b            //converting row 4L in source 2 to 16-bit
527    mul       v16.8h, v16.8h , v2.8h    //weight 1 mult. for row 3H
528    mla       v16.8h, v18.8h , v4.8h    //weight 2 mult. for row 3H
529    uxtl      v20.8h, v21.8b            //converting row 4H in source 1 to 16-bit
530    uxtl      v22.8h, v23.8b            //converting row 4H in source 2 to 16-bit
531    mul       v30.8h, v30.8h , v2.8h    //weight 1 mult. for row 4L
532    mla       v30.8h, v14.8h , v4.8h    //weight 2 mult. for row 4L
533    srshl     v24.8h, v24.8h , v0.8h    //rounds off the weighted samples from row 1L
534    mul       v20.8h, v20.8h , v2.8h    //weight 1 mult. for row 4H
535    mla       v20.8h, v22.8h , v4.8h    //weight 2 mult. for row 4H
536    srshl     v8.8h, v8.8h , v0.8h      //rounds off the weighted samples from row 1H
537    srshl     v28.8h, v28.8h , v0.8h    //rounds off the weighted samples from row 2L
538    add       v24.8h, v24.8h , v6.8h    //adding offset for row 1L
539    srshl     v12.8h, v12.8h , v0.8h    //rounds off the weighted samples from row 2H
540    add       v8.8h, v8.8h , v6.8h      //adding offset for row 1H
541    srshl     v26.8h, v26.8h , v0.8h    //rounds off the weighted samples from row 3L
542    add       v28.8h, v28.8h , v6.8h    //adding offset for row 2L
543    srshl     v16.8h, v16.8h , v0.8h    //rounds off the weighted samples from row 3H
544    add       v12.8h, v12.8h , v6.8h    //adding offset for row 2H
545    srshl     v30.8h, v30.8h , v0.8h    //rounds off the weighted samples from row 4L
546    add       v26.8h, v26.8h , v6.8h    //adding offset for row 3L
547    srshl     v20.8h, v20.8h , v0.8h    //rounds off the weighted samples from row 4H
548    add       v16.8h, v16.8h , v6.8h    //adding offset for row 3H
549    sqxtun    v10.8b, v24.8h            //saturating row 1L to unsigned 8-bit
550    add       v30.8h, v30.8h , v6.8h    //adding offset for row 4L
551    sqxtun    v11.8b, v8.8h             //saturating row 1H to unsigned 8-bit
552    add       v20.8h, v20.8h , v6.8h    //adding offset for row 4H
553    sqxtun    v18.8b, v28.8h            //saturating row 2L to unsigned 8-bit
554    sqxtun    v19.8b, v12.8h            //saturating row 2H to unsigned 8-bit
555    sqxtun    v14.8b, v26.8h            //saturating row 3L to unsigned 8-bit
556    sqxtun    v15.8b, v16.8h            //saturating row 3H to unsigned 8-bit
557    st1       {v10.8b, v11.8b}, [x2], x5 //store row 1 in destination
558    sqxtun    v22.8b, v30.8h            //saturating row 4L to unsigned 8-bit
559    sqxtun    v23.8b, v20.8h            //saturating row 4H to unsigned 8-bit
560    st1       {v18.8b, v19.8b}, [x2], x5 //store row 2 in destination
561    subs      w11, w11, #4              //decrement ht by 4
562    st1       {v14.8b, v15.8b}, [x2], x5 //store row 3 in destination
563    st1       {v22.8b, v23.8b}, [x2], x5 //store row 4 in destination
564    bgt       loop_8_uv                 //if greater than 0 repeat the loop again
565
566end_loops_uv:
567
568    // LDMFD sp!,{x4-x12,x15}                //Reload the registers from sp
569    ldp       x19, x20, [sp], #16
570    pop_v_regs
571    ret
572
573
574
575