shithub: libvpx

Download patch

ref: 4205d79273b3ae00f38c870d7c6939f5db615e2b
parent: 13eed79c776477f0bc3ed5e70c2fce69165cb77e
parent: 4082bf9d7c607c62a1ab8b3573f695de2cd39dd6
author: hkuang <[email protected]>
date: Thu Aug 22 11:57:28 EDT 2013

Merge "Add neon optimize vp9_short_idct10_16x16_add."

--- a/vp9/common/arm/neon/vp9_idct16x16_neon.c
+++ b/vp9/common/arm/neon/vp9_idct16x16_neon.c
@@ -20,6 +20,15 @@
                                                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();
 
@@ -61,6 +70,67 @@
                                      0,
                                      dest,
                                      dest_stride);
+
+  /* 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;
+}
+
+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
--- 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,11 +497,11 @@
     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
 
@@ -506,7 +508,6 @@
     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,20 +726,20 @@
     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]
@@ -752,32 +746,32 @@
     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 @@
     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}
--- a/vp9/common/vp9_rtcd_defs.sh
+++ b/vp9/common/vp9_rtcd_defs.sh
@@ -316,7 +316,7 @@
 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