Home | History | Annotate | Download | only in neon
      1 ;
      2 ;  Copyright (c) 2013 The WebM project authors. All Rights Reserved.
      3 ;
      4 ;  Use of this source code is governed by a BSD-style license
      5 ;  that can be found in the LICENSE file in the root of the source
      6 ;  tree. An additional intellectual property rights grant can be found
      7 ;  in the file PATENTS.  All contributing project authors may
      8 ;  be found in the AUTHORS file in the root of the source tree.
      9 ;
     10 
     11     EXPORT  |vp9_idct16x16_256_add_neon_pass1|
     12     EXPORT  |vp9_idct16x16_256_add_neon_pass2|
     13     EXPORT  |vp9_idct16x16_10_add_neon_pass1|
     14     EXPORT  |vp9_idct16x16_10_add_neon_pass2|
     15     ARM
     16     REQUIRE8
     17     PRESERVE8
     18 
     19     AREA ||.text||, CODE, READONLY, ALIGN=2
     20 
     21     ; Transpose a 8x8 16bit data matrix. Datas are loaded in q8-q15.
     22     MACRO
     23     TRANSPOSE8X8
     24     vswp            d17, d24
     25     vswp            d23, d30
     26     vswp            d21, d28
     27     vswp            d19, d26
     28     vtrn.32         q8, q10
     29     vtrn.32         q9, q11
     30     vtrn.32         q12, q14
     31     vtrn.32         q13, q15
     32     vtrn.16         q8, q9
     33     vtrn.16         q10, q11
     34     vtrn.16         q12, q13
     35     vtrn.16         q14, q15
     36     MEND
     37 
     38     AREA    Block, CODE, READONLY ; name this block of code
     39 ;void |vp9_idct16x16_256_add_neon_pass1|(int16_t *input,
     40 ;                                          int16_t *output, int output_stride)
     41 ;
     42 ; r0  int16_t input
     43 ; r1  int16_t *output
     44 ; r2  int  output_stride)
     45 
     46 ; idct16 stage1 - stage6 on all the elements loaded in q8-q15. The output
     47 ; will be stored back into q8-q15 registers. This function will touch q0-q7
     48 ; registers and use them as buffer during calculation.
     49 |vp9_idct16x16_256_add_neon_pass1| PROC
     50 
     51     ; TODO(hkuang): Find a better way to load the elements.
     52     ; load elements of 0, 2, 4, 6, 8, 10, 12, 14 into q8 - q15
     53     vld2.s16        {q8,q9}, [r0]!
     54     vld2.s16        {q9,q10}, [r0]!
     55     vld2.s16        {q10,q11}, [r0]!
     56     vld2.s16        {q11,q12}, [r0]!
     57     vld2.s16        {q12,q13}, [r0]!
     58     vld2.s16        {q13,q14}, [r0]!
     59     vld2.s16        {q14,q15}, [r0]!
     60     vld2.s16        {q1,q2}, [r0]!
     61     vmov.s16        q15, q1
     62 
     63     ; generate  cospi_28_64 = 3196
     64     mov             r3, #0xc00
     65     add             r3, #0x7c
     66 
     67     ; generate cospi_4_64  = 16069
     68     mov             r12, #0x3e00
     69     add             r12, #0xc5
     70 
     71     ; transpose the input data
     72     TRANSPOSE8X8
     73 
     74     ; stage 3
     75     vdup.16         d0, r3                    ; duplicate cospi_28_64
     76     vdup.16         d1, r12                   ; duplicate cospi_4_64
     77 
     78     ; preloading to avoid stall
     79     ; generate cospi_12_64 = 13623
     80     mov             r3, #0x3500
     81     add             r3, #0x37
     82 
     83     ; generate cospi_20_64 = 9102
     84     mov             r12, #0x2300
     85     add             r12, #0x8e
     86 
     87     ; step2[4] * cospi_28_64
     88     vmull.s16       q2, d18, d0
     89     vmull.s16       q3, d19, d0
     90 
     91     ; step2[4] * cospi_4_64
     92     vmull.s16       q5, d18, d1
     93     vmull.s16       q6, d19, d1
     94 
     95     ; temp1 = step2[4] * cospi_28_64 - step2[7] * cospi_4_64
     96     vmlsl.s16       q2, d30, d1
     97     vmlsl.s16       q3, d31, d1
     98 
     99     ; temp2 = step2[4] * cospi_4_64 + step2[7] * cospi_28_64
    100     vmlal.s16       q5, d30, d0
    101     vmlal.s16       q6, d31, d0
    102 
    103     vdup.16         d2, r3                    ; duplicate cospi_12_64
    104     vdup.16         d3, r12                   ; duplicate cospi_20_64
    105 
    106     ; dct_const_round_shift(temp1)
    107     vqrshrn.s32     d8, q2, #14               ; >> 14
    108     vqrshrn.s32     d9, q3, #14               ; >> 14
    109 
    110     ; dct_const_round_shift(temp2)
    111     vqrshrn.s32     d14, q5, #14              ; >> 14
    112     vqrshrn.s32     d15, q6, #14              ; >> 14
    113 
    114     ; preloading to avoid stall
    115     ; generate cospi_16_64 = 11585
    116     mov             r3, #0x2d00
    117     add             r3, #0x41
    118 
    119     ; generate cospi_24_64 = 6270
    120     mov             r12, #0x1800
    121     add             r12, #0x7e
    122 
    123     ; step2[5] * cospi_12_64
    124     vmull.s16       q2, d26, d2
    125     vmull.s16       q3, d27, d2
    126 
    127     ; step2[5] * cospi_20_64
    128     vmull.s16       q9, d26, d3
    129     vmull.s16       q15, d27, d3
    130 
    131     ; temp1 = input[5] * cospi_12_64 - input[3] * cospi_20_64
    132     vmlsl.s16       q2, d22, d3
    133     vmlsl.s16       q3, d23, d3
    134 
    135     ; temp2 = step2[5] * cospi_20_64 + step2[6] * cospi_12_64
    136     vmlal.s16       q9, d22, d2
    137     vmlal.s16       q15, d23, d2
    138 
    139     ; dct_const_round_shift(temp1)
    140     vqrshrn.s32     d10, q2, #14              ; >> 14
    141     vqrshrn.s32     d11, q3, #14              ; >> 14
    142 
    143     ; dct_const_round_shift(temp2)
    144     vqrshrn.s32     d12, q9, #14              ; >> 14
    145     vqrshrn.s32     d13, q15, #14             ; >> 14
    146 
    147     ; stage 4
    148     vdup.16         d30, r3                   ; cospi_16_64
    149 
    150     ; step1[0] * cospi_16_64
    151     vmull.s16       q2, d16, d30
    152     vmull.s16       q11, d17, d30
    153 
    154     ; step1[1] * cospi_16_64
    155     vmull.s16       q0, d24, d30
    156     vmull.s16       q1, d25, d30
    157 
    158     ; generate cospi_8_64 = 15137
    159     mov             r3, #0x3b00
    160     add             r3, #0x21
    161 
    162     vdup.16         d30, r12                  ; duplicate cospi_24_64
    163     vdup.16         d31, r3                   ; duplicate cospi_8_64
    164 
    165     ; temp1 = (step1[0] + step1[1]) * cospi_16_64
    166     vadd.s32        q3, q2, q0
    167     vadd.s32        q12, q11, q1
    168 
    169     ; temp2 = (step1[0] - step1[1]) * cospi_16_64
    170     vsub.s32        q13, q2, q0
    171     vsub.s32        q1, q11, q1
    172 
    173     ; dct_const_round_shift(temp1)
    174     vqrshrn.s32     d16, q3, #14              ; >> 14
    175     vqrshrn.s32     d17, q12, #14             ; >> 14
    176 
    177     ; dct_const_round_shift(temp2)
    178     vqrshrn.s32     d18, q13, #14             ; >> 14
    179     vqrshrn.s32     d19, q1, #14              ; >> 14
    180 
    181     ; step1[2] * cospi_24_64 - step1[3] * cospi_8_64;
    182     ; step1[2] * cospi_8_64
    183     vmull.s16       q0, d20, d31
    184     vmull.s16       q1, d21, d31
    185 
    186     ; step1[2] * cospi_24_64
    187     vmull.s16       q12, d20, d30
    188     vmull.s16       q13, d21, d30
    189 
    190     ; temp2 = input[1] * cospi_8_64 + input[3] * cospi_24_64
    191     vmlal.s16       q0, d28, d30
    192     vmlal.s16       q1, d29, d30
    193 
    194     ; temp1 = input[1] * cospi_24_64 - input[3] * cospi_8_64
    195     vmlsl.s16       q12, d28, d31
    196     vmlsl.s16       q13, d29, d31
    197 
    198     ; dct_const_round_shift(temp2)
    199     vqrshrn.s32     d22, q0, #14              ; >> 14
    200     vqrshrn.s32     d23, q1, #14              ; >> 14
    201 
    202     ; dct_const_round_shift(temp1)
    203     vqrshrn.s32     d20, q12, #14             ; >> 14
    204     vqrshrn.s32     d21, q13, #14             ; >> 14
    205 
    206     vsub.s16        q13, q4, q5               ; step2[5] = step1[4] - step1[5];
    207     vadd.s16        q4, q4, q5                ; step2[4] = step1[4] + step1[5];
    208     vsub.s16        q14, q7, q6               ; step2[6] = -step1[6] + step1[7];
    209     vadd.s16        q15, q6, q7               ; step2[7] = step1[6] + step1[7];
    210 
    211     ; generate cospi_16_64 = 11585
    212     mov             r3, #0x2d00
    213     add             r3, #0x41
    214 
    215     ; stage 5
    216     vadd.s16        q0, q8, q11               ; step1[0] = step2[0] + step2[3];
    217     vadd.s16        q1, q9, q10               ; step1[1] = step2[1] + step2[2];
    218     vsub.s16        q2, q9, q10               ; step1[2] = step2[1] - step2[2];
    219     vsub.s16        q3, q8, q11               ; step1[3] = step2[0] - step2[3];
    220 
    221     vdup.16         d16, r3;                  ; duplicate cospi_16_64
    222 
    223     ; step2[5] * cospi_16_64
    224     vmull.s16       q11, d26, d16
    225     vmull.s16       q12, d27, d16
    226 
    227     ; step2[6] * cospi_16_64
    228     vmull.s16       q9, d28, d16
    229     vmull.s16       q10, d29, d16
    230 
    231     ; temp1 = (step2[6] - step2[5]) * cospi_16_64
    232     vsub.s32        q6, q9, q11
    233     vsub.s32        q13, q10, q12
    234 
    235     ; temp2 = (step2[5] + step2[6]) * cospi_16_64
    236     vadd.s32        q9, q9, q11
    237     vadd.s32        q10, q10, q12
    238 
    239     ; dct_const_round_shift(temp1)
    240     vqrshrn.s32     d10, q6, #14              ; >> 14
    241     vqrshrn.s32     d11, q13, #14             ; >> 14
    242 
    243     ; dct_const_round_shift(temp2)
    244     vqrshrn.s32     d12, q9, #14              ; >> 14
    245     vqrshrn.s32     d13, q10, #14             ; >> 14
    246 
    247     ; stage 6
    248     vadd.s16        q8, q0, q15                ; step2[0] = step1[0] + step1[7];
    249     vadd.s16        q9, q1, q6                ; step2[1] = step1[1] + step1[6];
    250     vadd.s16        q10, q2, q5               ; step2[2] = step1[2] + step1[5];
    251     vadd.s16        q11, q3, q4               ; step2[3] = step1[3] + step1[4];
    252     vsub.s16        q12, q3, q4               ; step2[4] = step1[3] - step1[4];
    253     vsub.s16        q13, q2, q5               ; step2[5] = step1[2] - step1[5];
    254     vsub.s16        q14, q1, q6               ; step2[6] = step1[1] - step1[6];
    255     vsub.s16        q15, q0, q15              ; step2[7] = step1[0] - step1[7];
    256 
    257     ; store the data
    258     vst1.64         {d16}, [r1], r2
    259     vst1.64         {d17}, [r1], r2
    260     vst1.64         {d18}, [r1], r2
    261     vst1.64         {d19}, [r1], r2
    262     vst1.64         {d20}, [r1], r2
    263     vst1.64         {d21}, [r1], r2
    264     vst1.64         {d22}, [r1], r2
    265     vst1.64         {d23}, [r1], r2
    266     vst1.64         {d24}, [r1], r2
    267     vst1.64         {d25}, [r1], r2
    268     vst1.64         {d26}, [r1], r2
    269     vst1.64         {d27}, [r1], r2
    270     vst1.64         {d28}, [r1], r2
    271     vst1.64         {d29}, [r1], r2
    272     vst1.64         {d30}, [r1], r2
    273     vst1.64         {d31}, [r1], r2
    274 
    275     bx              lr
    276     ENDP  ; |vp9_idct16x16_256_add_neon_pass1|
    277 
    278 ;void vp9_idct16x16_256_add_neon_pass2(int16_t *src,
    279 ;                                        int16_t *output,
    280 ;                                        int16_t *pass1Output,
    281 ;                                        int16_t skip_adding,
    282 ;                                        uint8_t *dest,
    283 ;                                        int dest_stride)
    284 ;
    285 ; r0  int16_t *src
    286 ; r1  int16_t *output,
    287 ; r2  int16_t *pass1Output,
    288 ; r3  int16_t skip_adding,
    289 ; r4  uint8_t *dest,
    290 ; r5  int dest_stride)
    291 
    292 ; idct16 stage1 - stage7 on all the elements loaded in q8-q15. The output
    293 ; will be stored back into q8-q15 registers. This function will touch q0-q7
    294 ; registers and use them as buffer during calculation.
    295 |vp9_idct16x16_256_add_neon_pass2| PROC
    296     push            {r3-r9}
    297 
    298     ; TODO(hkuang): Find a better way to load the elements.
    299     ; load elements of 1, 3, 5, 7, 9, 11, 13, 15 into q8 - q15
    300     vld2.s16        {q8,q9}, [r0]!
    301     vld2.s16        {q9,q10}, [r0]!
    302     vld2.s16        {q10,q11}, [r0]!
    303     vld2.s16        {q11,q12}, [r0]!
    304     vld2.s16        {q12,q13}, [r0]!
    305     vld2.s16        {q13,q14}, [r0]!
    306     vld2.s16        {q14,q15}, [r0]!
    307     vld2.s16        {q0,q1}, [r0]!
    308     vmov.s16        q15, q0;
    309 
    310     ; generate  cospi_30_64 = 1606
    311     mov             r3, #0x0600
    312     add             r3, #0x46
    313 
    314     ; generate cospi_2_64  = 16305
    315     mov             r12, #0x3f00
    316     add             r12, #0xb1
    317 
    318     ; transpose the input data
    319     TRANSPOSE8X8
    320 
    321     ; stage 3
    322     vdup.16         d12, r3                   ; duplicate cospi_30_64
    323     vdup.16         d13, r12                  ; duplicate cospi_2_64
    324 
    325     ; preloading to avoid stall
    326     ; generate cospi_14_64 = 12665
    327     mov             r3, #0x3100
    328     add             r3, #0x79
    329 
    330     ; generate cospi_18_64 = 10394
    331     mov             r12, #0x2800
    332     add             r12, #0x9a
    333 
    334     ; step1[8] * cospi_30_64
    335     vmull.s16       q2, d16, d12
    336     vmull.s16       q3, d17, d12
    337 
    338     ; step1[8] * cospi_2_64
    339     vmull.s16       q1, d16, d13
    340     vmull.s16       q4, d17, d13
    341 
    342     ; temp1 = step1[8] * cospi_30_64 - step1[15] * cospi_2_64
    343     vmlsl.s16       q2, d30, d13
    344     vmlsl.s16       q3, d31, d13
    345 
    346     ; temp2 = step1[8] * cospi_2_64 + step1[15] * cospi_30_64
    347     vmlal.s16       q1, d30, d12
    348     vmlal.s16       q4, d31, d12
    349 
    350     vdup.16         d30, r3                   ; duplicate cospi_14_64
    351     vdup.16         d31, r12                  ; duplicate cospi_18_64
    352 
    353     ; dct_const_round_shift(temp1)
    354     vqrshrn.s32     d0, q2, #14               ; >> 14
    355     vqrshrn.s32     d1, q3, #14               ; >> 14
    356 
    357     ; dct_const_round_shift(temp2)
    358     vqrshrn.s32     d14, q1, #14              ; >> 14
    359     vqrshrn.s32     d15, q4, #14              ; >> 14
    360 
    361     ; preloading to avoid stall
    362     ; generate cospi_22_64 = 7723
    363     mov             r3, #0x1e00
    364     add             r3, #0x2b
    365 
    366     ; generate cospi_10_64 = 14449
    367     mov             r12, #0x3800
    368     add             r12, #0x71
    369 
    370     ; step1[9] * cospi_14_64
    371     vmull.s16       q2, d24, d30
    372     vmull.s16       q3, d25, d30
    373 
    374     ; step1[9] * cospi_18_64
    375     vmull.s16       q4, d24, d31
    376     vmull.s16       q5, d25, d31
    377 
    378     ; temp1 = step1[9] * cospi_14_64 - step1[14] * cospi_18_64
    379     vmlsl.s16       q2, d22, d31
    380     vmlsl.s16       q3, d23, d31
    381 
    382     ; temp2 = step1[9] * cospi_18_64 + step1[14] * cospi_14_64
    383     vmlal.s16       q4, d22, d30
    384     vmlal.s16       q5, d23, d30
    385 
    386     vdup.16         d30, r3                   ; duplicate cospi_22_64
    387     vdup.16         d31, r12                  ; duplicate cospi_10_64
    388 
    389     ; dct_const_round_shift(temp1)
    390     vqrshrn.s32     d2, q2, #14               ; >> 14
    391     vqrshrn.s32     d3, q3, #14               ; >> 14
    392 
    393     ; dct_const_round_shift(temp2)
    394     vqrshrn.s32     d12, q4, #14              ; >> 14
    395     vqrshrn.s32     d13, q5, #14              ; >> 14
    396 
    397     ; step1[10] * cospi_22_64
    398     vmull.s16       q11, d20, d30
    399     vmull.s16       q12, d21, d30
    400 
    401     ; step1[10] * cospi_10_64
    402     vmull.s16       q4, d20, d31
    403     vmull.s16       q5, d21, d31
    404 
    405     ; temp1 = step1[10] * cospi_22_64 - step1[13] * cospi_10_64
    406     vmlsl.s16       q11, d26, d31
    407     vmlsl.s16       q12, d27, d31
    408 
    409     ; temp2 = step1[10] * cospi_10_64 + step1[13] * cospi_22_64
    410     vmlal.s16       q4, d26, d30
    411     vmlal.s16       q5, d27, d30
    412 
    413     ; preloading to avoid stall
    414     ; generate cospi_6_64 = 15679
    415     mov             r3, #0x3d00
    416     add             r3, #0x3f
    417 
    418     ; generate cospi_26_64 = 4756
    419     mov             r12, #0x1200
    420     add             r12, #0x94
    421 
    422     vdup.16         d30, r3                   ; duplicate cospi_6_64
    423     vdup.16         d31, r12                  ; duplicate cospi_26_64
    424 
    425     ; dct_const_round_shift(temp1)
    426     vqrshrn.s32     d4, q11, #14              ; >> 14
    427     vqrshrn.s32     d5, q12, #14              ; >> 14
    428 
    429     ; dct_const_round_shift(temp2)
    430     vqrshrn.s32     d11, q5, #14              ; >> 14
    431     vqrshrn.s32     d10, q4, #14              ; >> 14
    432 
    433     ; step1[11] * cospi_6_64
    434     vmull.s16       q10, d28, d30
    435     vmull.s16       q11, d29, d30
    436 
    437     ; step1[11] * cospi_26_64
    438     vmull.s16       q12, d28, d31
    439     vmull.s16       q13, d29, d31
    440 
    441     ; temp1 = step1[11] * cospi_6_64 - step1[12] * cospi_26_64
    442     vmlsl.s16       q10, d18, d31
    443     vmlsl.s16       q11, d19, d31
    444 
    445     ; temp2 = step1[11] * cospi_26_64 + step1[12] * cospi_6_64
    446     vmlal.s16       q12, d18, d30
    447     vmlal.s16       q13, d19, d30
    448 
    449     vsub.s16        q9, q0, q1                ; step1[9]=step2[8]-step2[9]
    450     vadd.s16        q0, q0, q1                ; step1[8]=step2[8]+step2[9]
    451 
    452     ; dct_const_round_shift(temp1)
    453     vqrshrn.s32     d6, q10, #14              ; >> 14
    454     vqrshrn.s32     d7, q11, #14              ; >> 14
    455 
    456     ; dct_const_round_shift(temp2)
    457     vqrshrn.s32     d8, q12, #14              ; >> 14
    458     vqrshrn.s32     d9, q13, #14              ; >> 14
    459 
    460     ; stage 3
    461     vsub.s16        q10, q3, q2               ; step1[10]=-step2[10]+step2[11]
    462     vadd.s16        q11, q2, q3               ; step1[11]=step2[10]+step2[11]
    463     vadd.s16        q12, q4, q5               ; step1[12]=step2[12]+step2[13]
    464     vsub.s16        q13, q4, q5               ; step1[13]=step2[12]-step2[13]
    465     vsub.s16        q14, q7, q6               ; step1[14]=-step2[14]+tep2[15]
    466     vadd.s16        q7, q6, q7                ; step1[15]=step2[14]+step2[15]
    467 
    468     ; stage 4
    469     ; generate cospi_24_64 = 6270
    470     mov             r3, #0x1800
    471     add             r3, #0x7e
    472 
    473     ; generate cospi_8_64 = 15137
    474     mov             r12, #0x3b00
    475     add             r12, #0x21
    476 
    477     ; -step1[9] * cospi_8_64 + step1[14] * cospi_24_64
    478     vdup.16         d30, r12                  ; duplicate cospi_8_64
    479     vdup.16         d31, r3                   ; duplicate cospi_24_64
    480 
    481     ; step1[9] * cospi_24_64
    482     vmull.s16       q2, d18, d31
    483     vmull.s16       q3, d19, d31
    484 
    485     ; step1[14] * cospi_24_64
    486     vmull.s16       q4, d28, d31
    487     vmull.s16       q5, d29, d31
    488 
    489     ; temp2 = step1[9] * cospi_24_64 + step1[14] * cospi_8_64
    490     vmlal.s16       q2, d28, d30
    491     vmlal.s16       q3, d29, d30
    492 
    493     ; temp1 = -step1[9] * cospi_8_64 + step1[14] * cospi_24_64
    494     vmlsl.s16       q4, d18, d30
    495     vmlsl.s16       q5, d19, d30
    496 
    497     rsb             r12, #0
    498     vdup.16         d30, r12                  ; duplicate -cospi_8_64
    499 
    500     ; dct_const_round_shift(temp2)
    501     vqrshrn.s32     d12, q2, #14              ; >> 14
    502     vqrshrn.s32     d13, q3, #14              ; >> 14
    503 
    504     ; dct_const_round_shift(temp1)
    505     vqrshrn.s32     d2, q4, #14               ; >> 14
    506     vqrshrn.s32     d3, q5, #14               ; >> 14
    507 
    508     vmov.s16        q3, q11
    509     vmov.s16        q4, q12
    510 
    511     ; - step1[13] * cospi_8_64
    512     vmull.s16       q11, d26, d30
    513     vmull.s16       q12, d27, d30
    514 
    515     ; -step1[10] * cospi_8_64
    516     vmull.s16       q8, d20, d30
    517     vmull.s16       q9, d21, d30
    518 
    519     ; temp2 = -step1[10] * cospi_8_64 + step1[13] * cospi_24_64
    520     vmlsl.s16       q11, d20, d31
    521     vmlsl.s16       q12, d21, d31
    522 
    523     ; temp1 = -step1[10] * cospi_8_64 + step1[13] * cospi_24_64
    524     vmlal.s16       q8, d26, d31
    525     vmlal.s16       q9, d27, d31
    526 
    527     ; dct_const_round_shift(temp2)
    528     vqrshrn.s32     d4, q11, #14              ; >> 14
    529     vqrshrn.s32     d5, q12, #14              ; >> 14
    530 
    531     ; dct_const_round_shift(temp1)
    532     vqrshrn.s32     d10, q8, #14              ; >> 14
    533     vqrshrn.s32     d11, q9, #14              ; >> 14
    534 
    535     ; stage 5
    536     vadd.s16        q8, q0, q3                ; step1[8] = step2[8]+step2[11];
    537     vadd.s16        q9, q1, q2                ; step1[9] = step2[9]+step2[10];
    538     vsub.s16        q10, q1, q2               ; step1[10] = step2[9]-step2[10];
    539     vsub.s16        q11, q0, q3               ; step1[11] = step2[8]-step2[11];
    540     vsub.s16        q12, q7, q4               ; step1[12] =-step2[12]+step2[15];
    541     vsub.s16        q13, q6, q5               ; step1[13] =-step2[13]+step2[14];
    542     vadd.s16        q14, q6, q5               ; step1[14] =step2[13]+step2[14];
    543     vadd.s16        q15, q7, q4               ; step1[15] =step2[12]+step2[15];
    544 
    545     ; stage 6.
    546     ; generate cospi_16_64 = 11585
    547     mov             r12, #0x2d00
    548     add             r12, #0x41
    549 
    550     vdup.16         d14, r12                  ; duplicate cospi_16_64
    551 
    552     ; step1[13] * cospi_16_64
    553     vmull.s16       q3, d26, d14
    554     vmull.s16       q4, d27, d14
    555 
    556     ; step1[10] * cospi_16_64
    557     vmull.s16       q0, d20, d14
    558     vmull.s16       q1, d21, d14
    559 
    560     ; temp1 = (-step1[10] + step1[13]) * cospi_16_64
    561     vsub.s32        q5, q3, q0
    562     vsub.s32        q6, q4, q1
    563 
    564     ; temp2 = (step1[10] + step1[13]) * cospi_16_64
    565     vadd.s32        q10, q3, q0
    566     vadd.s32        q4, q4, q1
    567 
    568     ; dct_const_round_shift(temp1)
    569     vqrshrn.s32     d4, q5, #14               ; >> 14
    570     vqrshrn.s32     d5, q6, #14               ; >> 14
    571 
    572     ; dct_const_round_shift(temp2)
    573     vqrshrn.s32     d10, q10, #14             ; >> 14
    574     vqrshrn.s32     d11, q4, #14              ; >> 14
    575 
    576     ; step1[11] * cospi_16_64
    577     vmull.s16       q0, d22, d14
    578     vmull.s16       q1, d23, d14
    579 
    580     ; step1[12] * cospi_16_64
    581     vmull.s16       q13, d24, d14
    582     vmull.s16       q6, d25, d14
    583 
    584     ; temp1 = (-step1[11] + step1[12]) * cospi_16_64
    585     vsub.s32        q10, q13, q0
    586     vsub.s32        q4, q6, q1
    587 
    588     ; temp2 = (step1[11] + step1[12]) * cospi_16_64
    589     vadd.s32        q13, q13, q0
    590     vadd.s32        q6, q6, q1
    591 
    592     ; dct_const_round_shift(temp1)
    593     vqrshrn.s32     d6, q10, #14              ; >> 14
    594     vqrshrn.s32     d7, q4, #14               ; >> 14
    595 
    596     ; dct_const_round_shift(temp2)
    597     vqrshrn.s32     d8, q13, #14              ; >> 14
    598     vqrshrn.s32     d9, q6, #14               ; >> 14
    599 
    600     mov              r4, #16                  ; pass1Output stride
    601     ldr              r3, [sp]                 ; load skip_adding
    602     cmp              r3, #0                   ; check if need adding dest data
    603     beq              skip_adding_dest
    604 
    605     ldr              r7, [sp, #28]            ; dest used to save element 0-7
    606     mov              r9, r7                   ; save dest pointer for later use
    607     ldr              r8, [sp, #32]            ; load dest_stride
    608 
    609     ; stage 7
    610     ; load the data in pass1
    611     vld1.s16        {q0}, [r2], r4            ; load data step2[0]
    612     vld1.s16        {q1}, [r2], r4            ; load data step2[1]
    613     vld1.s16        {q10}, [r2], r4           ; load data step2[2]
    614     vld1.s16        {q11}, [r2], r4           ; load data step2[3]
    615     vld1.64         {d12}, [r7], r8           ; load destinatoin data
    616     vld1.64         {d13}, [r7], r8           ; load destinatoin data
    617     vadd.s16        q12, q0, q15              ; step2[0] + step2[15]
    618     vadd.s16        q13, q1, q14              ; step2[1] + step2[14]
    619     vrshr.s16       q12, q12, #6              ; ROUND_POWER_OF_TWO
    620     vrshr.s16       q13, q13, #6              ; ROUND_POWER_OF_TWO
    621     vaddw.u8        q12, q12, d12             ; + dest[j * dest_stride + i]
    622     vaddw.u8        q13, q13, d13             ; + dest[j * dest_stride + i]
    623     vqmovun.s16     d12, q12                  ; clip pixel
    624     vqmovun.s16     d13, q13                  ; clip pixel
    625     vst1.64         {d12}, [r9], r8           ; store the data
    626     vst1.64         {d13}, [r9], r8           ; store the data
    627     vsub.s16        q14, q1, q14              ; step2[1] - step2[14]
    628     vsub.s16        q15, q0, q15              ; step2[0] - step2[15]
    629     vld1.64         {d12}, [r7], r8           ; load destinatoin data
    630     vld1.64         {d13}, [r7], r8           ; load destinatoin data
    631     vadd.s16        q12, q10, q5              ; step2[2] + step2[13]
    632     vadd.s16        q13, q11, q4              ; step2[3] + step2[12]
    633     vrshr.s16       q12, q12, #6              ; ROUND_POWER_OF_TWO
    634     vrshr.s16       q13, q13, #6              ; ROUND_POWER_OF_TWO
    635     vaddw.u8        q12, q12, d12             ; + dest[j * dest_stride + i]
    636     vaddw.u8        q13, q13, d13             ; + dest[j * dest_stride + i]
    637     vqmovun.s16     d12, q12                  ; clip pixel
    638     vqmovun.s16     d13, q13                  ; clip pixel
    639     vst1.64         {d12}, [r9], r8           ; store the data
    640     vst1.64         {d13}, [r9], r8           ; store the data
    641     vsub.s16        q4, q11, q4               ; step2[3] - step2[12]
    642     vsub.s16        q5, q10, q5               ; step2[2] - step2[13]
    643     vld1.s16        {q0}, [r2], r4            ; load data step2[4]
    644     vld1.s16        {q1}, [r2], r4            ; load data step2[5]
    645     vld1.s16        {q10}, [r2], r4           ; load data step2[6]
    646     vld1.s16        {q11}, [r2], r4           ; load data step2[7]
    647     vld1.64         {d12}, [r7], r8           ; load destinatoin data
    648     vld1.64         {d13}, [r7], r8           ; load destinatoin data
    649     vadd.s16        q12, q0, q3               ; step2[4] + step2[11]
    650     vadd.s16        q13, q1, q2               ; step2[5] + step2[10]
    651     vrshr.s16       q12, q12, #6              ; ROUND_POWER_OF_TWO
    652     vrshr.s16       q13, q13, #6              ; ROUND_POWER_OF_TWO
    653     vaddw.u8        q12, q12, d12             ; + dest[j * dest_stride + i]
    654     vaddw.u8        q13, q13, d13             ; + dest[j * dest_stride + i]
    655     vqmovun.s16     d12, q12                  ; clip pixel
    656     vqmovun.s16     d13, q13                  ; clip pixel
    657     vst1.64         {d12}, [r9], r8           ; store the data
    658     vst1.64         {d13}, [r9], r8           ; store the data
    659     vsub.s16        q2, q1, q2                ; step2[5] - step2[10]
    660     vsub.s16        q3, q0, q3                ; step2[4] - step2[11]
    661     vld1.64         {d12}, [r7], r8           ; load destinatoin data
    662     vld1.64         {d13}, [r7], r8           ; load destinatoin data
    663     vadd.s16        q12, q10, q9              ; step2[6] + step2[9]
    664     vadd.s16        q13, q11, q8              ; step2[7] + step2[8]
    665     vrshr.s16       q12, q12, #6              ; ROUND_POWER_OF_TWO
    666     vrshr.s16       q13, q13, #6              ; ROUND_POWER_OF_TWO
    667     vaddw.u8        q12, q12, d12             ; + dest[j * dest_stride + i]
    668     vaddw.u8        q13, q13, d13             ; + dest[j * dest_stride + i]
    669     vqmovun.s16     d12, q12                  ; clip pixel
    670     vqmovun.s16     d13, q13                  ; clip pixel
    671     vst1.64         {d12}, [r9], r8           ; store the data
    672     vst1.64         {d13}, [r9], r8           ; store the data
    673     vld1.64         {d12}, [r7], r8           ; load destinatoin data
    674     vld1.64         {d13}, [r7], r8           ; load destinatoin data
    675     vsub.s16        q8, q11, q8               ; step2[7] - step2[8]
    676     vsub.s16        q9, q10, q9               ; step2[6] - step2[9]
    677 
    678     ; store the data  output 8,9,10,11,12,13,14,15
    679     vrshr.s16       q8, q8, #6                ; ROUND_POWER_OF_TWO
    680     vaddw.u8        q8, q8, d12               ; + dest[j * dest_stride + i]
    681     vqmovun.s16     d12, q8                   ; clip pixel
    682     vst1.64         {d12}, [r9], r8           ; store the data
    683     vld1.64         {d12}, [r7], r8           ; load destinatoin data
    684     vrshr.s16       q9, q9, #6
    685     vaddw.u8        q9, q9, d13               ; + dest[j * dest_stride + i]
    686     vqmovun.s16     d13, q9                   ; clip pixel
    687     vst1.64         {d13}, [r9], r8           ; store the data
    688     vld1.64         {d13}, [r7], r8           ; load destinatoin data
    689     vrshr.s16       q2, q2, #6
    690     vaddw.u8        q2, q2, d12               ; + dest[j * dest_stride + i]
    691     vqmovun.s16     d12, q2                   ; clip pixel
    692     vst1.64         {d12}, [r9], r8           ; store the data
    693     vld1.64         {d12}, [r7], r8           ; load destinatoin data
    694     vrshr.s16       q3, q3, #6
    695     vaddw.u8        q3, q3, d13               ; + dest[j * dest_stride + i]
    696     vqmovun.s16     d13, q3                   ; clip pixel
    697     vst1.64         {d13}, [r9], r8           ; store the data
    698     vld1.64         {d13}, [r7], r8           ; load destinatoin data
    699     vrshr.s16       q4, q4, #6
    700     vaddw.u8        q4, q4, d12               ; + dest[j * dest_stride + i]
    701     vqmovun.s16     d12, q4                   ; clip pixel
    702     vst1.64         {d12}, [r9], r8           ; store the data
    703     vld1.64         {d12}, [r7], r8           ; load destinatoin data
    704     vrshr.s16       q5, q5, #6
    705     vaddw.u8        q5, q5, d13               ; + dest[j * dest_stride + i]
    706     vqmovun.s16     d13, q5                   ; clip pixel
    707     vst1.64         {d13}, [r9], r8           ; store the data
    708     vld1.64         {d13}, [r7], r8           ; load destinatoin data
    709     vrshr.s16       q14, q14, #6
    710     vaddw.u8        q14, q14, d12             ; + dest[j * dest_stride + i]
    711     vqmovun.s16     d12, q14                  ; clip pixel
    712     vst1.64         {d12}, [r9], r8           ; store the data
    713     vld1.64         {d12}, [r7], r8           ; load destinatoin data
    714     vrshr.s16       q15, q15, #6
    715     vaddw.u8        q15, q15, d13             ; + dest[j * dest_stride + i]
    716     vqmovun.s16     d13, q15                  ; clip pixel
    717     vst1.64         {d13}, [r9], r8           ; store the data
    718     b               end_idct16x16_pass2
    719 
    720 skip_adding_dest
    721     ; stage 7
    722     ; load the data in pass1
    723     mov              r5, #24
    724     mov              r3, #8
    725 
    726     vld1.s16        {q0}, [r2], r4            ; load data step2[0]
    727     vld1.s16        {q1}, [r2], r4            ; load data step2[1]
    728     vadd.s16        q12, q0, q15              ; step2[0] + step2[15]
    729     vadd.s16        q13, q1, q14              ; step2[1] + step2[14]
    730     vld1.s16        {q10}, [r2], r4           ; load data step2[2]
    731     vld1.s16        {q11}, [r2], r4           ; load data step2[3]
    732     vst1.64         {d24}, [r1], r3           ; store output[0]
    733     vst1.64         {d25}, [r1], r5
    734     vst1.64         {d26}, [r1], r3           ; store output[1]
    735     vst1.64         {d27}, [r1], r5
    736     vadd.s16        q12, q10, q5              ; step2[2] + step2[13]
    737     vadd.s16        q13, q11, q4              ; step2[3] + step2[12]
    738     vsub.s16        q14, q1, q14              ; step2[1] - step2[14]
    739     vsub.s16        q15, q0, q15              ; step2[0] - step2[15]
    740     vst1.64         {d24}, [r1], r3           ; store output[2]
    741     vst1.64         {d25}, [r1], r5
    742     vst1.64         {d26}, [r1], r3           ; store output[3]
    743     vst1.64         {d27}, [r1], r5
    744     vsub.s16        q4, q11, q4               ; step2[3] - step2[12]
    745     vsub.s16        q5, q10, q5               ; step2[2] - step2[13]
    746     vld1.s16        {q0}, [r2], r4            ; load data step2[4]
    747     vld1.s16        {q1}, [r2], r4            ; load data step2[5]
    748     vadd.s16        q12, q0, q3               ; step2[4] + step2[11]
    749     vadd.s16        q13, q1, q2               ; step2[5] + step2[10]
    750     vld1.s16        {q10}, [r2], r4           ; load data step2[6]
    751     vld1.s16        {q11}, [r2], r4           ; load data step2[7]
    752     vst1.64         {d24}, [r1], r3           ; store output[4]
    753     vst1.64         {d25}, [r1], r5
    754     vst1.64         {d26}, [r1], r3           ; store output[5]
    755     vst1.64         {d27}, [r1], r5
    756     vadd.s16        q12, q10, q9              ; step2[6] + step2[9]
    757     vadd.s16        q13, q11, q8              ; step2[7] + step2[8]
    758     vsub.s16        q2, q1, q2                ; step2[5] - step2[10]
    759     vsub.s16        q3, q0, q3                ; step2[4] - step2[11]
    760     vsub.s16        q8, q11, q8               ; step2[7] - step2[8]
    761     vsub.s16        q9, q10, q9               ; step2[6] - step2[9]
    762     vst1.64         {d24}, [r1], r3           ; store output[6]
    763     vst1.64         {d25}, [r1], r5
    764     vst1.64         {d26}, [r1], r3           ; store output[7]
    765     vst1.64         {d27}, [r1], r5
    766 
    767     ; store the data  output 8,9,10,11,12,13,14,15
    768     vst1.64         {d16}, [r1], r3
    769     vst1.64         {d17}, [r1], r5
    770     vst1.64         {d18}, [r1], r3
    771     vst1.64         {d19}, [r1], r5
    772     vst1.64         {d4}, [r1], r3
    773     vst1.64         {d5}, [r1], r5
    774     vst1.64         {d6}, [r1], r3
    775     vst1.64         {d7}, [r1], r5
    776     vst1.64         {d8}, [r1], r3
    777     vst1.64         {d9}, [r1], r5
    778     vst1.64         {d10}, [r1], r3
    779     vst1.64         {d11}, [r1], r5
    780     vst1.64         {d28}, [r1], r3
    781     vst1.64         {d29}, [r1], r5
    782     vst1.64         {d30}, [r1], r3
    783     vst1.64         {d31}, [r1], r5
    784 end_idct16x16_pass2
    785     pop             {r3-r9}
    786     bx              lr
    787     ENDP  ; |vp9_idct16x16_256_add_neon_pass2|
    788 
    789 ;void |vp9_idct16x16_10_add_neon_pass1|(int16_t *input,
    790 ;                                             int16_t *output, int output_stride)
    791 ;
    792 ; r0  int16_t input
    793 ; r1  int16_t *output
    794 ; r2  int  output_stride)
    795 
    796 ; idct16 stage1 - stage6 on all the elements loaded in q8-q15. The output
    797 ; will be stored back into q8-q15 registers. This function will touch q0-q7
    798 ; registers and use them as buffer during calculation.
    799 |vp9_idct16x16_10_add_neon_pass1| PROC
    800 
    801     ; TODO(hkuang): Find a better way to load the elements.
    802     ; load elements of 0, 2, 4, 6, 8, 10, 12, 14 into q8 - q15
    803     vld2.s16        {q8,q9}, [r0]!
    804     vld2.s16        {q9,q10}, [r0]!
    805     vld2.s16        {q10,q11}, [r0]!
    806     vld2.s16        {q11,q12}, [r0]!
    807     vld2.s16        {q12,q13}, [r0]!
    808     vld2.s16        {q13,q14}, [r0]!
    809     vld2.s16        {q14,q15}, [r0]!
    810     vld2.s16        {q1,q2}, [r0]!
    811     vmov.s16        q15, q1
    812 
    813     ; generate  cospi_28_64*2 = 6392
    814     mov             r3, #0x1800
    815     add             r3, #0xf8
    816 
    817     ; generate cospi_4_64*2  = 32138
    818     mov             r12, #0x7d00
    819     add             r12, #0x8a
    820 
    821     ; transpose the input data
    822     TRANSPOSE8X8
    823 
    824     ; stage 3
    825     vdup.16         q0, r3                    ; duplicate cospi_28_64*2
    826     vdup.16         q1, r12                   ; duplicate cospi_4_64*2
    827 
    828     ; The following instructions use vqrdmulh to do the
    829     ; dct_const_round_shift(step2[4] * cospi_28_64). vvqrdmulh will multiply,
    830     ; double, and return the high 16 bits, effectively giving >> 15. Doubling
    831     ; the constant will change this to >> 14.
    832     ; dct_const_round_shift(step2[4] * cospi_28_64);
    833     vqrdmulh.s16    q4, q9, q0
    834 
    835     ; preloading to avoid stall
    836     ; generate cospi_16_64*2 = 23170
    837     mov             r3, #0x5a00
    838     add             r3, #0x82
    839 
    840     ; dct_const_round_shift(step2[4] * cospi_4_64);
    841     vqrdmulh.s16    q7, q9, q1
    842 
    843     ; stage 4
    844     vdup.16         q1, r3                    ; cospi_16_64*2
    845 
    846     ; generate cospi_16_64 = 11585
    847     mov             r3, #0x2d00
    848     add             r3, #0x41
    849 
    850     vdup.16         d4, r3;                   ; duplicate cospi_16_64
    851 
    852     ; dct_const_round_shift(step1[0] * cospi_16_64)
    853     vqrdmulh.s16    q8, q8, q1
    854 
    855     ; step2[6] * cospi_16_64
    856     vmull.s16       q9, d14, d4
    857     vmull.s16       q10, d15, d4
    858 
    859     ; step2[5] * cospi_16_64
    860     vmull.s16       q12, d9, d4
    861     vmull.s16       q11, d8, d4
    862 
    863     ; temp1 = (step2[6] - step2[5]) * cospi_16_64
    864     vsub.s32        q15, q10, q12
    865     vsub.s32        q6, q9, q11
    866 
    867     ; temp2 = (step2[5] + step2[6]) * cospi_16_64
    868     vadd.s32        q9, q9, q11
    869     vadd.s32        q10, q10, q12
    870 
    871     ; dct_const_round_shift(temp1)
    872     vqrshrn.s32     d11, q15, #14             ; >> 14
    873     vqrshrn.s32     d10, q6, #14              ; >> 14
    874 
    875     ; dct_const_round_shift(temp2)
    876     vqrshrn.s32     d12, q9, #14              ; >> 14
    877     vqrshrn.s32     d13, q10, #14             ; >> 14
    878 
    879     ; stage 6
    880     vadd.s16        q2, q8, q7                ; step2[0] = step1[0] + step1[7];
    881     vadd.s16        q10, q8, q5               ; step2[2] = step1[2] + step1[5];
    882     vadd.s16        q11, q8, q4               ; step2[3] = step1[3] + step1[4];
    883     vadd.s16        q9, q8, q6                ; step2[1] = step1[1] + step1[6];
    884     vsub.s16        q12, q8, q4               ; step2[4] = step1[3] - step1[4];
    885     vsub.s16        q13, q8, q5               ; step2[5] = step1[2] - step1[5];
    886     vsub.s16        q14, q8, q6               ; step2[6] = step1[1] - step1[6];
    887     vsub.s16        q15, q8, q7               ; step2[7] = step1[0] - step1[7];
    888 
    889     ; store the data
    890     vst1.64         {d4}, [r1], r2
    891     vst1.64         {d5}, [r1], r2
    892     vst1.64         {d18}, [r1], r2
    893     vst1.64         {d19}, [r1], r2
    894     vst1.64         {d20}, [r1], r2
    895     vst1.64         {d21}, [r1], r2
    896     vst1.64         {d22}, [r1], r2
    897     vst1.64         {d23}, [r1], r2
    898     vst1.64         {d24}, [r1], r2
    899     vst1.64         {d25}, [r1], r2
    900     vst1.64         {d26}, [r1], r2
    901     vst1.64         {d27}, [r1], r2
    902     vst1.64         {d28}, [r1], r2
    903     vst1.64         {d29}, [r1], r2
    904     vst1.64         {d30}, [r1], r2
    905     vst1.64         {d31}, [r1], r2
    906 
    907     bx              lr
    908     ENDP  ; |vp9_idct16x16_10_add_neon_pass1|
    909 
    910 ;void vp9_idct16x16_10_add_neon_pass2(int16_t *src,
    911 ;                                           int16_t *output,
    912 ;                                           int16_t *pass1Output,
    913 ;                                           int16_t skip_adding,
    914 ;                                           uint8_t *dest,
    915 ;                                           int dest_stride)
    916 ;
    917 ; r0  int16_t *src
    918 ; r1  int16_t *output,
    919 ; r2  int16_t *pass1Output,
    920 ; r3  int16_t skip_adding,
    921 ; r4  uint8_t *dest,
    922 ; r5  int dest_stride)
    923 
    924 ; idct16 stage1 - stage7 on all the elements loaded in q8-q15. The output
    925 ; will be stored back into q8-q15 registers. This function will touch q0-q7
    926 ; registers and use them as buffer during calculation.
    927 |vp9_idct16x16_10_add_neon_pass2| PROC
    928     push            {r3-r9}
    929 
    930     ; TODO(hkuang): Find a better way to load the elements.
    931     ; load elements of 1, 3, 5, 7, 9, 11, 13, 15 into q8 - q15
    932     vld2.s16        {q8,q9}, [r0]!
    933     vld2.s16        {q9,q10}, [r0]!
    934     vld2.s16        {q10,q11}, [r0]!
    935     vld2.s16        {q11,q12}, [r0]!
    936     vld2.s16        {q12,q13}, [r0]!
    937     vld2.s16        {q13,q14}, [r0]!
    938     vld2.s16        {q14,q15}, [r0]!
    939     vld2.s16        {q0,q1}, [r0]!
    940     vmov.s16        q15, q0;
    941 
    942     ; generate 2*cospi_30_64 = 3212
    943     mov             r3, #0xc00
    944     add             r3, #0x8c
    945 
    946     ; generate 2*cospi_2_64  = 32610
    947     mov             r12, #0x7f00
    948     add             r12, #0x62
    949 
    950     ; transpose the input data
    951     TRANSPOSE8X8
    952 
    953     ; stage 3
    954     vdup.16         q6, r3                    ; duplicate 2*cospi_30_64
    955 
    956     ; dct_const_round_shift(step1[8] * cospi_30_64)
    957     vqrdmulh.s16    q0, q8, q6
    958 
    959     vdup.16         q6, r12                   ; duplicate 2*cospi_2_64
    960 
    961     ; dct_const_round_shift(step1[8] * cospi_2_64)
    962     vqrdmulh.s16    q7, q8, q6
    963 
    964     ; preloading to avoid stall
    965     ; generate 2*cospi_26_64 = 9512
    966     mov             r12, #0x2500
    967     add             r12, #0x28
    968     rsb             r12, #0
    969     vdup.16         q15, r12                  ; duplicate -2*cospi_26_64
    970 
    971     ; generate 2*cospi_6_64 = 31358
    972     mov             r3, #0x7a00
    973     add             r3, #0x7e
    974     vdup.16         q14, r3                   ; duplicate 2*cospi_6_64
    975 
    976     ; dct_const_round_shift(- step1[12] * cospi_26_64)
    977     vqrdmulh.s16    q3, q9, q15
    978 
    979     ; dct_const_round_shift(step1[12] * cospi_6_64)
    980     vqrdmulh.s16    q4, q9, q14
    981 
    982     ; stage 4
    983     ; generate cospi_24_64 = 6270
    984     mov             r3, #0x1800
    985     add             r3, #0x7e
    986     vdup.16         d31, r3                   ; duplicate cospi_24_64
    987 
    988     ; generate cospi_8_64 = 15137
    989     mov             r12, #0x3b00
    990     add             r12, #0x21
    991     vdup.16         d30, r12                  ; duplicate cospi_8_64
    992 
    993     ; step1[14] * cospi_24_64
    994     vmull.s16       q12, d14, d31
    995     vmull.s16       q5, d15, d31
    996 
    997     ; step1[9] * cospi_24_64
    998     vmull.s16       q2, d0, d31
    999     vmull.s16       q11, d1, d31
   1000 
   1001     ; temp1 = -step1[9] * cospi_8_64 + step1[14] * cospi_24_64
   1002     vmlsl.s16       q12, d0, d30
   1003     vmlsl.s16       q5, d1, d30
   1004 
   1005     ; temp2 = step1[9] * cospi_24_64 + step1[14] * cospi_8_64
   1006     vmlal.s16       q2, d14, d30
   1007     vmlal.s16       q11, d15, d30
   1008 
   1009     rsb              r12, #0
   1010     vdup.16          d30, r12                 ; duplicate -cospi_8_64
   1011 
   1012     ; dct_const_round_shift(temp1)
   1013     vqrshrn.s32     d2, q12, #14              ; >> 14
   1014     vqrshrn.s32     d3, q5, #14               ; >> 14
   1015 
   1016     ; dct_const_round_shift(temp2)
   1017     vqrshrn.s32     d12, q2, #14              ; >> 14
   1018     vqrshrn.s32     d13, q11, #14             ; >> 14
   1019 
   1020     ; - step1[13] * cospi_8_64
   1021     vmull.s16       q10, d8, d30
   1022     vmull.s16       q13, d9, d30
   1023 
   1024     ; -step1[10] * cospi_8_64
   1025     vmull.s16       q8, d6, d30
   1026     vmull.s16       q9, d7, d30
   1027 
   1028     ; temp1 = -step1[10] * cospi_24_64 - step1[13] * cospi_8_64
   1029     vmlsl.s16       q10, d6, d31
   1030     vmlsl.s16       q13, d7, d31
   1031 
   1032     ; temp2 = -step1[10] * cospi_8_64 + step1[13] * cospi_24_64
   1033     vmlal.s16       q8, d8, d31
   1034     vmlal.s16       q9, d9, d31
   1035 
   1036     ; dct_const_round_shift(temp1)
   1037     vqrshrn.s32     d4, q10, #14              ; >> 14
   1038     vqrshrn.s32     d5, q13, #14              ; >> 14
   1039 
   1040     ; dct_const_round_shift(temp2)
   1041     vqrshrn.s32     d10, q8, #14              ; >> 14
   1042     vqrshrn.s32     d11, q9, #14              ; >> 14
   1043 
   1044     ; stage 5
   1045     vadd.s16        q8, q0, q3                ; step1[8] = step2[8]+step2[11];
   1046     vadd.s16        q9, q1, q2                ; step1[9] = step2[9]+step2[10];
   1047     vsub.s16        q10, q1, q2               ; step1[10] = step2[9]-step2[10];
   1048     vsub.s16        q11, q0, q3               ; step1[11] = step2[8]-step2[11];
   1049     vsub.s16        q12, q7, q4               ; step1[12] =-step2[12]+step2[15];
   1050     vsub.s16        q13, q6, q5               ; step1[13] =-step2[13]+step2[14];
   1051     vadd.s16        q14, q6, q5               ; step1[14] =step2[13]+step2[14];
   1052     vadd.s16        q15, q7, q4               ; step1[15] =step2[12]+step2[15];
   1053 
   1054     ; stage 6.
   1055     ; generate cospi_16_64 = 11585
   1056     mov             r12, #0x2d00
   1057     add             r12, #0x41
   1058 
   1059     vdup.16         d14, r12                  ; duplicate cospi_16_64
   1060 
   1061     ; step1[13] * cospi_16_64
   1062     vmull.s16       q3, d26, d14
   1063     vmull.s16       q4, d27, d14
   1064 
   1065     ; step1[10] * cospi_16_64
   1066     vmull.s16       q0, d20, d14
   1067     vmull.s16       q1, d21, d14
   1068 
   1069     ; temp1 = (-step1[10] + step1[13]) * cospi_16_64
   1070     vsub.s32        q5, q3, q0
   1071     vsub.s32        q6, q4, q1
   1072 
   1073     ; temp2 = (step1[10] + step1[13]) * cospi_16_64
   1074     vadd.s32        q0, q3, q0
   1075     vadd.s32        q1, q4, q1
   1076 
   1077     ; dct_const_round_shift(temp1)
   1078     vqrshrn.s32     d4, q5, #14               ; >> 14
   1079     vqrshrn.s32     d5, q6, #14               ; >> 14
   1080 
   1081     ; dct_const_round_shift(temp2)
   1082     vqrshrn.s32     d10, q0, #14              ; >> 14
   1083     vqrshrn.s32     d11, q1, #14              ; >> 14
   1084 
   1085     ; step1[11] * cospi_16_64
   1086     vmull.s16       q0, d22, d14
   1087     vmull.s16       q1, d23, d14
   1088 
   1089     ; step1[12] * cospi_16_64
   1090     vmull.s16       q13, d24, d14
   1091     vmull.s16       q6, d25, d14
   1092 
   1093     ; temp1 = (-step1[11] + step1[12]) * cospi_16_64
   1094     vsub.s32        q10, q13, q0
   1095     vsub.s32        q4, q6, q1
   1096 
   1097     ; temp2 = (step1[11] + step1[12]) * cospi_16_64
   1098     vadd.s32        q13, q13, q0
   1099     vadd.s32        q6, q6, q1
   1100 
   1101     ; dct_const_round_shift(input_dc * cospi_16_64)
   1102     vqrshrn.s32     d6, q10, #14              ; >> 14
   1103     vqrshrn.s32     d7, q4, #14               ; >> 14
   1104 
   1105     ; dct_const_round_shift((step1[11] + step1[12]) * cospi_16_64);
   1106     vqrshrn.s32     d8, q13, #14              ; >> 14
   1107     vqrshrn.s32     d9, q6, #14               ; >> 14
   1108 
   1109     mov              r4, #16                  ; pass1Output stride
   1110     ldr              r3, [sp]                 ; load skip_adding
   1111 
   1112     ; stage 7
   1113     ; load the data in pass1
   1114     mov              r5, #24
   1115     mov              r3, #8
   1116 
   1117     vld1.s16        {q0}, [r2], r4            ; load data step2[0]
   1118     vld1.s16        {q1}, [r2], r4            ; load data step2[1]
   1119     vadd.s16        q12, q0, q15              ; step2[0] + step2[15]
   1120     vadd.s16        q13, q1, q14              ; step2[1] + step2[14]
   1121     vld1.s16        {q10}, [r2], r4           ; load data step2[2]
   1122     vld1.s16        {q11}, [r2], r4           ; load data step2[3]
   1123     vst1.64         {d24}, [r1], r3           ; store output[0]
   1124     vst1.64         {d25}, [r1], r5
   1125     vst1.64         {d26}, [r1], r3           ; store output[1]
   1126     vst1.64         {d27}, [r1], r5
   1127     vadd.s16        q12, q10, q5              ; step2[2] + step2[13]
   1128     vadd.s16        q13, q11, q4              ; step2[3] + step2[12]
   1129     vsub.s16        q14, q1, q14              ; step2[1] - step2[14]
   1130     vsub.s16        q15, q0, q15              ; step2[0] - step2[15]
   1131     vst1.64         {d24}, [r1], r3           ; store output[2]
   1132     vst1.64         {d25}, [r1], r5
   1133     vst1.64         {d26}, [r1], r3           ; store output[3]
   1134     vst1.64         {d27}, [r1], r5
   1135     vsub.s16        q4, q11, q4               ; step2[3] - step2[12]
   1136     vsub.s16        q5, q10, q5               ; step2[2] - step2[13]
   1137     vld1.s16        {q0}, [r2], r4            ; load data step2[4]
   1138     vld1.s16        {q1}, [r2], r4            ; load data step2[5]
   1139     vadd.s16        q12, q0, q3               ; step2[4] + step2[11]
   1140     vadd.s16        q13, q1, q2               ; step2[5] + step2[10]
   1141     vld1.s16        {q10}, [r2], r4           ; load data step2[6]
   1142     vld1.s16        {q11}, [r2], r4           ; load data step2[7]
   1143     vst1.64         {d24}, [r1], r3           ; store output[4]
   1144     vst1.64         {d25}, [r1], r5
   1145     vst1.64         {d26}, [r1], r3           ; store output[5]
   1146     vst1.64         {d27}, [r1], r5
   1147     vadd.s16        q12, q10, q9              ; step2[6] + step2[9]
   1148     vadd.s16        q13, q11, q8              ; step2[7] + step2[8]
   1149     vsub.s16        q2, q1, q2                ; step2[5] - step2[10]
   1150     vsub.s16        q3, q0, q3                ; step2[4] - step2[11]
   1151     vsub.s16        q8, q11, q8               ; step2[7] - step2[8]
   1152     vsub.s16        q9, q10, q9               ; step2[6] - step2[9]
   1153     vst1.64         {d24}, [r1], r3           ; store output[6]
   1154     vst1.64         {d25}, [r1], r5
   1155     vst1.64         {d26}, [r1], r3           ; store output[7]
   1156     vst1.64         {d27}, [r1], r5
   1157 
   1158     ; store the data  output 8,9,10,11,12,13,14,15
   1159     vst1.64         {d16}, [r1], r3
   1160     vst1.64         {d17}, [r1], r5
   1161     vst1.64         {d18}, [r1], r3
   1162     vst1.64         {d19}, [r1], r5
   1163     vst1.64         {d4}, [r1], r3
   1164     vst1.64         {d5}, [r1], r5
   1165     vst1.64         {d6}, [r1], r3
   1166     vst1.64         {d7}, [r1], r5
   1167     vst1.64         {d8}, [r1], r3
   1168     vst1.64         {d9}, [r1], r5
   1169     vst1.64         {d10}, [r1], r3
   1170     vst1.64         {d11}, [r1], r5
   1171     vst1.64         {d28}, [r1], r3
   1172     vst1.64         {d29}, [r1], r5
   1173     vst1.64         {d30}, [r1], r3
   1174     vst1.64         {d31}, [r1], r5
   1175 end_idct10_16x16_pass2
   1176     pop             {r3-r9}
   1177     bx              lr
   1178     ENDP  ; |vp9_idct16x16_10_add_neon_pass2|
   1179     END
   1180