Home | History | Annotate | Download | only in arm
      1 @/*****************************************************************************
      2 @*
      3 @* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
      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 @/**
     19 @ *******************************************************************************
     20 @ * @file
     21 @ *  ihevc_itrans_recon_8x8_neon.s
     22 @ *
     23 @ * @brief
     24 @ *  contains function definitions for single stage  inverse transform
     25 @ *
     26 @ * @author
     27 @ * anand s
     28 @ *
     29 @ * @par list of functions:
     30 @ *  - ihevc_itrans_recon_16x16()
     31 @ *
     32 @ * @remarks
     33 @ *  none
     34 @ *
     35 @ *******************************************************************************
     36 @*/
     37 
     38 @/**
     39 @ *******************************************************************************
     40 @ *
     41 @ * @brief
     42 @ *  this function performs inverse transform  and reconstruction for 8x8
     43 @ * input block
     44 @ *
     45 @ * @par description:
     46 @ *  performs inverse transform and adds the prediction  data and clips output
     47 @ * to 8 bit
     48 @ *
     49 @ * @param[in] pi2_src
     50 @ *  input 16x16 coefficients
     51 @ *
     52 @ * @param[in] pi2_tmp
     53 @ *  temporary 16x16 buffer for storing inverse
     54 @ *
     55 @ *  transform
     56 @ *  1st stage output
     57 @ *
     58 @ * @param[in] pu1_pred
     59 @ *  prediction 16x16 block
     60 @ *
     61 @ * @param[out] pu1_dst
     62 @ *  output 8x8 block
     63 @ *
     64 @ * @param[in] src_strd
     65 @ *  input stride
     66 @ *
     67 @ * @param[in] pred_strd
     68 @ *  prediction stride
     69 @ *
     70 @ * @param[in] dst_strd
     71 @ *  output stride
     72 @ *
     73 @ * @param[in] shift
     74 @ *  output shift
     75 @ *
     76 @ * @param[in] r12
     77 @ *  zero columns in pi2_src
     78 @ *
     79 @ * @returns  void
     80 @ *
     81 @ * @remarks
     82 @ *  none
     83 @ *
     84 @ *******************************************************************************
     85 @ */
     86 
     87 @void ihevc_itrans_recon_16x16(word16 *pi2_src,
     88 @                            word16 *pi2_tmp,
     89 @                            uword8 *pu1_pred,
     90 @                            uword8 *pu1_dst,
     91 @                            word32 src_strd,
     92 @                            word32 pred_strd,
     93 @                            word32 dst_strd,
     94 @                            word32 r12
     95 @                            word32 r11             )
     96 
     97 @**************variables vs registers*************************
     98 @   r0 => *pi2_src
     99 @   r1 => *pi2_tmp
    100 @   r2 => *pu1_pred
    101 @   r3 => *pu1_dst
    102 @   src_strd
    103 @   pred_strd
    104 @   dst_strd
    105 @   r12
    106 @   r11
    107 
    108 .equ    src_stride_offset,     104
    109 .equ    pred_stride_offset,    108
    110 .equ    out_stride_offset,     112
    111 .equ    zero_cols_offset,      116
    112 .equ    zero_rows_offset,      120
    113 
    114 .text
    115 .align 4
    116 
    117 
    118 
    119 
    120 
    121 
    122 .set shift_stage1_idct ,   7
    123 .set shift_stage2_idct ,   12
    124 @#define zero_cols       r12
    125 @#define zero_rows       r11
    126 .globl ihevc_itrans_recon_16x16_a9q
    127 
    128 .extern g_ai2_ihevc_trans_16_transpose
    129 
    130 g_ai2_ihevc_trans_16_transpose_addr:
    131 .long g_ai2_ihevc_trans_16_transpose - ulbl1 - 8
    132 
    133 .type ihevc_itrans_recon_16x16_a9q, %function
    134 
    135 ihevc_itrans_recon_16x16_a9q:
    136 
    137     stmfd       sp!,{r4-r12,lr}
    138     vpush       {d8  -  d15}
    139     ldr         r6,[sp,#src_stride_offset]  @ src stride
    140     ldr         r12,[sp,#zero_cols_offset]
    141     ldr         r11,[sp,#zero_rows_offset]
    142 
    143 
    144 
    145     ldr         r14,g_ai2_ihevc_trans_16_transpose_addr
    146 ulbl1:
    147     add         r14,r14,pc
    148     vld1.16     {d0,d1,d2,d3},[r14]         @//d0,d1 are used for storing the constant data
    149     movw        r7,#0xffff
    150     and         r12,r12,r7
    151     and         r11,r11,r7
    152     mov         r6,r6,lsl #1                @ x sizeof(word16)
    153     add         r9,r0,r6, lsl #1            @ 2 rows
    154 
    155     add         r10,r6,r6, lsl #1           @ 3 rows
    156     add         r5,r6,r6,lsl #2
    157     movw        r7,#0xfff0
    158 
    159     cmp         r12,r7
    160     bge         zero_12cols_decision
    161 
    162     cmp         r12,#0xff00
    163     bge         zero_8cols_decision
    164 
    165 
    166 
    167 
    168     mov         r14,#4
    169     cmp         r11,r7
    170     rsbge       r10,r6,#0
    171 
    172     cmp         r11,#0xff00
    173     movge       r8,r5
    174     rsbge       r8,r8,#0
    175     movlt       r8,r10
    176     add         r5,r5,r6,lsl #3
    177     rsb         r5,r5,#0
    178 
    179     b           first_stage_top_four_bottom_four
    180 
    181 zero_12cols_decision:
    182     mov         r14,#1
    183     cmp         r11,#0xff00
    184     movge       r8,r5
    185     movlt       r8,r10
    186     add         r5,r5,r6,lsl #3
    187     rsb         r5,r5,#0
    188 
    189     b           first_stage_top_four_bottom_four
    190 
    191 zero_8cols_decision:
    192     mov         r14,#2
    193     mov         r8,r5
    194     rsb         r8,r8,#0
    195     cmp         r11,#0xff00
    196     movlt       r8,r10
    197     add         r5,r5,r6,lsl #3
    198     rsb         r5,r5,#0
    199     cmp         r11,r7
    200     rsbge       r10,r6,#0
    201 
    202 
    203     b           first_stage_top_four_bottom_four
    204 
    205 
    206 @d0[0]= 64      d2[0]=64
    207 @d0[1]= 90      d2[1]=57
    208 @d0[2]= 89      d2[2]=50
    209 @d0[3]= 87      d2[3]=43
    210 @d1[0]= 83      d3[0]=36
    211 @d1[1]= 80      d3[1]=25
    212 @d1[2]= 75      d3[2]=18
    213 @d1[3]= 70      d3[3]=9
    214 
    215 
    216 
    217 first_stage:
    218     add         r0,r0,#8
    219     add         r9,r9,#8
    220 
    221 first_stage_top_four_bottom_four:
    222 
    223     vld1.16     d10,[r0],r6
    224     vld1.16     d11,[r9],r6
    225     vld1.16     d6,[r0],r10
    226     vld1.16     d7,[r9],r10
    227     cmp         r11,r7
    228     bge         skip_load4rows
    229 
    230     vld1.16     d4,[r0],r6
    231     vld1.16     d5,[r9],r6
    232     vld1.16     d8,[r0],r8
    233     vld1.16     d9,[r9],r8
    234 
    235 @ registers used: q0,q1,q3,q5,q2,q4
    236 
    237 @ d10 =r0
    238 @d6= r1
    239 @d11=r2
    240 @d7=r3
    241 
    242 skip_load4rows:
    243     vmull.s16   q12,d6,d0[1]                @// y1 * cos1(part of b0)
    244     vmull.s16   q13,d6,d0[3]                @// y1 * cos3(part of b1)
    245     vmull.s16   q14,d6,d1[1]                @// y1 * sin3(part of b2)
    246     vmull.s16   q15,d6,d1[3]                @// y1 * sin1(part of b3)
    247 
    248     vmlal.s16   q12,d7,d0[3]                @// y1 * cos1 + y3 * cos3(part of b0)
    249     vmlal.s16   q13,d7,d2[1]                @// y1 * cos3 - y3 * sin1(part of b1)
    250     vmlal.s16   q14,d7,d3[3]                @// y1 * sin3 - y3 * cos1(part of b2)
    251     vmlsl.s16   q15,d7,d2[3]                @// y1 * sin1 - y3 * sin3(part of b3)
    252 
    253 
    254 
    255 
    256 
    257 
    258     vmull.s16   q6,d10,d0[0]
    259     vmlal.s16   q6,d11,d0[2]
    260     vmull.s16   q7,d10,d0[0]
    261     vmlal.s16   q7,d11,d1[2]
    262     vmull.s16   q8,d10,d0[0]
    263     vmlal.s16   q8,d11,d2[2]
    264     vmull.s16   q9,d10,d0[0]
    265     vmlal.s16   q9,d11,d3[2]
    266 
    267     bge         skip_last12rows_kernel1
    268 
    269 
    270     vmlal.s16   q12,d8,d1[1]
    271     vmlal.s16   q13,d8,d3[3]
    272     vmlsl.s16   q14,d8,d1[3]
    273     vmlsl.s16   q15,d8,d0[3]
    274 
    275 
    276     vmlal.s16   q12,d9,d1[3]
    277     vmlsl.s16   q13,d9,d2[3]
    278     vmlsl.s16   q14,d9,d0[3]
    279     vmlal.s16   q15,d9,d3[3]
    280 
    281 
    282 
    283 
    284 
    285     vmlal.s16   q6,d4,d1[0]
    286     vmlal.s16   q6,d5,d1[2]
    287     vmlal.s16   q7,d4,d3[0]
    288     vmlsl.s16   q7,d5,d3[2]
    289     vmlsl.s16   q8,d4,d3[0]
    290     vmlsl.s16   q8,d5,d0[2]
    291     vmlsl.s16   q9,d4,d1[0]
    292     vmlsl.s16   q9,d5,d2[2]
    293 
    294 @d0[0]= 64      d2[0]=64
    295 @d0[1]= 90      d2[1]=57
    296 @d0[2]= 89      d2[2]=50
    297 @d0[3]= 87      d2[3]=43
    298 @d1[0]= 83      d3[0]=36
    299 @d1[1]= 80      d3[1]=25
    300 @d1[2]= 75      d3[2]=18
    301 @d1[3]= 70      d3[3]=9
    302     cmp         r11,#0xff00
    303     bge         skip_last12rows_kernel1
    304 
    305 
    306     vld1.16     d10,[r0],r6
    307     vld1.16     d11,[r9],r6
    308     vld1.16     d6,[r0],r10
    309     vld1.16     d7,[r9],r10
    310     vld1.16     d4,[r0],r6
    311     vld1.16     d5,[r9],r6
    312     vld1.16     d8,[r0],r5
    313     vld1.16     d9,[r9],r5
    314 
    315 
    316 
    317 
    318     vmlal.s16   q12,d6,d2[1]                @// y1 * cos1(part of b0)
    319     vmlsl.s16   q13,d6,d1[1]                @// y1 * cos3(part of b1)
    320     vmlsl.s16   q14,d6,d3[1]                @// y1 * sin3(part of b2)
    321     vmlal.s16   q15,d6,d0[1]                @// y1 * sin1(part of b3)
    322 
    323     vmlal.s16   q12,d7,d2[3]                @// y1 * cos1 + y3 * cos3(part of b0)
    324     vmlsl.s16   q13,d7,d0[1]                @// y1 * cos3 - y3 * sin1(part of b1)
    325     vmlal.s16   q14,d7,d2[1]                @// y1 * sin3 - y3 * cos1(part of b2)
    326     vmlal.s16   q15,d7,d3[1]                @// y1 * sin1 - y3 * sin3(part of b3)
    327 
    328 
    329 
    330     vmlal.s16   q12,d8,d3[1]
    331     vmlsl.s16   q13,d8,d1[3]
    332     vmlal.s16   q14,d8,d0[1]
    333     vmlsl.s16   q15,d8,d1[1]
    334 
    335 
    336     vmlal.s16   q12,d9,d3[3]
    337     vmlsl.s16   q13,d9,d3[1]
    338     vmlal.s16   q14,d9,d2[3]
    339     vmlsl.s16   q15,d9,d2[1]
    340 
    341 
    342 
    343 
    344 
    345     vmlal.s16   q6,d10,d0[0]
    346     vmlal.s16   q6,d11,d2[2]
    347     vmlal.s16   q6,d4,d3[0]
    348     vmlal.s16   q6,d5,d3[2]
    349 
    350 
    351 
    352 
    353     vmlsl.s16   q7,d10,d0[0]
    354     vmlsl.s16   q7,d11,d0[2]
    355     vmlsl.s16   q7,d4,d1[0]
    356     vmlsl.s16   q7,d5,d2[2]
    357 
    358 
    359     vmlsl.s16   q8,d10,d0[0]
    360     vmlal.s16   q8,d11,d3[2]
    361     vmlal.s16   q8,d4,d1[0]
    362     vmlal.s16   q8,d5,d1[2]
    363 
    364 
    365     vmlal.s16   q9,d10,d0[0]
    366     vmlal.s16   q9,d11,d1[2]
    367     vmlsl.s16   q9,d4,d3[0]
    368     vmlsl.s16   q9,d5,d0[2]
    369 
    370 skip_last12rows_kernel1:
    371     vadd.s32    q10,q6,q12
    372     vsub.s32    q11,q6,q12
    373 
    374     vadd.s32    q6,q7,q13
    375     vsub.s32    q12,q7,q13
    376 
    377     vadd.s32    q7,q8,q14
    378     vsub.s32    q13,q8,q14
    379 
    380 
    381     vadd.s32    q8,q9,q15
    382     vsub.s32    q14,q9,q15
    383 
    384 
    385 
    386 
    387 
    388 
    389 
    390     vqrshrn.s32 d30,q10,#shift_stage1_idct  @// r0 = (a0 + b0 + rnd) >> 7(shift_stage1_idct)
    391     vqrshrn.s32 d19,q11,#shift_stage1_idct  @// r7 = (a0 - b0 + rnd) >> 7(shift_stage1_idct)
    392     vqrshrn.s32 d31,q7,#shift_stage1_idct   @// r2 = (a2 + b2 + rnd) >> 7(shift_stage1_idct)
    393     vqrshrn.s32 d18,q13,#shift_stage1_idct  @// r5 = (a2 - b2 + rnd) >> 7(shift_stage1_idct)
    394     vqrshrn.s32 d12,q6,#shift_stage1_idct   @// r1 = (a1 + b1 + rnd) >> 7(shift_stage1_idct)
    395     vqrshrn.s32 d15,q12,#shift_stage1_idct  @// r6 = (a1 - b1 + rnd) >> 7(shift_stage1_idct)
    396     vqrshrn.s32 d13,q8,#shift_stage1_idct   @// r3 = (a3 + b3 + rnd) >> 7(shift_stage1_idct)
    397     vqrshrn.s32 d14,q14,#shift_stage1_idct  @// r4 = (a3 - b3 + rnd) >> 7(shift_stage1_idct)
    398 
    399     vst1.16     {d30,d31},[r1]!
    400     vst1.16     {d18,d19},[r1]!
    401     sub         r1,r1,#32
    402 
    403     bge         skip_stage1_kernel_load
    404 
    405 first_stage_middle_eight:
    406 
    407 
    408 
    409     vld1.16     d10,[r0],r6
    410     vld1.16     d11,[r9],r6
    411     vld1.16     d6,[r0],r10
    412     vld1.16     d7,[r9],r10
    413     vld1.16     d4,[r0],r6
    414     vld1.16     d5,[r9],r6
    415     vld1.16     d8,[r0],r8
    416     vld1.16     d9,[r9],r8
    417 
    418 
    419 skip_stage1_kernel_load:
    420     vmull.s16   q12,d6,d2[1]                @// y1 * cos1(part of b0)
    421     vmull.s16   q13,d6,d2[3]                @// y1 * cos3(part of b1)
    422     vmull.s16   q14,d6,d3[1]                @// y1 * sin3(part of b2)
    423     vmull.s16   q15,d6,d3[3]                @// y1 * sin1(part of b3)
    424 
    425     vmlsl.s16   q12,d7,d1[1]                @// y1 * cos1 + y3 * cos3(part of b0)
    426     vmlsl.s16   q13,d7,d0[1]                @// y1 * cos3 - y3 * sin1(part of b1)
    427     vmlsl.s16   q14,d7,d1[3]                @// y1 * sin3 - y3 * cos1(part of b2)
    428     vmlsl.s16   q15,d7,d3[1]                @// y1 * sin1 - y3 * sin3(part of b3)
    429 
    430 
    431 
    432 
    433 
    434 
    435     vmull.s16   q11,d10,d0[0]
    436     vmlsl.s16   q11,d11,d3[2]
    437     vmull.s16   q10,d10,d0[0]
    438     vmlsl.s16   q10,d11,d2[2]
    439     vmull.s16   q8,d10,d0[0]
    440     vmlsl.s16   q8,d11,d1[2]
    441     vmull.s16   q9,d10,d0[0]
    442     vmlsl.s16   q9,d11,d0[2]
    443 
    444 
    445     cmp         r11,r7
    446     bge         skip_last12rows_kernel2
    447 
    448     vmlsl.s16   q12,d8,d3[1]
    449     vmlal.s16   q13,d8,d2[1]
    450     vmlal.s16   q14,d8,d0[1]
    451     vmlal.s16   q15,d8,d2[3]
    452 
    453 
    454     vmlal.s16   q12,d9,d0[1]
    455     vmlal.s16   q13,d9,d3[1]
    456     vmlsl.s16   q14,d9,d1[1]
    457     vmlsl.s16   q15,d9,d2[1]
    458 
    459 
    460 
    461     vmlsl.s16   q11,d4,d1[0]
    462     vmlal.s16   q11,d5,d2[2]
    463     vmlsl.s16   q10,d4,d3[0]
    464     vmlal.s16   q10,d5,d0[2]
    465     vmlal.s16   q8,d4,d3[0]
    466     vmlal.s16   q8,d5,d3[2]
    467     vmlal.s16   q9,d4,d1[0]
    468     vmlsl.s16   q9,d5,d1[2]
    469 
    470 @d0[0]= 64      d2[0]=64
    471 @d0[1]= 90      d2[1]=57
    472 @d0[2]= 89      d2[2]=50
    473 @d0[3]= 87      d2[3]=43
    474 @d1[0]= 83      d3[0]=36
    475 @d1[1]= 80      d3[1]=25
    476 @d1[2]= 75      d3[2]=18
    477 @d1[3]= 70      d3[3]=9
    478     cmp         r11,#0xff00
    479     bge         skip_last12rows_kernel2
    480 
    481     vld1.16     d10,[r0],r6
    482     vld1.16     d11,[r9],r6
    483     vld1.16     d6,[r0],r10
    484     vld1.16     d7,[r9],r10
    485     vld1.16     d4,[r0],r6
    486     vld1.16     d5,[r9],r6
    487     vld1.16     d8,[r0],r5
    488     vld1.16     d9,[r9],r5
    489 
    490 
    491     vmlsl.s16   q12,d6,d3[3]                @// y1 * cos1(part of b0)
    492     vmlsl.s16   q13,d6,d0[3]                @// y1 * cos3(part of b1)
    493     vmlal.s16   q14,d6,d2[3]                @// y1 * sin3(part of b2)
    494     vmlal.s16   q15,d6,d1[3]                @// y1 * sin1(part of b3)
    495 
    496     vmlsl.s16   q12,d7,d0[3]                @// y1 * cos1 + y3 * cos3(part of b0)
    497     vmlal.s16   q13,d7,d1[3]                @// y1 * cos3 - y3 * sin1(part of b1)
    498     vmlal.s16   q14,d7,d3[3]                @// y1 * sin3 - y3 * cos1(part of b2)
    499     vmlsl.s16   q15,d7,d1[1]                @// y1 * sin1 - y3 * sin3(part of b3)
    500 
    501 
    502     vmlal.s16   q12,d8,d2[3]
    503     vmlal.s16   q13,d8,d3[3]
    504     vmlsl.s16   q14,d8,d2[1]
    505     vmlal.s16   q15,d8,d0[3]
    506 
    507 
    508     vmlal.s16   q12,d9,d1[3]
    509     vmlsl.s16   q13,d9,d1[1]
    510     vmlal.s16   q14,d9,d0[3]
    511     vmlsl.s16   q15,d9,d0[1]
    512 
    513 
    514 
    515 
    516     vmlal.s16   q11,d10,d0[0]
    517     vmlsl.s16   q11,d11,d1[2]
    518     vmlsl.s16   q11,d4,d3[0]
    519     vmlal.s16   q11,d5,d0[2]
    520 
    521 
    522 
    523     vmlsl.s16   q10,d10,d0[0]
    524     vmlsl.s16   q10,d11,d3[2]
    525     vmlal.s16   q10,d4,d1[0]
    526     vmlsl.s16   q10,d5,d1[2]
    527 
    528 
    529     vmlsl.s16   q8,d10,d0[0]
    530     vmlal.s16   q8,d11,d0[2]
    531     vmlsl.s16   q8,d4,d1[0]
    532     vmlal.s16   q8,d5,d2[2]
    533 
    534 
    535 
    536     vmlal.s16   q9,d10,d0[0]
    537     vmlsl.s16   q9,d11,d2[2]
    538     vmlal.s16   q9,d4,d3[0]
    539     vmlsl.s16   q9,d5,d3[2]
    540 
    541 skip_last12rows_kernel2:
    542 
    543     vadd.s32    q2,q11,q12
    544     vsub.s32    q11,q11,q12
    545 
    546     vadd.s32    q3,q10,q13
    547     vsub.s32    q12,q10,q13
    548 
    549     vadd.s32    q5,q8,q14
    550     vsub.s32    q13,q8,q14
    551 
    552 
    553     vadd.s32    q8,q9,q15
    554     vsub.s32    q14,q9,q15
    555 
    556 
    557     vqrshrn.s32 d18,q2,#shift_stage1_idct   @// r0 = (a0 + b0 + rnd) >> 7(shift_stage1_idct)
    558     vqrshrn.s32 d31,q11,#shift_stage1_idct  @// r7 = (a0 - b0 + rnd) >> 7(shift_stage1_idct)
    559     vqrshrn.s32 d19,q5,#shift_stage1_idct   @// r2 = (a2 + b2 + rnd) >> 7(shift_stage1_idct)
    560     vqrshrn.s32 d30,q13,#shift_stage1_idct  @// r5 = (a2 - b2 + rnd) >> 7(shift_stage1_idct)
    561     vqrshrn.s32 d20,q3,#shift_stage1_idct   @// r1 = (a1 + b1 + rnd) >> 7(shift_stage1_idct)
    562     vqrshrn.s32 d23,q12,#shift_stage1_idct  @// r6 = (a1 - b1 + rnd) >> 7(shift_stage1_idct)
    563     vqrshrn.s32 d21,q8,#shift_stage1_idct   @// r3 = (a3 + b3 + rnd) >> 7(shift_stage1_idct)
    564     vqrshrn.s32 d22,q14,#shift_stage1_idct  @// r4 = (a3 - b3 + rnd) >> 7(shift_stage1_idct)
    565 
    566 
    567     @ registers used:   {q2,q4,q6,q7}, {q9,q15,q10,q11}
    568 
    569 
    570 
    571 
    572 
    573 
    574     vld1.16     {d4,d5},[r1]!
    575     vld1.16     {d8,d9},[r1]!
    576     sub         r1,r1,#32
    577 
    578 @d4=r0
    579 @d12=r1
    580 @d5=r2
    581 @d13=r3
    582 
    583 @d18=r4
    584 @d20=r5
    585 @d19=r6
    586 @d21=r7
    587 
    588 @d22=r8
    589 @d30=r9
    590 @d23=r10
    591 @d31=r11
    592 
    593 @d14=r12
    594 @d8=r13
    595 @d15=r14
    596 @d9=r15
    597 
    598 
    599     vtrn.16     q2,q6
    600     vtrn.16     q9,q10
    601     vtrn.16     q11,q15
    602     vtrn.16     q7,q4
    603 
    604 
    605 
    606     vtrn.32     d4,d5
    607     vtrn.32     d12,d13
    608 
    609     vtrn.32     d18,d19
    610     vtrn.32     d20,d21
    611 
    612     vtrn.32     d22,d23
    613     vtrn.32     d30,d31
    614 
    615     vtrn.32     d14,d15
    616     vtrn.32     d8,d9
    617 
    618 
    619 @ d4 =r0 1- 4 values
    620 @ d5 =r2 1- 4 values
    621 @ d12=r1 1- 4 values
    622 @ d13=r3 1- 4 values
    623 
    624 @ d18 =r0 5- 8 values
    625 @ d19 =r2 5- 8 values
    626 @ d20=r1 5- 8 values
    627 @ d21=r3 5- 8 values
    628 
    629 @ d22 =r0 9- 12 values
    630 @ d23 =r2 9- 12 values
    631 @ d30=r1 9- 12 values
    632 @ d31=r3 9- 12 values
    633 
    634 @ d14 =r0 13-16 values
    635 @ d15 =r2 13- 16 values
    636 @ d8=r1 13- 16 values
    637 @ d9=r3 13- 16 values
    638 
    639 
    640     vst1.16     {q2},[r1]!
    641     vst1.16     {q6},[r1]!
    642 
    643     vst1.16     {q9},[r1]!
    644     vst1.16     {q10},[r1]!
    645     vst1.16     {q11},[r1]!
    646     vst1.16     {q15},[r1]!
    647     vst1.16     {q7},[r1]!
    648     vst1.16     {q4},[r1]!
    649 
    650 
    651     subs        r14,r14,#1
    652     bne         first_stage
    653 
    654 
    655 
    656 
    657 
    658 
    659 
    660 
    661 
    662 
    663     mov         r6,r7
    664 
    665     ldr         r8,[sp,#pred_stride_offset] @ prediction stride
    666     ldr         r7,[sp,#out_stride_offset]  @ destination stride
    667 
    668     mov         r10,#16
    669 
    670     cmp         r12,r6
    671     subge       r1,r1,#128
    672     bge         label1
    673 
    674     cmp         r12,#0xff00
    675     subge       r1,r1,#256
    676     bge         label_2
    677 
    678     sub         r1,r1,#512
    679     rsb         r10,r10,#0
    680 
    681 label_2:
    682     add         r9,r1,#128
    683     add         r11,r9,#128
    684     add         r0,r11,#128
    685 
    686 
    687 
    688 label1:
    689 @   mov   r6,r1
    690 
    691 
    692     mov         r14,#4
    693     add         r4,r2,r8, lsl #1            @ r4 = r2 + pred_strd * 2    => r4 points to 3rd row of pred data
    694     add         r5,r8,r8, lsl #1            @
    695 @   add r0,r3,r7, lsl #1    @ r0 points to 3rd row of dest data
    696 @   add r10,r7,r7, lsl #1   @
    697 
    698 
    699 
    700 
    701 second_stage:
    702     vld1.16     {d10,d11},[r1]!
    703     vld1.16     {d6,d7},[r1],r10
    704     cmp         r12,r6
    705     bge         second_stage_process
    706     vld1.16     {d4,d5},[r9]!
    707     vld1.16     {d8,d9},[r9],r10
    708 
    709 second_stage_process:
    710 
    711 
    712     vmull.s16   q12,d6,d0[1]                @// y1 * cos1(part of b0)
    713     vmull.s16   q13,d6,d0[3]                @// y1 * cos3(part of b1)
    714     vmull.s16   q14,d6,d1[1]                @// y1 * sin3(part of b2)
    715     vmull.s16   q15,d6,d1[3]                @// y1 * sin1(part of b3)
    716 
    717     vmlal.s16   q12,d7,d0[3]                @// y1 * cos1 + y3 * cos3(part of b0)
    718     vmlal.s16   q13,d7,d2[1]                @// y1 * cos3 - y3 * sin1(part of b1)
    719     vmlal.s16   q14,d7,d3[3]                @// y1 * sin3 - y3 * cos1(part of b2)
    720     vmlsl.s16   q15,d7,d2[3]                @// y1 * sin1 - y3 * sin3(part of b3)
    721 
    722 
    723     vmull.s16   q6,d10,d0[0]
    724     vmlal.s16   q6,d11,d0[2]
    725     vmull.s16   q7,d10,d0[0]
    726     vmlal.s16   q7,d11,d1[2]
    727     vmull.s16   q8,d10,d0[0]
    728     vmlal.s16   q8,d11,d2[2]
    729     vmull.s16   q9,d10,d0[0]
    730     vmlal.s16   q9,d11,d3[2]
    731 
    732     bge         skip_last8rows_stage2_kernel1
    733 
    734     vmlal.s16   q12,d8,d1[1]
    735     vmlal.s16   q13,d8,d3[3]
    736     vmlsl.s16   q14,d8,d1[3]
    737     vmlsl.s16   q15,d8,d0[3]
    738 
    739 
    740     vmlal.s16   q12,d9,d1[3]
    741     vmlsl.s16   q13,d9,d2[3]
    742     vmlsl.s16   q14,d9,d0[3]
    743     vmlal.s16   q15,d9,d3[3]
    744 
    745 
    746     vmlal.s16   q6,d4,d1[0]
    747     vmlal.s16   q6,d5,d1[2]
    748     vmlal.s16   q7,d4,d3[0]
    749     vmlsl.s16   q7,d5,d3[2]
    750     vmlsl.s16   q8,d4,d3[0]
    751     vmlsl.s16   q8,d5,d0[2]
    752     vmlsl.s16   q9,d4,d1[0]
    753     vmlsl.s16   q9,d5,d2[2]
    754 
    755     cmp         r12,#0xff00
    756     bge         skip_last8rows_stage2_kernel1
    757 
    758 
    759     vld1.16     {d10,d11},[r11]!
    760     vld1.16     {d6,d7},[r11],r10
    761     vld1.16     {d4,d5},[r0]!
    762     vld1.16     {d8,d9},[r0],r10
    763 
    764 
    765 
    766 
    767 
    768     vmlal.s16   q12,d6,d2[1]                @// y1 * cos1(part of b0)
    769     vmlsl.s16   q13,d6,d1[1]                @// y1 * cos3(part of b1)
    770     vmlsl.s16   q14,d6,d3[1]                @// y1 * sin3(part of b2)
    771     vmlal.s16   q15,d6,d0[1]                @// y1 * sin1(part of b3)
    772 
    773     vmlal.s16   q12,d7,d2[3]                @// y1 * cos1 + y3 * cos3(part of b0)
    774     vmlsl.s16   q13,d7,d0[1]                @// y1 * cos3 - y3 * sin1(part of b1)
    775     vmlal.s16   q14,d7,d2[1]                @// y1 * sin3 - y3 * cos1(part of b2)
    776     vmlal.s16   q15,d7,d3[1]                @// y1 * sin1 - y3 * sin3(part of b3)
    777 
    778 
    779 
    780     vmlal.s16   q12,d8,d3[1]
    781     vmlsl.s16   q13,d8,d1[3]
    782     vmlal.s16   q14,d8,d0[1]
    783     vmlsl.s16   q15,d8,d1[1]
    784 
    785 
    786     vmlal.s16   q12,d9,d3[3]
    787     vmlsl.s16   q13,d9,d3[1]
    788     vmlal.s16   q14,d9,d2[3]
    789     vmlsl.s16   q15,d9,d2[1]
    790 
    791 
    792 
    793 
    794 
    795     vmlal.s16   q6,d10,d0[0]
    796     vmlal.s16   q6,d11,d2[2]
    797     vmlal.s16   q6,d4,d3[0]
    798     vmlal.s16   q6,d5,d3[2]
    799 
    800 
    801 
    802 
    803     vmlsl.s16   q7,d10,d0[0]
    804     vmlsl.s16   q7,d11,d0[2]
    805     vmlsl.s16   q7,d4,d1[0]
    806     vmlsl.s16   q7,d5,d2[2]
    807 
    808 
    809     vmlsl.s16   q8,d10,d0[0]
    810     vmlal.s16   q8,d11,d3[2]
    811     vmlal.s16   q8,d4,d1[0]
    812     vmlal.s16   q8,d5,d1[2]
    813 
    814 
    815     vmlal.s16   q9,d10,d0[0]
    816     vmlal.s16   q9,d11,d1[2]
    817     vmlsl.s16   q9,d4,d3[0]
    818     vmlsl.s16   q9,d5,d0[2]
    819 
    820 
    821 
    822 
    823 
    824 
    825 skip_last8rows_stage2_kernel1:
    826 
    827 
    828 
    829     vadd.s32    q10,q6,q12
    830     vsub.s32    q11,q6,q12
    831 
    832     vadd.s32    q6,q7,q13
    833     vsub.s32    q12,q7,q13
    834 
    835     vadd.s32    q7,q8,q14
    836     vsub.s32    q13,q8,q14
    837 
    838 
    839     vadd.s32    q8,q9,q15
    840     vsub.s32    q14,q9,q15
    841 
    842 
    843 
    844 
    845 
    846 
    847 
    848     vqrshrn.s32 d30,q10,#shift_stage2_idct  @// r0 = (a0 + b0 + rnd) >> 7(shift_stage1_idct)
    849     vqrshrn.s32 d19,q11,#shift_stage2_idct  @// r7 = (a0 - b0 + rnd) >> 7(shift_stage1_idct)
    850     vqrshrn.s32 d31,q7,#shift_stage2_idct   @// r2 = (a2 + b2 + rnd) >> 7(shift_stage1_idct)
    851     vqrshrn.s32 d18,q13,#shift_stage2_idct  @// r5 = (a2 - b2 + rnd) >> 7(shift_stage1_idct)
    852     vqrshrn.s32 d12,q6,#shift_stage2_idct   @// r1 = (a1 + b1 + rnd) >> 7(shift_stage1_idct)
    853     vqrshrn.s32 d15,q12,#shift_stage2_idct  @// r6 = (a1 - b1 + rnd) >> 7(shift_stage1_idct)
    854     vqrshrn.s32 d13,q8,#shift_stage2_idct   @// r3 = (a3 + b3 + rnd) >> 7(shift_stage1_idct)
    855     vqrshrn.s32 d14,q14,#shift_stage2_idct  @// r4 = (a3 - b3 + rnd) >> 7(shift_stage1_idct)
    856 
    857     bge         skip_stage2_kernel_load
    858 
    859     @q2,q4,q6,q7 is used
    860     vld1.16     {d10,d11},[r1]!
    861     vld1.16     {d6,d7},[r1]!
    862     vld1.16     {d4,d5},[r9]!
    863     vld1.16     {d8,d9},[r9]!
    864 skip_stage2_kernel_load:
    865     sub         r1,r1,#32
    866     vst1.16     {d30,d31},[r1]!
    867     vst1.16     {d18,d19},[r1]!
    868     sub         r1,r1,#32
    869 
    870     vmull.s16   q12,d6,d2[1]                @// y1 * cos1(part of b0)
    871     vmull.s16   q13,d6,d2[3]                @// y1 * cos3(part of b1)
    872     vmull.s16   q14,d6,d3[1]                @// y1 * sin3(part of b2)
    873     vmull.s16   q15,d6,d3[3]                @// y1 * sin1(part of b3)
    874 
    875     vmlsl.s16   q12,d7,d1[1]                @// y1 * cos1 + y3 * cos3(part of b0)
    876     vmlsl.s16   q13,d7,d0[1]                @// y1 * cos3 - y3 * sin1(part of b1)
    877     vmlsl.s16   q14,d7,d1[3]                @// y1 * sin3 - y3 * cos1(part of b2)
    878     vmlsl.s16   q15,d7,d3[1]                @// y1 * sin1 - y3 * sin3(part of b3)
    879 
    880 
    881     vmull.s16   q11,d10,d0[0]
    882     vmlsl.s16   q11,d11,d3[2]
    883     vmull.s16   q10,d10,d0[0]
    884     vmlsl.s16   q10,d11,d2[2]
    885     vmull.s16   q8,d10,d0[0]
    886     vmlsl.s16   q8,d11,d1[2]
    887     vmull.s16   q9,d10,d0[0]
    888     vmlsl.s16   q9,d11,d0[2]
    889 
    890 
    891 
    892     cmp         r12,r6
    893     bge         skip_last8rows_stage2_kernel2
    894 
    895 
    896     vmlsl.s16   q12,d8,d3[1]
    897     vmlal.s16   q13,d8,d2[1]
    898     vmlal.s16   q14,d8,d0[1]
    899     vmlal.s16   q15,d8,d2[3]
    900 
    901 
    902     vmlal.s16   q12,d9,d0[1]
    903     vmlal.s16   q13,d9,d3[1]
    904     vmlsl.s16   q14,d9,d1[1]
    905     vmlsl.s16   q15,d9,d2[1]
    906 
    907 
    908 
    909     vmlsl.s16   q11,d4,d1[0]
    910     vmlal.s16   q11,d5,d2[2]
    911     vmlsl.s16   q10,d4,d3[0]
    912     vmlal.s16   q10,d5,d0[2]
    913     vmlal.s16   q8,d4,d3[0]
    914     vmlal.s16   q8,d5,d3[2]
    915     vmlal.s16   q9,d4,d1[0]
    916     vmlsl.s16   q9,d5,d1[2]
    917     cmp         r12,#0xff00
    918     bge         skip_last8rows_stage2_kernel2
    919 
    920     vld1.16     {d10,d11},[r11]!
    921     vld1.16     {d6,d7},[r11]!
    922     vld1.16     {d4,d5},[r0]!
    923     vld1.16     {d8,d9},[r0]!
    924 
    925     vmlsl.s16   q12,d6,d3[3]                @// y1 * cos1(part of b0)
    926     vmlsl.s16   q13,d6,d0[3]                @// y1 * cos3(part of b1)
    927     vmlal.s16   q14,d6,d2[3]                @// y1 * sin3(part of b2)
    928     vmlal.s16   q15,d6,d1[3]                @// y1 * sin1(part of b3)
    929 
    930     vmlsl.s16   q12,d7,d0[3]                @// y1 * cos1 + y3 * cos3(part of b0)
    931     vmlal.s16   q13,d7,d1[3]                @// y1 * cos3 - y3 * sin1(part of b1)
    932     vmlal.s16   q14,d7,d3[3]                @// y1 * sin3 - y3 * cos1(part of b2)
    933     vmlsl.s16   q15,d7,d1[1]                @// y1 * sin1 - y3 * sin3(part of b3)
    934 
    935 
    936     vmlal.s16   q12,d8,d2[3]
    937     vmlal.s16   q13,d8,d3[3]
    938     vmlsl.s16   q14,d8,d2[1]
    939     vmlal.s16   q15,d8,d0[3]
    940 
    941 
    942     vmlal.s16   q12,d9,d1[3]
    943     vmlsl.s16   q13,d9,d1[1]
    944     vmlal.s16   q14,d9,d0[3]
    945     vmlsl.s16   q15,d9,d0[1]
    946 
    947 
    948 
    949 
    950     vmlal.s16   q11,d10,d0[0]
    951     vmlsl.s16   q11,d11,d1[2]
    952     vmlsl.s16   q11,d4,d3[0]
    953     vmlal.s16   q11,d5,d0[2]
    954 
    955 
    956 
    957     vmlsl.s16   q10,d10,d0[0]
    958     vmlsl.s16   q10,d11,d3[2]
    959     vmlal.s16   q10,d4,d1[0]
    960     vmlsl.s16   q10,d5,d1[2]
    961 
    962 
    963     vmlsl.s16   q8,d10,d0[0]
    964     vmlal.s16   q8,d11,d0[2]
    965     vmlsl.s16   q8,d4,d1[0]
    966     vmlal.s16   q8,d5,d2[2]
    967 
    968 
    969 
    970     vmlal.s16   q9,d10,d0[0]
    971     vmlsl.s16   q9,d11,d2[2]
    972     vmlal.s16   q9,d4,d3[0]
    973     vmlsl.s16   q9,d5,d3[2]
    974 
    975 
    976 skip_last8rows_stage2_kernel2:
    977 
    978 
    979 
    980     vadd.s32    q2,q11,q12
    981     vsub.s32    q11,q11,q12
    982 
    983     vadd.s32    q3,q10,q13
    984     vsub.s32    q12,q10,q13
    985 
    986     vadd.s32    q5,q8,q14
    987     vsub.s32    q13,q8,q14
    988 
    989 
    990     vadd.s32    q8,q9,q15
    991     vsub.s32    q14,q9,q15
    992 
    993 
    994     vqrshrn.s32 d18,q2,#shift_stage2_idct   @// r0 = (a0 + b0 + rnd) >> 7(shift_stage1_idct)
    995     vqrshrn.s32 d31,q11,#shift_stage2_idct  @// r7 = (a0 - b0 + rnd) >> 7(shift_stage1_idct)
    996     vqrshrn.s32 d19,q5,#shift_stage2_idct   @// r2 = (a2 + b2 + rnd) >> 7(shift_stage1_idct)
    997     vqrshrn.s32 d30,q13,#shift_stage2_idct  @// r5 = (a2 - b2 + rnd) >> 7(shift_stage1_idct)
    998     vqrshrn.s32 d20,q3,#shift_stage2_idct   @// r1 = (a1 + b1 + rnd) >> 7(shift_stage1_idct)
    999     vqrshrn.s32 d23,q12,#shift_stage2_idct  @// r6 = (a1 - b1 + rnd) >> 7(shift_stage1_idct)
   1000     vqrshrn.s32 d21,q8,#shift_stage2_idct   @// r3 = (a3 + b3 + rnd) >> 7(shift_stage1_idct)
   1001     vqrshrn.s32 d22,q14,#shift_stage2_idct  @// r4 = (a3 - b3 + rnd) >> 7(shift_stage1_idct)
   1002 
   1003     vld1.16     {d4,d5},[r1]!
   1004     vld1.16     {d8,d9},[r1]!
   1005 
   1006 
   1007 
   1008     @ registers used:   {q2,q4,q6,q7}, {q9,q15,q10,q11}
   1009 
   1010 @d4=r0
   1011 @d12=r1
   1012 @d5=r2
   1013 @d13=r3
   1014 
   1015 @d18=r4
   1016 @d20=r5
   1017 @d19=r6
   1018 @d21=r7
   1019 
   1020 @d22=r8
   1021 @d30=r9
   1022 @d23=r10
   1023 @d31=r11
   1024 
   1025 @d14=r12
   1026 @d8=r13
   1027 @d15=r14
   1028 @d9=r15
   1029 
   1030 
   1031     vtrn.16     q2,q6
   1032     vtrn.16     q9,q10
   1033     vtrn.16     q11,q15
   1034     vtrn.16     q7,q4
   1035 
   1036 
   1037 
   1038     vtrn.32     d4,d5
   1039     vtrn.32     d12,d13
   1040 
   1041     vtrn.32     d18,d19
   1042     vtrn.32     d20,d21
   1043 
   1044     vtrn.32     d22,d23
   1045     vtrn.32     d30,d31
   1046 
   1047     vtrn.32     d14,d15
   1048     vtrn.32     d8,d9
   1049 
   1050 @ d4 =r0 1- 4 values
   1051 @ d5 =r2 1- 4 values
   1052 @ d12=r1 1- 4 values
   1053 @ d13=r3 1- 4 values
   1054 
   1055 @ d18 =r0 5- 8 values
   1056 @ d19 =r2 5- 8 values
   1057 @ d20=r1 5- 8 values
   1058 @ d21=r3 5- 8 values
   1059 
   1060 @ d22 =r0 9- 12 values
   1061 @ d23 =r2 9- 12 values
   1062 @ d30=r1 9- 12 values
   1063 @ d31=r3 9- 12 values
   1064 
   1065 @ d14 =r0 13-16 values
   1066 @ d15 =r2 13- 16 values
   1067 @ d8=r1 13- 16 values
   1068 @ d9=r3 13- 16 values
   1069 
   1070 
   1071     vswp        d5,d18
   1072     vswp        d23,d14
   1073     vswp        d13,d20
   1074     vswp        d31,d8
   1075 
   1076 @ q2: r0 1-8 values
   1077 @ q11: r0 9-16 values
   1078 @ q9 : r2 1-8 values
   1079 @ q7 : r2 9-16 values
   1080 @ q6 : r1 1- 8 values
   1081 @ q10: r3 1-8 values
   1082 @ q15: r1 9-16 values
   1083 @ q4:  r3 9-16 values
   1084 
   1085 
   1086 @   registers free: q8,q14,q12,q13
   1087 
   1088 
   1089     vld1.8      {d16,d17},[r2],r8
   1090     vld1.8      {d28,d29},[r2],r5
   1091     vld1.8      {d24,d25},[r4],r8
   1092     vld1.8      {d26,d27},[r4],r5
   1093 
   1094 
   1095 
   1096 
   1097     vaddw.u8    q2,q2,d16
   1098     vaddw.u8    q11,q11,d17
   1099     vaddw.u8    q6,q6,d28
   1100     vaddw.u8    q15,q15,d29
   1101     vaddw.u8    q9,q9,d24
   1102     vaddw.u8    q7,q7,d25
   1103     vaddw.u8    q10,q10,d26
   1104     vaddw.u8    q4,q4,d27
   1105 
   1106 
   1107     vqmovun.s16 d16,q2
   1108     vqmovun.s16 d17,q11
   1109     vqmovun.s16 d28,q6
   1110     vqmovun.s16 d29,q15
   1111     vqmovun.s16 d24,q9
   1112     vqmovun.s16 d25,q7
   1113     vqmovun.s16 d26,q10
   1114     vqmovun.s16 d27,q4
   1115 
   1116 
   1117 
   1118     vst1.8      {d16,d17},[r3],r7
   1119     vst1.8      {d28,d29},[r3],r7
   1120     vst1.8      {d24,d25},[r3],r7
   1121     vst1.8      {d26,d27},[r3],r7
   1122 
   1123     subs        r14,r14,#1
   1124 
   1125 
   1126 
   1127     bne         second_stage
   1128 
   1129 
   1130     vpop        {d8  -  d15}
   1131     ldmfd       sp!,{r4-r12,pc}
   1132 
   1133 
   1134 
   1135 
   1136 
   1137 
   1138 
   1139 
   1140 
   1141 
   1142 
   1143