From 4082bf9d7c607c62a1ab8b3573f695de2cd39dd6 Mon Sep 17 00:00:00 2001
From: hkuang <hkuang@google.com>
Date: Wed, 21 Aug 2013 14:19:08 -0700
Subject: [PATCH] Add neon optimize vp9_short_idct10_16x16_add.

vp9_short_idct10_16x16_add is used to handle the block that only have valid data
at top left 4x4 block. All the other datas are 0. So we could cut many
unnecessary calculations in order to save instructions.

Change-Id: I6e30a3fee1ece5af7f258532416d0bfddd1143f0
---
 vp9/common/arm/neon/vp9_idct16x16_neon.c      |  70 ++
 .../arm/neon/vp9_short_idct16x16_add_neon.asm | 785 +++++++++++++-----
 vp9/common/vp9_rtcd_defs.sh                   |   2 +-
 3 files changed, 655 insertions(+), 202 deletions(-)

diff --git a/vp9/common/arm/neon/vp9_idct16x16_neon.c b/vp9/common/arm/neon/vp9_idct16x16_neon.c
index 319d58f6fd..fc38605925 100644
--- a/vp9/common/arm/neon/vp9_idct16x16_neon.c
+++ b/vp9/common/arm/neon/vp9_idct16x16_neon.c
@@ -20,6 +20,15 @@ extern void vp9_short_idct16x16_add_neon_pass2(int16_t *src,
                                                int16_t skip_adding,
                                                uint8_t *dest,
                                                int dest_stride);
+extern void vp9_short_idct10_16x16_add_neon_pass1(int16_t *input,
+                                               int16_t *output,
+                                               int output_stride);
+extern void vp9_short_idct10_16x16_add_neon_pass2(int16_t *src,
+                                               int16_t *output,
+                                               int16_t *pass1Output,
+                                               int16_t skip_adding,
+                                               uint8_t *dest,
+                                               int dest_stride);
 extern void save_registers();
 extern void restore_registers();
 
@@ -97,3 +106,64 @@ void vp9_short_idct16x16_add_neon(int16_t *input,
 
   return;
 }
+
+void vp9_short_idct10_16x16_add_neon(int16_t *input,
+                                  uint8_t *dest, int dest_stride) {
+  int16_t pass1_output[16*16] = {0};
+  int16_t row_idct_output[16*16] = {0};
+
+  // save d8-d15 register values.
+  save_registers();
+
+  /* Parallel idct on the upper 8 rows */
+  // First pass processes even elements 0, 2, 4, 6, 8, 10, 12, 14 and save the
+  // stage 6 result in pass1_output.
+  vp9_short_idct10_16x16_add_neon_pass1(input, pass1_output, 8);
+
+  // Second pass processes odd elements 1, 3, 5, 7, 9, 11, 13, 15 and combines
+  // with result in pass1(pass1_output) to calculate final result in stage 7
+  // which will be saved into row_idct_output.
+  vp9_short_idct10_16x16_add_neon_pass2(input+1,
+                                        row_idct_output,
+                                        pass1_output,
+                                        0,
+                                        dest,
+                                        dest_stride);
+
+  /* Skip Parallel idct on the lower 8 rows as they are all 0s */
+
+  /* Parallel idct on the left 8 columns */
+  // First pass processes even elements 0, 2, 4, 6, 8, 10, 12, 14 and save the
+  // stage 6 result in pass1_output.
+  vp9_short_idct16x16_add_neon_pass1(row_idct_output, pass1_output, 8);
+
+  // Second pass processes odd elements 1, 3, 5, 7, 9, 11, 13, 15 and combines
+  // with result in pass1(pass1_output) to calculate final result in stage 7.
+  // Then add the result to the destination data.
+  vp9_short_idct16x16_add_neon_pass2(row_idct_output+1,
+                                     row_idct_output,
+                                     pass1_output,
+                                     1,
+                                     dest,
+                                     dest_stride);
+
+  /* Parallel idct on the right 8 columns */
+  // First pass processes even elements 0, 2, 4, 6, 8, 10, 12, 14 and save the
+  // stage 6 result in pass1_output.
+  vp9_short_idct16x16_add_neon_pass1(row_idct_output+8*16, pass1_output, 8);
+
+  // Second pass processes odd elements 1, 3, 5, 7, 9, 11, 13, 15 and combines
+  // with result in pass1(pass1_output) to calculate final result in stage 7.
+  // Then add the result to the destination data.
+  vp9_short_idct16x16_add_neon_pass2(row_idct_output+8*16+1,
+                                     row_idct_output+8,
+                                     pass1_output,
+                                     1,
+                                     dest+8,
+                                     dest_stride);
+
+  // restore d8-d15 register values.
+  restore_registers();
+
+  return;
+}
diff --git a/vp9/common/arm/neon/vp9_short_idct16x16_add_neon.asm b/vp9/common/arm/neon/vp9_short_idct16x16_add_neon.asm
index 8d0eab937c..8df543565a 100644
--- a/vp9/common/arm/neon/vp9_short_idct16x16_add_neon.asm
+++ b/vp9/common/arm/neon/vp9_short_idct16x16_add_neon.asm
@@ -10,6 +10,8 @@
 
     EXPORT  |vp9_short_idct16x16_add_neon_pass1|
     EXPORT  |vp9_short_idct16x16_add_neon_pass2|
+    EXPORT  |vp9_short_idct10_16x16_add_neon_pass1|
+    EXPORT  |vp9_short_idct10_16x16_add_neon_pass2|
     EXPORT  |save_registers|
     EXPORT  |restore_registers|
     ARM
@@ -88,11 +90,11 @@
     vmull.s16       q2, d18, d0
     vmull.s16       q3, d19, d0
 
-    ; step2[4] * cospi_28_64 - step2[7] * cospi_4_64
+    ; temp1 = step2[4] * cospi_28_64 - step2[7] * cospi_4_64
     vmlsl.s16       q2, d30, d1
     vmlsl.s16       q3, d31, d1
 
-    ; dct_const_round_shift(temp1);
+    ; dct_const_round_shift(temp1)
     vqrshrn.s32     d8, q2, #14               ; >> 14
     vqrshrn.s32     d9, q3, #14               ; >> 14
 
@@ -100,16 +102,16 @@
     vmull.s16       q2, d18, d1
     vmull.s16       q3, d19, d1
 
-    ; step2[4] * cospi_4_64 + step2[7] * cospi_28_64
+    ; temp2 = step2[4] * cospi_4_64 + step2[7] * cospi_28_64
     vmlal.s16       q2, d30, d0
     vmlal.s16       q3, d31, d0
 
-    ; dct_const_round_shift(temp2);
+    ; dct_const_round_shift(temp2)
     vqrshrn.s32     d14, q2, #14              ; >> 14
     vqrshrn.s32     d15, q3, #14              ; >> 14
 
-    vdup.16         d0, r3;                   ; duplicate cospi_12_64
-    vdup.16         d1, r12;                  ; duplicate cospi_20_64
+    vdup.16         d0, r3                   ; duplicate cospi_12_64
+    vdup.16         d1, r12                  ; duplicate cospi_20_64
 
     ; preloading to avoid stall
     ; generate cospi_16_64 = 11585
@@ -124,11 +126,11 @@
     vmull.s16       q2, d26, d0
     vmull.s16       q3, d27, d0
 
-    ; input[5] * cospi_12_64 - input[3] * cospi_20_64
+    ; temp1 = input[5] * cospi_12_64 - input[3] * cospi_20_64
     vmlsl.s16       q2, d22, d1
     vmlsl.s16       q3, d23, d1
 
-    ; dct_const_round_shift(temp1);
+    ; dct_const_round_shift(temp1)
     vqrshrn.s32     d10, q2, #14              ; >> 14
     vqrshrn.s32     d11, q3, #14              ; >> 14
 
@@ -136,11 +138,11 @@
     vmull.s16       q2, d26, d1
     vmull.s16       q3, d27, d1
 
-    ; step2[5] * cospi_20_64 + step2[6] * cospi_12_64
+    ; temp2 = step2[5] * cospi_20_64 + step2[6] * cospi_12_64
     vmlal.s16       q2, d22, d0
     vmlal.s16       q3, d23, d0
 
-    ; dct_const_round_shift(input_dc * cospi_16_64)
+    ; dct_const_round_shift(temp2)
     vqrshrn.s32     d12, q2, #14              ; >> 14
     vqrshrn.s32     d13, q3, #14              ; >> 14
 
@@ -155,19 +157,19 @@
     vmull.s16       q0, d24, d30
     vmull.s16       q1, d25, d30
 
-    ; (step1[0] + step1[1]) * cospi_16_64;
+    ; temp1 = (step1[0] + step1[1]) * cospi_16_64
     vadd.s32        q3, q2, q0
     vadd.s32        q15, q11, q1
 
-    ; step2[0] = dct_const_round_shift(temp1)
+    ; dct_const_round_shift(temp1)
     vqrshrn.s32     d16, q3, #14              ; >> 14
     vqrshrn.s32     d17, q15, #14             ; >> 14
 
-    ; (step1[0] - step1[1]) * cospi_16_64
+    ; temp2 = (step1[0] - step1[1]) * cospi_16_64
     vsub.s32        q3, q2, q0
     vsub.s32        q15, q11, q1
 
-    ; dct_const_round_shift(input_dc * cospi_16_64)
+    ; dct_const_round_shift(temp2)
     vqrshrn.s32     d18, q3, #14              ; >> 14
     vqrshrn.s32     d19, q15, #14             ; >> 14
 
@@ -183,11 +185,11 @@
     vmull.s16       q0, d20, d31
     vmull.s16       q1, d21, d31
 
-    ; input[1] * cospi_8_64 + input[3] * cospi_24_64
+    ; temp2 = input[1] * cospi_8_64 + input[3] * cospi_24_64
     vmlal.s16       q0, d28, d30
     vmlal.s16       q1, d29, d30
 
-    ; dct_const_round_shift(temp2);
+    ; dct_const_round_shift(temp2)
     vqrshrn.s32     d22, q0, #14              ; >> 14
     vqrshrn.s32     d23, q1, #14              ; >> 14
 
@@ -195,11 +197,11 @@
     vmull.s16       q0, d20, d30
     vmull.s16       q1, d21, d30
 
-    ; input[1] * cospi_24_64 - input[3] * cospi_8_64
+    ; temp1 = input[1] * cospi_24_64 - input[3] * cospi_8_64
     vmlsl.s16       q0, d28, d31
     vmlsl.s16       q1, d29, d31
 
-    ; dct_const_round_shift(input_dc * cospi_16_64)
+    ; dct_const_round_shift(temp1)
     vqrshrn.s32     d20, q0, #14              ; >> 14
     vqrshrn.s32     d21, q1, #14              ; >> 14
     vsub.s16        q13, q4, q5               ; step2[5] = step1[4] - step1[5];
@@ -219,27 +221,27 @@
 
     vdup.16         d16, r3;                  ; duplicate cospi_16_64
 
-    ; step2[6] * cospi_16_64
-    vmull.s16       q9, d28, d16
-    vmull.s16       q10, d29, d16
-
     ; step2[5] * cospi_16_64
     vmull.s16       q11, d26, d16
     vmull.s16       q12, d27, d16
 
-    ; (step2[6] - step2[5]) * cospi_16_64
+    ; step2[6] * cospi_16_64
+    vmull.s16       q9, d28, d16
+    vmull.s16       q10, d29, d16
+
+    ; temp1 = (step2[6] - step2[5]) * cospi_16_64
     vsub.s32        q6, q9, q11
     vsub.s32        q7, q10, q12
 
-    ; step1[5] = dct_const_round_shift(temp1);
+    ; dct_const_round_shift(temp1)
     vqrshrn.s32     d10, q6, #14              ; >> 14
     vqrshrn.s32     d11, q7, #14              ; >> 14
 
-    ; temp2 = (step2[5] + step2[6]) * cospi_16_64;
+    ; temp2 = (step2[5] + step2[6]) * cospi_16_64
     vadd.s32        q9, q9, q11
     vadd.s32        q10, q10, q12
 
-    ; step1[6] = dct_const_round_shift(temp2);
+    ; dct_const_round_shift(temp2)
     vqrshrn.s32     d12, q9, #14              ; >> 14
     vqrshrn.s32     d13, q10, #14             ; >> 14
 
@@ -298,7 +300,7 @@
     push            {r3-r9}
 
     ; TODO(hkuang): Find a better way to load the elements.
-    ; load elements of 0, 2, 4, 6, 8, 10, 12, 14 into q8 - q15
+    ; load elements of 1, 3, 5, 7, 9, 11, 13, 15 into q8 - q15
     vld2.s16        {q8,q9}, [r0]!
     vld2.s16        {q9,q10}, [r0]!
     vld2.s16        {q10,q11}, [r0]!
@@ -333,15 +335,15 @@
     mov             r12, #0x2800
     add             r12, #0x9a
 
-    ; step1[8] * cospi_30_64 = input[1] * cospi_30_64
+    ; step1[8] * cospi_30_64
     vmull.s16       q2, d16, d12
     vmull.s16       q3, d17, d12
 
-    ; step1[8] * cospi_30_64 - step1[15] * cospi_2_64
+    ; temp1 = step1[8] * cospi_30_64 - step1[15] * cospi_2_64
     vmlsl.s16       q2, d30, d13
     vmlsl.s16       q3, d31, d13
 
-    ; dct_const_round_shift(temp1);
+    ; dct_const_round_shift(temp1)
     vqrshrn.s32     d0, q2, #14               ; >> 14
     vqrshrn.s32     d1, q3, #14               ; >> 14
 
@@ -349,11 +351,11 @@
     vmull.s16       q2, d16, d13
     vmull.s16       q3, d17, d13
 
-    ; step1[8] * cospi_2_64 + step1[15] * cospi_30_64
+    ; temp2 = step1[8] * cospi_2_64 + step1[15] * cospi_30_64
     vmlal.s16       q2, d30, d12
     vmlal.s16       q3, d31, d12
 
-    ; dct_const_round_shift(temp2);
+    ; dct_const_round_shift(temp2)
     vqrshrn.s32     d14, q2, #14              ; >> 14
     vqrshrn.s32     d15, q3, #14              ; >> 14
 
@@ -369,15 +371,15 @@
     mov             r12, #0x3800
     add             r12, #0x71
 
-    ; step1[9] * cospi_14_64 = input[9] * cospi_12_64
+    ; step1[9] * cospi_14_64
     vmull.s16       q2, d24, d30
     vmull.s16       q3, d25, d30
 
-    ; step1[9] * cospi_14_64 - step1[14] * cospi_18_64
+    ; temp1 = step1[9] * cospi_14_64 - step1[14] * cospi_18_64
     vmlsl.s16       q2, d22, d31
     vmlsl.s16       q3, d23, d31
 
-    ; dct_const_round_shift(temp1);
+    ; dct_const_round_shift(temp1)
     vqrshrn.s32     d2, q2, #14               ; >> 14
     vqrshrn.s32     d3, q3, #14               ; >> 14
 
@@ -385,11 +387,11 @@
     vmull.s16       q2, d24, d31
     vmull.s16       q3, d25, d31
 
-    ; step1[9] * cospi_18_64 + step1[14] * cospi_14_64
+    ; temp2 = step1[9] * cospi_18_64 + step1[14] * cospi_14_64
     vmlal.s16       q2, d22, d30
     vmlal.s16       q3, d23, d30
 
-    ; dct_const_round_shift(temp1)
+    ; dct_const_round_shift(temp2)
     vqrshrn.s32     d12, q2, #14              ; >> 14
     vqrshrn.s32     d13, q3, #14              ; >> 14
 
@@ -400,11 +402,11 @@
     vmull.s16       q11, d20, d30
     vmull.s16       q12, d21, d30
 
-    ; step1[10] * cospi_22_64 - step1[13] * cospi_10_64
+    ; temp1 = step1[10] * cospi_22_64 - step1[13] * cospi_10_64
     vmlsl.s16       q11, d26, d31
     vmlsl.s16       q12, d27, d31
 
-    ; dct_const_round_shift(temp1);
+    ; dct_const_round_shift(temp1)
     vqrshrn.s32     d4, q11, #14              ; >> 14
     vqrshrn.s32     d5, q12, #14              ; >> 14
 
@@ -412,11 +414,11 @@
     vmull.s16       q11, d20, d31
     vmull.s16       q12, d21, d31
 
-    ; step1[10] * cospi_10_64 + step1[13] * cospi_22_64
+    ; temp2 = step1[10] * cospi_10_64 + step1[13] * cospi_22_64
     vmlal.s16       q11, d26, d30
     vmlal.s16       q12, d27, d30
 
-    ; dct_const_round_shift(input_dc * cospi_16_64)
+    ; dct_const_round_shift(temp2)
     vqrshrn.s32     d10, q11, #14             ; >> 14
     vqrshrn.s32     d11, q12, #14             ; >> 14
 
@@ -432,15 +434,15 @@
     vdup.16         d30, r3                   ; duplicate cospi_6_64
     vdup.16         d31, r12                  ; duplicate cospi_26_64
 
-    ; step1[11] * cospi_6_64 = input[13] * cospi_6_64
+    ; step1[11] * cospi_6_64
     vmull.s16       q10, d28, d30
     vmull.s16       q11, d29, d30
 
-    ; step1[11] * cospi_6_64 - step1[12] * cospi_26_64
+    ; temp1 = step1[11] * cospi_6_64 - step1[12] * cospi_26_64
     vmlsl.s16       q10, d18, d31
     vmlsl.s16       q11, d19, d31
 
-    ; dct_const_round_shift(temp1);
+    ; dct_const_round_shift(temp1)
     vqrshrn.s32     d6, q10, #14              ; >> 14
     vqrshrn.s32     d7, q11, #14              ; >> 14
 
@@ -448,11 +450,11 @@
     vmull.s16       q10, d28, d31
     vmull.s16       q11, d29, d31
 
-    ; step1[12] * cospi_6_64
+    ; temp2 = step1[11] * cospi_26_64 + step1[12] * cospi_6_64
     vmlal.s16       q10, d18, d30
     vmlal.s16       q11, d19, d30
 
-    ; dct_const_round_shift(input_dc * cospi_16_64)
+    ; dct_const_round_shift(temp2)
     vqrshrn.s32     d8, q10, #14              ; >> 14
     vqrshrn.s32     d9, q11, #14              ; >> 14
 
@@ -475,7 +477,7 @@
     mov             r12, #0x3b00
     add             r12, #0x21
 
-    ; -step1[9] * cospi_8_64 + step1[14] * cospi_24_64;
+    ; -step1[9] * cospi_8_64 + step1[14] * cospi_24_64
     vdup.16         d30, r12                  ; duplicate cospi_8_64
     vdup.16         d31, r3                   ; duplicate cospi_24_64
 
@@ -483,7 +485,7 @@
     vmull.s16       q4, d28, d31
     vmull.s16       q5, d29, d31
 
-    ; -step1[9] * cospi_8_64 + step1[14] * cospi_24_64
+    ; temp1 = -step1[9] * cospi_8_64 + step1[14] * cospi_24_64
     vmlsl.s16       q4, d18, d30
     vmlsl.s16       q5, d19, d30
 
@@ -495,18 +497,17 @@
     vmull.s16       q2, d18, d31
     vmull.s16       q3, d19, d31
 
-    ; step1[9] * cospi_24_64 + step1[14] * cospi_8_64
+    ; temp2 = step1[9] * cospi_24_64 + step1[14] * cospi_8_64
     vmlal.s16       q2, d28, d30
     vmlal.s16       q3, d29, d30
 
-    ; dct_const_round_shift(temp1)
+    ; dct_const_round_shift(temp2)
     vqrshrn.s32     d12, q2, #14              ; >> 14
     vqrshrn.s32     d13, q3, #14              ; >> 14
 
     vmov.s16        q3, q11
     vmov.s16        q4, q12
 
-    ; -step1[10] * cospi_24_64 - step1[13] * cospi_8_64
     rsb              r12, #0
     vdup.16         d30, r12                  ; duplicate -cospi_8_64
 
@@ -514,11 +515,11 @@
     vmull.s16       q11, d26, d30
     vmull.s16       q12, d27, d30
 
-    ; -step1[10] * cospi_8_64 + step1[13] * cospi_24_64
+    ; temp2 = -step1[10] * cospi_8_64 + step1[13] * cospi_24_64
     vmlsl.s16       q11, d20, d31
     vmlsl.s16       q12, d21, d31
 
-    ; dct_const_round_shift(temp1)
+    ; dct_const_round_shift(temp2)
     vqrshrn.s32     d4, q11, #14              ; >> 14
     vqrshrn.s32     d5, q12, #14              ; >> 14
 
@@ -526,11 +527,11 @@
     vmull.s16       q8, d20, d30
     vmull.s16       q9, d21, d30
 
-    ; -step1[10] * cospi_8_64 + step1[13] * cospi_24_64
+    ; temp1 = -step1[10] * cospi_8_64 + step1[13] * cospi_24_64
     vmlal.s16       q8, d26, d31
     vmlal.s16       q9, d27, d31
 
-    ; dct_const_round_shift(temp2)
+    ; dct_const_round_shift(temp1)
     vqrshrn.s32     d10, q8, #14              ; >> 14
     vqrshrn.s32     d11, q9, #14              ; >> 14
 
@@ -544,67 +545,60 @@
     vadd.s16        q14, q6, q5               ; step1[14] =step2[13]+step2[14];
     vadd.s16        q15, q7, q4               ; step1[15] =step2[12]+step2[15];
 
-    ; stage 6. The following instruction may not be needed, but they will make
-    ; the data more easy to manage as data will be grouped in q0 - q7.
-    vmov.s16        q0, q8
-    vmov.s16        q1, q9
-    vmov.s16        q6, q14
-    vmov.s16        q7, q15
-
+    ; stage 6.
     ; generate cospi_16_64 = 11585
     mov             r12, #0x2d00
     add             r12, #0x41
 
-    vdup.16         d30, r12                  ; duplicate cospi_16_64
+    vdup.16         d14, r12                  ; duplicate cospi_16_64
 
     ; step1[13] * cospi_16_64
-    vmull.s16       q3, d26, d30
-    vmull.s16       q4, d27, d30
+    vmull.s16       q3, d26, d14
+    vmull.s16       q4, d27, d14
 
     ; step1[10] * cospi_16_64
-    vmull.s16       q8, d20, d30
-    vmull.s16       q9, d21, d30
+    vmull.s16       q0, d20, d14
+    vmull.s16       q1, d21, d14
 
-    ; (-step1[10] + step1[13]) * cospi_16_64;
-    vsub.s32        q5, q3, q8
-    vsub.s32        q14, q4, q9
+    ; temp1 = (-step1[10] + step1[13]) * cospi_16_64
+    vsub.s32        q5, q3, q0
+    vsub.s32        q6, q4, q1
 
     ; dct_const_round_shift(temp1)
     vqrshrn.s32     d4, q5, #14               ; >> 14
-    vqrshrn.s32     d5, q14, #14              ; >> 14
+    vqrshrn.s32     d5, q6, #14               ; >> 14
 
-    ; (step1[10] + step1[13]) * cospi_16_64
-    vadd.s32        q5, q3, q8
-    vadd.s32        q14, q4, q9
+    ; temp2 = (step1[10] + step1[13]) * cospi_16_64
+    vadd.s32        q5, q3, q0
+    vadd.s32        q6, q4, q1
 
-    ; dct_const_round_shift(temp2);
+    ; dct_const_round_shift(temp2)
     vqrshrn.s32     d10, q5, #14              ; >> 14
-    vqrshrn.s32     d11, q14, #14             ; >> 14
+    vqrshrn.s32     d11, q6, #14              ; >> 14
 
-    ; (-step1[11] + step1[12]) * cospi_16_64;
     ; step1[11] * cospi_16_64
-    vmull.s16       q8, d22, d30
-    vmull.s16       q9, d23, d30
+    vmull.s16       q0, d22, d14
+    vmull.s16       q1, d23, d14
 
     ; step1[12] * cospi_16_64
-    vmull.s16       q13, d24, d30
-    vmull.s16       q14, d25, d30
+    vmull.s16       q13, d24, d14
+    vmull.s16       q6, d25, d14
 
-    ; (-step1[11] + step1[12]) * cospi_16_64
-    vsub.s32        q10, q13, q8
-    vsub.s32        q4, q14, q9
+    ; temp1 = (-step1[11] + step1[12]) * cospi_16_64
+    vsub.s32        q10, q13, q0
+    vsub.s32        q4, q6, q1
 
-    ; dct_const_round_shift(input_dc * cospi_16_64)
+    ; dct_const_round_shift(temp1)
     vqrshrn.s32     d6, q10, #14              ; >> 14
     vqrshrn.s32     d7, q4, #14               ; >> 14
 
-    ; (step1[11] + step1[12]) * cospi_16_64
-    vadd.s32        q13, q13, q8
-    vadd.s32        q14, q14, q9
+    ; temp2 = (step1[11] + step1[12]) * cospi_16_64
+    vadd.s32        q13, q13, q0
+    vadd.s32        q6, q6, q1
 
-    ; dct_const_round_shift(temp2);
+    ; dct_const_round_shift(temp2)
     vqrshrn.s32     d8, q13, #14              ; >> 14
-    vqrshrn.s32     d9, q14, #14              ; >> 14
+    vqrshrn.s32     d9, q6, #14               ; >> 14
 
     mov              r4, #16                  ; pass1Output stride
     ldr              r3, [sp]                 ; load skip_adding
@@ -617,113 +611,113 @@
 
     ; stage 7
     ; load the data in pass1
-    vld1.s16        {q8}, [r2], r4            ; load data step2[0]
-    vld1.s16        {q9}, [r2], r4            ; load data step2[1]
+    vld1.s16        {q0}, [r2], r4            ; load data step2[0]
+    vld1.s16        {q1}, [r2], r4            ; load data step2[1]
     vld1.s16        {q10}, [r2], r4           ; load data step2[2]
     vld1.s16        {q11}, [r2], r4           ; load data step2[3]
-    vld1.64         {d28}, [r7], r8           ; load destinatoin data
-    vld1.64         {d29}, [r7], r8           ; load destinatoin data
-    vadd.s16        q12, q8, q7               ; step2[0] + step2[15]
-    vadd.s16        q13, q9, q6               ; step2[1] + step2[14]
+    vld1.64         {d12}, [r7], r8           ; load destinatoin data
+    vld1.64         {d13}, [r7], r8           ; load destinatoin data
+    vadd.s16        q12, q0, q15              ; step2[0] + step2[15]
+    vadd.s16        q13, q1, q14              ; step2[1] + step2[14]
     vrshr.s16       q12, q12, #6              ; ROUND_POWER_OF_TWO
     vrshr.s16       q13, q13, #6              ; ROUND_POWER_OF_TWO
-    vaddw.u8        q12, q12, d28             ; + dest[j * dest_stride + i]
-    vaddw.u8        q13, q13, d29             ; + dest[j * dest_stride + i]
-    vqmovun.s16     d28, q12                  ; clip pixel
-    vqmovun.s16     d29, q13                  ; clip pixel
-    vst1.64         {d28}, [r9], r8           ; store the data
-    vst1.64         {d29}, [r9], r8           ; store the data
-    vsub.s16        q6, q9, q6                ; step2[1] - step2[14]
-    vsub.s16        q7, q8, q7                ; step2[0] - step2[15]
-    vld1.64         {d28}, [r7], r8           ; load destinatoin data
-    vld1.64         {d29}, [r7], r8           ; load destinatoin data
+    vaddw.u8        q12, q12, d12             ; + dest[j * dest_stride + i]
+    vaddw.u8        q13, q13, d13             ; + dest[j * dest_stride + i]
+    vqmovun.s16     d12, q12                  ; clip pixel
+    vqmovun.s16     d13, q13                  ; clip pixel
+    vst1.64         {d12}, [r9], r8           ; store the data
+    vst1.64         {d13}, [r9], r8           ; store the data
+    vsub.s16        q14, q1, q14              ; step2[1] - step2[14]
+    vsub.s16        q15, q0, q15              ; step2[0] - step2[15]
+    vld1.64         {d12}, [r7], r8           ; load destinatoin data
+    vld1.64         {d13}, [r7], r8           ; load destinatoin data
     vadd.s16        q12, q10, q5              ; step2[2] + step2[13]
     vadd.s16        q13, q11, q4              ; step2[3] + step2[12]
     vrshr.s16       q12, q12, #6              ; ROUND_POWER_OF_TWO
     vrshr.s16       q13, q13, #6              ; ROUND_POWER_OF_TWO
-    vaddw.u8        q12, q12, d28             ; + dest[j * dest_stride + i]
-    vaddw.u8        q13, q13, d29             ; + dest[j * dest_stride + i]
-    vqmovun.s16     d28, q12                  ; clip pixel
-    vqmovun.s16     d29, q13                  ; clip pixel
-    vst1.64         {d28}, [r9], r8           ; store the data
-    vst1.64         {d29}, [r9], r8           ; store the data
+    vaddw.u8        q12, q12, d12             ; + dest[j * dest_stride + i]
+    vaddw.u8        q13, q13, d13             ; + dest[j * dest_stride + i]
+    vqmovun.s16     d12, q12                  ; clip pixel
+    vqmovun.s16     d13, q13                  ; clip pixel
+    vst1.64         {d12}, [r9], r8           ; store the data
+    vst1.64         {d13}, [r9], r8           ; store the data
     vsub.s16        q4, q11, q4               ; step2[3] - step2[12]
     vsub.s16        q5, q10, q5               ; step2[2] - step2[13]
-    vld1.s16        {q8}, [r2], r4            ; load data step2[4]
-    vld1.s16        {q9}, [r2], r4            ; load data step2[5]
+    vld1.s16        {q0}, [r2], r4            ; load data step2[4]
+    vld1.s16        {q1}, [r2], r4            ; load data step2[5]
     vld1.s16        {q10}, [r2], r4           ; load data step2[6]
     vld1.s16        {q11}, [r2], r4           ; load data step2[7]
-    vld1.64         {d28}, [r7], r8           ; load destinatoin data
-    vld1.64         {d29}, [r7], r8           ; load destinatoin data
-    vadd.s16        q12, q8, q3               ; step2[4] + step2[11]
-    vadd.s16        q13, q9, q2               ; step2[5] + step2[10]
+    vld1.64         {d12}, [r7], r8           ; load destinatoin data
+    vld1.64         {d13}, [r7], r8           ; load destinatoin data
+    vadd.s16        q12, q0, q3               ; step2[4] + step2[11]
+    vadd.s16        q13, q1, q2               ; step2[5] + step2[10]
     vrshr.s16       q12, q12, #6              ; ROUND_POWER_OF_TWO
     vrshr.s16       q13, q13, #6              ; ROUND_POWER_OF_TWO
-    vaddw.u8        q12, q12, d28             ; + dest[j * dest_stride + i]
-    vaddw.u8        q13, q13, d29             ; + dest[j * dest_stride + i]
-    vqmovun.s16     d28, q12                  ; clip pixel
-    vqmovun.s16     d29, q13                  ; clip pixel
-    vst1.64         {d28}, [r9], r8           ; store the data
-    vst1.64         {d29}, [r9], r8           ; store the data
-    vsub.s16        q2, q9, q2                ; step2[5] - step2[10]
-    vsub.s16        q3, q8, q3                ; step2[4] - step2[11]
-    vld1.64         {d28}, [r7], r8           ; load destinatoin data
-    vld1.64         {d29}, [r7], r8           ; load destinatoin data
-    vadd.s16        q12, q10, q1              ; step2[6] + step2[9]
-    vadd.s16        q13, q11, q0              ; step2[7] + step2[8]
+    vaddw.u8        q12, q12, d12             ; + dest[j * dest_stride + i]
+    vaddw.u8        q13, q13, d13             ; + dest[j * dest_stride + i]
+    vqmovun.s16     d12, q12                  ; clip pixel
+    vqmovun.s16     d13, q13                  ; clip pixel
+    vst1.64         {d12}, [r9], r8           ; store the data
+    vst1.64         {d13}, [r9], r8           ; store the data
+    vsub.s16        q2, q1, q2                ; step2[5] - step2[10]
+    vsub.s16        q3, q0, q3                ; step2[4] - step2[11]
+    vld1.64         {d12}, [r7], r8           ; load destinatoin data
+    vld1.64         {d13}, [r7], r8           ; load destinatoin data
+    vadd.s16        q12, q10, q9              ; step2[6] + step2[9]
+    vadd.s16        q13, q11, q8              ; step2[7] + step2[8]
     vrshr.s16       q12, q12, #6              ; ROUND_POWER_OF_TWO
     vrshr.s16       q13, q13, #6              ; ROUND_POWER_OF_TWO
-    vaddw.u8        q12, q12, d28             ; + dest[j * dest_stride + i]
-    vaddw.u8        q13, q13, d29             ; + dest[j * dest_stride + i]
-    vqmovun.s16     d28, q12                  ; clip pixel
-    vqmovun.s16     d29, q13                  ; clip pixel
-    vst1.64         {d28}, [r9], r8           ; store the data
-    vst1.64         {d29}, [r9], r8           ; store the data
-    vld1.64         {d28}, [r7], r8           ; load destinatoin data
-    vld1.64         {d29}, [r7], r8           ; load destinatoin data
-    vsub.s16        q0, q11, q0               ; step2[7] - step2[8]
-    vsub.s16        q1, q10, q1               ; step2[6] - step2[9]
+    vaddw.u8        q12, q12, d12             ; + dest[j * dest_stride + i]
+    vaddw.u8        q13, q13, d13             ; + dest[j * dest_stride + i]
+    vqmovun.s16     d12, q12                  ; clip pixel
+    vqmovun.s16     d13, q13                  ; clip pixel
+    vst1.64         {d12}, [r9], r8           ; store the data
+    vst1.64         {d13}, [r9], r8           ; store the data
+    vld1.64         {d12}, [r7], r8           ; load destinatoin data
+    vld1.64         {d13}, [r7], r8           ; load destinatoin data
+    vsub.s16        q8, q11, q8               ; step2[7] - step2[8]
+    vsub.s16        q9, q10, q9               ; step2[6] - step2[9]
 
     ; store the data  output 8,9,10,11,12,13,14,15
-    vrshr.s16       q0, q0, #6                ; ROUND_POWER_OF_TWO
-    vaddw.u8        q0, q0, d28               ; + dest[j * dest_stride + i]
-    vqmovun.s16     d28, q0                   ; clip pixel
-    vst1.64         {d28}, [r9], r8           ; store the data
-    vld1.64         {d28}, [r7], r8           ; load destinatoin data
-    vrshr.s16       q1, q1, #6
-    vaddw.u8        q1, q1, d29               ; + dest[j * dest_stride + i]
-    vqmovun.s16     d29, q1                   ; clip pixel
-    vst1.64         {d29}, [r9], r8           ; store the data
-    vld1.64         {d29}, [r7], r8           ; load destinatoin data
+    vrshr.s16       q8, q8, #6                ; ROUND_POWER_OF_TWO
+    vaddw.u8        q8, q8, d12               ; + dest[j * dest_stride + i]
+    vqmovun.s16     d12, q8                   ; clip pixel
+    vst1.64         {d12}, [r9], r8           ; store the data
+    vld1.64         {d12}, [r7], r8           ; load destinatoin data
+    vrshr.s16       q9, q9, #6
+    vaddw.u8        q9, q9, d13               ; + dest[j * dest_stride + i]
+    vqmovun.s16     d13, q9                   ; clip pixel
+    vst1.64         {d13}, [r9], r8           ; store the data
+    vld1.64         {d13}, [r7], r8           ; load destinatoin data
     vrshr.s16       q2, q2, #6
-    vaddw.u8        q2, q2, d28               ; + dest[j * dest_stride + i]
-    vqmovun.s16     d28, q2                   ; clip pixel
-    vst1.64         {d28}, [r9], r8           ; store the data
-    vld1.64         {d28}, [r7], r8           ; load destinatoin data
+    vaddw.u8        q2, q2, d12               ; + dest[j * dest_stride + i]
+    vqmovun.s16     d12, q2                   ; clip pixel
+    vst1.64         {d12}, [r9], r8           ; store the data
+    vld1.64         {d12}, [r7], r8           ; load destinatoin data
     vrshr.s16       q3, q3, #6
-    vaddw.u8        q3, q3, d29               ; + dest[j * dest_stride + i]
-    vqmovun.s16     d29, q3                   ; clip pixel
-    vst1.64         {d29}, [r9], r8           ; store the data
-    vld1.64         {d29}, [r7], r8           ; load destinatoin data
+    vaddw.u8        q3, q3, d13               ; + dest[j * dest_stride + i]
+    vqmovun.s16     d13, q3                   ; clip pixel
+    vst1.64         {d13}, [r9], r8           ; store the data
+    vld1.64         {d13}, [r7], r8           ; load destinatoin data
     vrshr.s16       q4, q4, #6
-    vaddw.u8        q4, q4, d28               ; + dest[j * dest_stride + i]
-    vqmovun.s16     d28, q4                   ; clip pixel
-    vst1.64         {d28}, [r9], r8           ; store the data
-    vld1.64         {d28}, [r7], r8           ; load destinatoin data
+    vaddw.u8        q4, q4, d12               ; + dest[j * dest_stride + i]
+    vqmovun.s16     d12, q4                   ; clip pixel
+    vst1.64         {d12}, [r9], r8           ; store the data
+    vld1.64         {d12}, [r7], r8           ; load destinatoin data
     vrshr.s16       q5, q5, #6
-    vaddw.u8        q5, q5, d29               ; + dest[j * dest_stride + i]
-    vqmovun.s16     d29, q5                   ; clip pixel
-    vst1.64         {d29}, [r9], r8           ; store the data
-    vld1.64         {d29}, [r7], r8           ; load destinatoin data
-    vrshr.s16       q6, q6, #6
-    vaddw.u8        q6, q6, d28               ; + dest[j * dest_stride + i]
-    vqmovun.s16     d28, q6                   ; clip pixel
-    vst1.64         {d28}, [r9], r8           ; store the data
-    vld1.64         {d28}, [r7], r8           ; load destinatoin data
-    vrshr.s16       q7, q7, #6
-    vaddw.u8        q7, q7, d29               ; + dest[j * dest_stride + i]
-    vqmovun.s16     d29, q7                   ; clip pixel
-    vst1.64         {d29}, [r9], r8           ; store the data
+    vaddw.u8        q5, q5, d13               ; + dest[j * dest_stride + i]
+    vqmovun.s16     d13, q5                   ; clip pixel
+    vst1.64         {d13}, [r9], r8           ; store the data
+    vld1.64         {d13}, [r7], r8           ; load destinatoin data
+    vrshr.s16       q14, q14, #6
+    vaddw.u8        q14, q14, d12             ; + dest[j * dest_stride + i]
+    vqmovun.s16     d12, q14                  ; clip pixel
+    vst1.64         {d12}, [r9], r8           ; store the data
+    vld1.64         {d12}, [r7], r8           ; load destinatoin data
+    vrshr.s16       q15, q15, #6
+    vaddw.u8        q15, q15, d13             ; + dest[j * dest_stride + i]
+    vqmovun.s16     d13, q15                  ; clip pixel
+    vst1.64         {d13}, [r9], r8           ; store the data
     b               end_idct16x16_pass2
 
 skip_adding_dest
@@ -732,52 +726,52 @@ skip_adding_dest
     mov              r5, #24
     mov              r3, #8
 
-    vld1.s16        {q8}, [r2], r4            ; load data step2[0]
-    vld1.s16        {q9}, [r2], r4            ; load data step2[1]
+    vld1.s16        {q0}, [r2], r4            ; load data step2[0]
+    vld1.s16        {q1}, [r2], r4            ; load data step2[1]
+    vadd.s16        q12, q0, q15              ; step2[0] + step2[15]
+    vadd.s16        q13, q1, q14              ; step2[1] + step2[14]
     vld1.s16        {q10}, [r2], r4           ; load data step2[2]
     vld1.s16        {q11}, [r2], r4           ; load data step2[3]
-    vadd.s16        q12, q8, q7               ; step2[0] + step2[15]
-    vadd.s16        q13, q9, q6               ; step2[1] + step2[14]
     vst1.64         {d24}, [r1], r3           ; store output[0]
     vst1.64         {d25}, [r1], r5
     vst1.64         {d26}, [r1], r3           ; store output[1]
     vst1.64         {d27}, [r1], r5
-    vsub.s16        q6, q9, q6                ; step2[1] - step2[14]
-    vsub.s16        q7, q8, q7                ; step2[0] - step2[15]
     vadd.s16        q12, q10, q5              ; step2[2] + step2[13]
     vadd.s16        q13, q11, q4              ; step2[3] + step2[12]
+    vsub.s16        q14, q1, q14              ; step2[1] - step2[14]
+    vsub.s16        q15, q0, q15              ; step2[0] - step2[15]
     vst1.64         {d24}, [r1], r3           ; store output[2]
     vst1.64         {d25}, [r1], r5
     vst1.64         {d26}, [r1], r3           ; store output[3]
     vst1.64         {d27}, [r1], r5
     vsub.s16        q4, q11, q4               ; step2[3] - step2[12]
     vsub.s16        q5, q10, q5               ; step2[2] - step2[13]
-    vld1.s16        {q8}, [r2], r4            ; load data step2[4]
-    vld1.s16        {q9}, [r2], r4            ; load data step2[5]
+    vld1.s16        {q0}, [r2], r4            ; load data step2[4]
+    vld1.s16        {q1}, [r2], r4            ; load data step2[5]
+    vadd.s16        q12, q0, q3               ; step2[4] + step2[11]
+    vadd.s16        q13, q1, q2               ; step2[5] + step2[10]
     vld1.s16        {q10}, [r2], r4           ; load data step2[6]
     vld1.s16        {q11}, [r2], r4           ; load data step2[7]
-    vadd.s16        q12, q8, q3               ; step2[4] + step2[11]
-    vadd.s16        q13, q9, q2               ; step2[5] + step2[10]
     vst1.64         {d24}, [r1], r3           ; store output[4]
     vst1.64         {d25}, [r1], r5
     vst1.64         {d26}, [r1], r3           ; store output[5]
     vst1.64         {d27}, [r1], r5
-    vsub.s16        q2, q9, q2                ; step2[5] - step2[10]
-    vsub.s16        q3, q8, q3                ; step2[4] - step2[11]
-    vadd.s16        q12, q10, q1              ; step2[6] + step2[9]
-    vadd.s16        q13, q11, q0              ; step2[7] + step2[8]
+    vadd.s16        q12, q10, q9              ; step2[6] + step2[9]
+    vadd.s16        q13, q11, q8              ; step2[7] + step2[8]
+    vsub.s16        q2, q1, q2                ; step2[5] - step2[10]
+    vsub.s16        q3, q0, q3                ; step2[4] - step2[11]
+    vsub.s16        q8, q11, q8               ; step2[7] - step2[8]
+    vsub.s16        q9, q10, q9               ; step2[6] - step2[9]
     vst1.64         {d24}, [r1], r3           ; store output[6]
     vst1.64         {d25}, [r1], r5
     vst1.64         {d26}, [r1], r3           ; store output[7]
     vst1.64         {d27}, [r1], r5
-    vsub.s16        q0, q11, q0               ; step2[7] - step2[8]
-    vsub.s16        q1, q10, q1               ; step2[6] - step2[9]
 
     ; store the data  output 8,9,10,11,12,13,14,15
-    vst1.64         {d0}, [r1], r3
-    vst1.64         {d1}, [r1], r5
-    vst1.64         {d2}, [r1], r3
-    vst1.64         {d3}, [r1], r5
+    vst1.64         {d16}, [r1], r3
+    vst1.64         {d17}, [r1], r5
+    vst1.64         {d18}, [r1], r3
+    vst1.64         {d19}, [r1], r5
     vst1.64         {d4}, [r1], r3
     vst1.64         {d5}, [r1], r5
     vst1.64         {d6}, [r1], r3
@@ -786,21 +780,410 @@ skip_adding_dest
     vst1.64         {d9}, [r1], r5
     vst1.64         {d10}, [r1], r3
     vst1.64         {d11}, [r1], r5
-    vst1.64         {d12}, [r1], r3
-    vst1.64         {d13}, [r1], r5
-    vst1.64         {d14}, [r1], r3
-    vst1.64         {d15}, [r1], r5
-
+    vst1.64         {d28}, [r1], r3
+    vst1.64         {d29}, [r1], r5
+    vst1.64         {d30}, [r1], r3
+    vst1.64         {d31}, [r1], r5
 end_idct16x16_pass2
     pop             {r3-r9}
     bx              lr
     ENDP  ; |vp9_short_idct16x16_add_neon_pass2|
+
+;void |vp9_short_idct10_16x16_add_neon_pass1|(int16_t *input,
+;                                             int16_t *output, int output_stride)
+;
+; r0  int16_t input
+; r1  int16_t *output
+; r2  int  output_stride)
+
+; idct16 stage1 - stage6 on all the elements loaded in q8-q15. The output
+; will be stored back into q8-q15 registers. This function will touch q0-q7
+; registers and use them as buffer during calculation.
+|vp9_short_idct10_16x16_add_neon_pass1| PROC
+
+    ; TODO(hkuang): Find a better way to load the elements.
+    ; load elements of 0, 2, 4, 6, 8, 10, 12, 14 into q8 - q15
+    vld2.s16        {q8,q9}, [r0]!
+    vld2.s16        {q9,q10}, [r0]!
+    vld2.s16        {q10,q11}, [r0]!
+    vld2.s16        {q11,q12}, [r0]!
+    vld2.s16        {q12,q13}, [r0]!
+    vld2.s16        {q13,q14}, [r0]!
+    vld2.s16        {q14,q15}, [r0]!
+    vld2.s16        {q1,q2}, [r0]!
+    vmov.s16        q15, q1
+
+    ; generate  cospi_28_64*2 = 6392
+    mov             r3, #0x1800
+    add             r3, #0xf8
+
+    ; generate cospi_4_64*2  = 32138
+    mov             r12, #0x7d00
+    add             r12, #0x8a
+
+    ; transpose the input data
+    TRANSPOSE8X8
+
+    ; stage 3
+    vdup.16         q0, r3                    ; duplicate cospi_28_64*2
+    vdup.16         q1, r12                   ; duplicate cospi_4_64*2
+
+    ; The following instructions use vqrdmulh to do the
+    ; dct_const_round_shift(step2[4] * cospi_28_64). vvqrdmulh will multiply,
+    ; double, and return the high 16 bits, effectively giving >> 15. Doubling
+    ; the constant will change this to >> 14.
+    ; dct_const_round_shift(step2[4] * cospi_28_64);
+    vqrdmulh.s16    q4, q9, q0
+
+    ; preloading to avoid stall
+    ; generate cospi_16_64*2 = 23170
+    mov             r3, #0x5a00
+    add             r3, #0x82
+
+    ; dct_const_round_shift(step2[4] * cospi_4_64);
+    vqrdmulh.s16    q7, q9, q1
+
+    ; stage 4
+    vdup.16         q1, r3                   ; cospi_16_64*2
+
+    ; generate cospi_16_64 = 11585
+    mov             r3, #0x2d00
+    add             r3, #0x41
+
+    vdup.16         d4, r3;                  ; duplicate cospi_16_64
+
+    ; dct_const_round_shift(step1[0] * cospi_16_64)
+    vqrdmulh.s16    q8, q8, q1
+
+    ; step2[5] * cospi_16_64
+    vmull.s16       q12, d9, d4
+    vmull.s16       q11, d8, d4
+
+    ; step2[6] * cospi_16_64
+    vmull.s16       q9, d14, d4
+    vmull.s16       q10, d15, d4
+
+    ; temp1 = (step2[6] - step2[5]) * cospi_16_64
+    vsub.s32        q15, q10, q12
+    vsub.s32        q6, q9, q11
+
+    ; dct_const_round_shift(temp1)
+    vqrshrn.s32     d11, q15, #14             ; >> 14
+    vqrshrn.s32     d10, q6, #14              ; >> 14
+
+    ; temp2 = (step2[5] + step2[6]) * cospi_16_64
+    vadd.s32        q9, q9, q11
+    vadd.s32        q10, q10, q12
+
+    ; dct_const_round_shift(temp2)
+    vqrshrn.s32     d12, q9, #14              ; >> 14
+    vqrshrn.s32     d13, q10, #14             ; >> 14
+
+    ; stage 6
+    vadd.s16        q2, q8, q7               ; step2[0] = step1[0] + step1[7];
+    vadd.s16        q9, q8, q6                ; step2[1] = step1[1] + step1[6];
+    vadd.s16        q10, q8, q5               ; step2[2] = step1[2] + step1[5];
+    vadd.s16        q11, q8, q4               ; step2[3] = step1[3] + step1[4];
+    vsub.s16        q12, q8, q4               ; step2[4] = step1[3] - step1[4];
+    vsub.s16        q13, q8, q5               ; step2[5] = step1[2] - step1[5];
+    vsub.s16        q14, q8, q6               ; step2[6] = step1[1] - step1[6];
+    vsub.s16        q15, q8, q7               ; step2[7] = step1[0] - step1[7];
+
+    ; store the data
+    vst1.64         {d4}, [r1], r2
+    vst1.64         {d5}, [r1], r2
+    vst1.64         {d18}, [r1], r2
+    vst1.64         {d19}, [r1], r2
+    vst1.64         {d20}, [r1], r2
+    vst1.64         {d21}, [r1], r2
+    vst1.64         {d22}, [r1], r2
+    vst1.64         {d23}, [r1], r2
+    vst1.64         {d24}, [r1], r2
+    vst1.64         {d25}, [r1], r2
+    vst1.64         {d26}, [r1], r2
+    vst1.64         {d27}, [r1], r2
+    vst1.64         {d28}, [r1], r2
+    vst1.64         {d29}, [r1], r2
+    vst1.64         {d30}, [r1], r2
+    vst1.64         {d31}, [r1], r2
+
+    bx              lr
+    ENDP  ; |vp9_short_idct10_16x16_add_neon_pass1|
+
+;void vp9_short_idct10_16x16_add_neon_pass2(int16_t *src,
+;                                           int16_t *output,
+;                                           int16_t *pass1Output,
+;                                           int16_t skip_adding,
+;                                           uint8_t *dest,
+;                                           int dest_stride)
+;
+; r0  int16_t *src
+; r1  int16_t *output,
+; r2  int16_t *pass1Output,
+; r3  int16_t skip_adding,
+; r4  uint8_t *dest,
+; r5  int dest_stride)
+
+; idct16 stage1 - stage7 on all the elements loaded in q8-q15. The output
+; will be stored back into q8-q15 registers. This function will touch q0-q7
+; registers and use them as buffer during calculation.
+|vp9_short_idct10_16x16_add_neon_pass2| PROC
+    push            {r3-r9}
+
+    ; TODO(hkuang): Find a better way to load the elements.
+    ; load elements of 1, 3, 5, 7, 9, 11, 13, 15 into q8 - q15
+    vld2.s16        {q8,q9}, [r0]!
+    vld2.s16        {q9,q10}, [r0]!
+    vld2.s16        {q10,q11}, [r0]!
+    vld2.s16        {q11,q12}, [r0]!
+    vld2.s16        {q12,q13}, [r0]!
+    vld2.s16        {q13,q14}, [r0]!
+    vld2.s16        {q14,q15}, [r0]!
+    vld2.s16        {q0,q1}, [r0]!
+    vmov.s16        q15, q0;
+
+    ; generate 2*cospi_30_64 = 3212
+    mov             r3, #0xc00
+    add             r3, #0x8c
+
+    ; generate 2*cospi_2_64  = 32610
+    mov             r12, #0x7f00
+    add             r12, #0x62
+
+    ; transpose the input data
+    TRANSPOSE8X8
+
+    ; stage 3
+    vdup.16         q6, r3                    ; duplicate 2*cospi_30_64
+
+    ; dct_const_round_shift(step1[8] * cospi_30_64)
+    vqrdmulh.s16    q0, q8, q6
+
+    vdup.16         q6, r12                   ; duplicate 2*cospi_2_64
+
+    ; dct_const_round_shift(step1[8] * cospi_2_64)
+    vqrdmulh.s16    q7, q8, q6
+
+    ; preloading to avoid stall
+    ; generate 2*cospi_26_64 = 9512
+    mov             r12, #0x2500
+    add             r12, #0x28
+    rsb             r12, #0
+    vdup.16         q15, r12                  ; duplicate -2*cospi_26_64
+
+    ; generate 2*cospi_6_64 = 31358
+    mov             r3, #0x7a00
+    add             r3, #0x7e
+    vdup.16         q14, r3                   ; duplicate 2*cospi_6_64
+
+    ; dct_const_round_shift(- step1[12] * cospi_26_64)
+    vqrdmulh.s16    q3, q9, q15
+
+    ; dct_const_round_shift(step1[12] * cospi_6_64)
+    vqrdmulh.s16    q4, q9, q14
+
+    ; stage 4
+    ; generate cospi_24_64 = 6270
+    mov             r3, #0x1800
+    add             r3, #0x7e
+    vdup.16         d31, r3                   ; duplicate cospi_24_64
+
+    ; generate cospi_8_64 = 15137
+    mov             r12, #0x3b00
+    add             r12, #0x21
+    vdup.16         d30, r12                  ; duplicate cospi_8_64
+
+    ; step1[14] * cospi_24_64
+    vmull.s16       q12, d14, d31
+    vmull.s16       q5, d15, d31
+
+    ; temp1 = -step1[9] * cospi_8_64 + step1[14] * cospi_24_64
+    vmlsl.s16       q12, d0, d30
+    vmlsl.s16       q5, d1, d30
+
+    ; dct_const_round_shift(temp1)
+    vqrshrn.s32     d2, q12, #14              ; >> 14
+    vqrshrn.s32     d3, q5, #14               ; >> 14
+
+    ; step1[9] * cospi_24_64
+    vmull.s16       q2, d0, d31
+    vmull.s16       q11, d1, d31
+
+    ; temp2 = step1[9] * cospi_24_64 + step1[14] * cospi_8_64
+    vmlal.s16       q2, d14, d30
+    vmlal.s16       q11, d15, d30
+
+    ; dct_const_round_shift(temp2)
+    vqrshrn.s32     d12, q2, #14              ; >> 14
+    vqrshrn.s32     d13, q11, #14             ; >> 14
+
+    rsb              r12, #0
+    vdup.16         d30, r12                  ; duplicate -cospi_8_64
+
+    ; - step1[13] * cospi_8_64
+    vmull.s16       q10, d8, d30
+    vmull.s16       q13, d9, d30
+
+    ; temp1 = -step1[10] * cospi_24_64 - step1[13] * cospi_8_64
+    vmlsl.s16       q10, d6, d31
+    vmlsl.s16       q13, d7, d31
+
+    ; dct_const_round_shift(temp1)
+    vqrshrn.s32     d4, q10, #14              ; >> 14
+    vqrshrn.s32     d5, q13, #14              ; >> 14
+
+    ; -step1[10] * cospi_8_64
+    vmull.s16       q8, d6, d30
+    vmull.s16       q9, d7, d30
+
+    ; temp2 = -step1[10] * cospi_8_64 + step1[13] * cospi_24_64
+    vmlal.s16       q8, d8, d31
+    vmlal.s16       q9, d9, d31
+
+    ; dct_const_round_shift(temp2)
+    vqrshrn.s32     d10, q8, #14              ; >> 14
+    vqrshrn.s32     d11, q9, #14              ; >> 14
+
+    ; stage 5
+    vadd.s16        q8, q0, q3                ; step1[8] = step2[8]+step2[11];
+    vadd.s16        q9, q1, q2                ; step1[9] = step2[9]+step2[10];
+    vsub.s16        q10, q1, q2               ; step1[10] = step2[9]-step2[10];
+    vsub.s16        q11, q0, q3               ; step1[11] = step2[8]-step2[11];
+    vsub.s16        q12, q7, q4               ; step1[12] =-step2[12]+step2[15];
+    vsub.s16        q13, q6, q5               ; step1[13] =-step2[13]+step2[14];
+    vadd.s16        q14, q6, q5               ; step1[14] =step2[13]+step2[14];
+    vadd.s16        q15, q7, q4               ; step1[15] =step2[12]+step2[15];
+
+    ; stage 6.
+    ; generate cospi_16_64 = 11585
+    mov             r12, #0x2d00
+    add             r12, #0x41
+
+    vdup.16         d14, r12                  ; duplicate cospi_16_64
+
+    ; step1[13] * cospi_16_64
+    vmull.s16       q3, d26, d14
+    vmull.s16       q4, d27, d14
+
+    ; step1[10] * cospi_16_64
+    vmull.s16       q0, d20, d14
+    vmull.s16       q1, d21, d14
+
+    ; temp1 = (-step1[10] + step1[13]) * cospi_16_64
+    vsub.s32        q5, q3, q0
+    vsub.s32        q6, q4, q1
+
+    ; dct_const_round_shift(temp1)
+    vqrshrn.s32     d4, q5, #14               ; >> 14
+    vqrshrn.s32     d5, q6, #14               ; >> 14
+
+    ; temp2 = (step1[10] + step1[13]) * cospi_16_64
+    vadd.s32        q5, q3, q0
+    vadd.s32        q6, q4, q1
+
+    ; dct_const_round_shift(temp2)
+    vqrshrn.s32     d10, q5, #14              ; >> 14
+    vqrshrn.s32     d11, q6, #14              ; >> 14
+
+    ; step1[11] * cospi_16_64
+    vmull.s16       q0, d22, d14
+    vmull.s16       q1, d23, d14
+
+    ; step1[12] * cospi_16_64
+    vmull.s16       q13, d24, d14
+    vmull.s16       q6, d25, d14
+
+    ; temp1 = (-step1[11] + step1[12]) * cospi_16_64
+    vsub.s32        q10, q13, q0
+    vsub.s32        q4, q6, q1
+
+    ; dct_const_round_shift(input_dc * cospi_16_64)
+    vqrshrn.s32     d6, q10, #14              ; >> 14
+    vqrshrn.s32     d7, q4, #14               ; >> 14
+
+    ; temp2 = (step1[11] + step1[12]) * cospi_16_64
+    vadd.s32        q13, q13, q0
+    vadd.s32        q6, q6, q1
+
+    ; dct_const_round_shift((step1[11] + step1[12]) * cospi_16_64);
+    vqrshrn.s32     d8, q13, #14              ; >> 14
+    vqrshrn.s32     d9, q6, #14               ; >> 14
+
+    mov              r4, #16                  ; pass1Output stride
+    ldr              r3, [sp]                 ; load skip_adding
+
+    ; stage 7
+    ; load the data in pass1
+    mov              r5, #24
+    mov              r3, #8
+
+    vld1.s16        {q0}, [r2], r4            ; load data step2[0]
+    vld1.s16        {q1}, [r2], r4            ; load data step2[1]
+    vadd.s16        q12, q0, q15              ; step2[0] + step2[15]
+    vadd.s16        q13, q1, q14              ; step2[1] + step2[14]
+    vld1.s16        {q10}, [r2], r4           ; load data step2[2]
+    vld1.s16        {q11}, [r2], r4           ; load data step2[3]
+    vst1.64         {d24}, [r1], r3           ; store output[0]
+    vst1.64         {d25}, [r1], r5
+    vst1.64         {d26}, [r1], r3           ; store output[1]
+    vst1.64         {d27}, [r1], r5
+    vadd.s16        q12, q10, q5              ; step2[2] + step2[13]
+    vadd.s16        q13, q11, q4              ; step2[3] + step2[12]
+    vsub.s16        q14, q1, q14              ; step2[1] - step2[14]
+    vsub.s16        q15, q0, q15              ; step2[0] - step2[15]
+    vst1.64         {d24}, [r1], r3           ; store output[2]
+    vst1.64         {d25}, [r1], r5
+    vst1.64         {d26}, [r1], r3           ; store output[3]
+    vst1.64         {d27}, [r1], r5
+    vsub.s16        q4, q11, q4               ; step2[3] - step2[12]
+    vsub.s16        q5, q10, q5               ; step2[2] - step2[13]
+    vld1.s16        {q0}, [r2], r4            ; load data step2[4]
+    vld1.s16        {q1}, [r2], r4            ; load data step2[5]
+    vadd.s16        q12, q0, q3               ; step2[4] + step2[11]
+    vadd.s16        q13, q1, q2               ; step2[5] + step2[10]
+    vld1.s16        {q10}, [r2], r4           ; load data step2[6]
+    vld1.s16        {q11}, [r2], r4           ; load data step2[7]
+    vst1.64         {d24}, [r1], r3           ; store output[4]
+    vst1.64         {d25}, [r1], r5
+    vst1.64         {d26}, [r1], r3           ; store output[5]
+    vst1.64         {d27}, [r1], r5
+    vadd.s16        q12, q10, q9              ; step2[6] + step2[9]
+    vadd.s16        q13, q11, q8              ; step2[7] + step2[8]
+    vsub.s16        q2, q1, q2                ; step2[5] - step2[10]
+    vsub.s16        q3, q0, q3                ; step2[4] - step2[11]
+    vsub.s16        q8, q11, q8               ; step2[7] - step2[8]
+    vsub.s16        q9, q10, q9               ; step2[6] - step2[9]
+    vst1.64         {d24}, [r1], r3           ; store output[6]
+    vst1.64         {d25}, [r1], r5
+    vst1.64         {d26}, [r1], r3           ; store output[7]
+    vst1.64         {d27}, [r1], r5
+
+    ; store the data  output 8,9,10,11,12,13,14,15
+    vst1.64         {d16}, [r1], r3
+    vst1.64         {d17}, [r1], r5
+    vst1.64         {d18}, [r1], r3
+    vst1.64         {d19}, [r1], r5
+    vst1.64         {d4}, [r1], r3
+    vst1.64         {d5}, [r1], r5
+    vst1.64         {d6}, [r1], r3
+    vst1.64         {d7}, [r1], r5
+    vst1.64         {d8}, [r1], r3
+    vst1.64         {d9}, [r1], r5
+    vst1.64         {d10}, [r1], r3
+    vst1.64         {d11}, [r1], r5
+    vst1.64         {d28}, [r1], r3
+    vst1.64         {d29}, [r1], r5
+    vst1.64         {d30}, [r1], r3
+    vst1.64         {d31}, [r1], r5
+end_idct10_16x16_pass2
+    pop             {r3-r9}
+    bx              lr
+    ENDP  ; |vp9_short_idct10_16x16_add_neon_pass2|
 ;void |save_registers|()
 |save_registers| PROC
     vpush           {d8-d15}
     bx              lr
     ENDP  ; |save_registers|
-
 ;void |restore_registers|()
 |restore_registers| PROC
     vpop           {d8-d15}
diff --git a/vp9/common/vp9_rtcd_defs.sh b/vp9/common/vp9_rtcd_defs.sh
index f13b7b18c2..d075443edc 100644
--- a/vp9/common/vp9_rtcd_defs.sh
+++ b/vp9/common/vp9_rtcd_defs.sh
@@ -316,7 +316,7 @@ prototype void vp9_short_idct16x16_add "int16_t *input, uint8_t *dest, int dest_
 specialize vp9_short_idct16x16_add sse2 neon
 
 prototype void vp9_short_idct10_16x16_add "int16_t *input, uint8_t *dest, int dest_stride"
-specialize vp9_short_idct10_16x16_add sse2
+specialize vp9_short_idct10_16x16_add sse2 neon
 
 prototype void vp9_short_idct32x32_add "int16_t *input, uint8_t *dest, int dest_stride"
 specialize vp9_short_idct32x32_add sse2
-- 
GitLab