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