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