shithub: openh264

Download patch

ref: c011890764bebeb237674e78c44155711284bb76
parent: 811c647c0ec3553ff8fa16cf933146e59aa4277e
author: Martin Storsjö <martin@martin.st>
date: Sun Mar 9 08:53:38 EDT 2014

Push clobbered neon registers on the stack

According to the calling convention, the registers q4-q7 should be
preserved by functions. The caller (generated by the compiler) could
be using those registers anywhere for any intermediate data.

Functions that use more than 12 of the qX registers must push
the clobbered registers on the stack in order to be able to restore them
afterwards.

In functions that don't use all 16 registers, but clobber some of
the callee saved registers q4-q7, one or more of them are remapped
to reduce the number of registers that have to be saved/restored.

This incurs a very small (around 0.5%) slowdown in the decoder and
encoder.

--- a/codec/common/deblocking_neon.S
+++ b/codec/common/deblocking_neon.S
@@ -277,6 +277,7 @@
 #endif
 
 WELS_ASM_FUNC_BEGIN DeblockLumaLt4V_neon
+    vpush	{q4-q7}
     vdup.u8	q11, r2
     vdup.u8	q9, r3
 
@@ -290,7 +291,7 @@
     vld1.u8	{q5}, [r0]
     sub			r2, r2, r1
 
-    ldr			r3, [sp, #0]
+    ldr			r3, [sp, #64]
     vld1.s8	{d31}, [r3]
     vdup.s8	d28, d31[0]
     vdup.s8	d30, d31[1]
@@ -332,10 +333,12 @@
     vst1.u8	{q3}, [r2]	, r1
     vst1.u8	{q7}, [r2]
 
+    vpop	{q4-q7}
 WELS_ASM_FUNC_END
 
 
 WELS_ASM_FUNC_BEGIN DeblockLumaEq4V_neon
+    vpush	{q4-q7}
 
     vdup.u8	q5, r2
     vdup.u8	q4, r3
@@ -393,10 +396,12 @@
     DIFF_LUMA_EQ4_MASK	q3,  q14, q0, q4
     vst1.u8	{q4}, [r3], r1
 
+    vpop	{q4-q7}
 WELS_ASM_FUNC_END
 
 
     WELS_ASM_FUNC_BEGIN DeblockLumaLt4H_neon
+    vpush	{q4-q7}
 
     vdup.u8	q11, r2
     vdup.u8	q9, r3
@@ -429,7 +434,7 @@
 
     sub			r0, r0, r1, lsl #4
 
-    ldr			r3, [sp, #0]
+    ldr			r3, [sp, #64]
     vld1.s8	{d31}, [r3]
     vdup.s8	d28, d31[0]
     vdup.s8	d30, d31[1]
@@ -488,10 +493,12 @@
     STORE_LUMA_DATA_4		d6, d7, d8, d9, 4, 5
     STORE_LUMA_DATA_4		d6, d7, d8, d9, 6, 7
 
+    vpop	{q4-q7}
 WELS_ASM_FUNC_END
 
 
 WELS_ASM_FUNC_BEGIN DeblockLumaEq4H_neon
+    vpush	{q4-q7}
     vdup.u8	q5, r2
     vdup.u8	q4, r3
 
@@ -591,6 +598,7 @@
     STORE_LUMA_DATA_3		d7,d8,d9,d13,d14,d15,6
     STORE_LUMA_DATA_3		d7,d8,d9,d13,d14,d15,7
 
+    vpop	{q4-q7}
 WELS_ASM_FUNC_END
 
 
@@ -647,9 +655,10 @@
 
 
     WELS_ASM_FUNC_BEGIN DeblockChromaEq4V_neon
+    vpush	{q4-q5}
 
     vdup.u8	q11, r3
-    ldr			r3, [sp, #0]
+    ldr			r3, [sp, #32]
 
     sub			r0, r0, r2	, lsl #1
     sub			r1, r1, r2, lsl #1
@@ -670,10 +679,10 @@
 
     vmov			q11, q10
 
-    DIFF_CHROMA_EQ4_P0Q0		d0, d2, d4, d6, q4, q5, q6, d14, d0		// Cb::p0' q0'
-    DIFF_CHROMA_EQ4_P0Q0		d1, d3, d5, d7, q12, q13, q14, d15, d1	// Cr::p0' q0'
+    DIFF_CHROMA_EQ4_P0Q0		d0, d2, d4, d6, q4, q5, q8, d30, d0		// Cb::p0' q0'
+    DIFF_CHROMA_EQ4_P0Q0		d1, d3, d5, d7, q12, q13, q14, d31, d1	// Cr::p0' q0'
 
-    vbsl.u8	q10, q7, q1
+    vbsl.u8	q10, q15, q1
     vst1.u8	{d20}, [r0], r2
     vst1.u8	{d21}, [r1], r2
 
@@ -681,6 +690,7 @@
     vst1.u8	{d22}, [r0]
     vst1.u8	{d23}, [r1]
 
+    vpop	{q4-q5}
 WELS_ASM_FUNC_END
 
 WELS_ASM_FUNC_BEGIN DeblockChromaLt4H_neon
@@ -747,8 +757,9 @@
 WELS_ASM_FUNC_END
 
 WELS_ASM_FUNC_BEGIN DeblockChromaEq4H_neon
+    vpush	{q4-q5}
     vdup.u8	q11, r3
-    ldr			r3, [sp, #0]
+    ldr			r3, [sp, #32]
 
     sub			r0, r0, #2
     sub			r1, r1, #2
@@ -792,6 +803,7 @@
     STORE_CHROMA_DATA_4	d0, d1, d2, d3, d4, d5, d6, d7, 6
     STORE_CHROMA_DATA_4	d0, d1, d2, d3, d4, d5, d6, d7, 7
 
+    vpop	{q4-q5}
 WELS_ASM_FUNC_END
 
 
--- a/codec/common/mc_neon.S
+++ b/codec/common/mc_neon.S
@@ -1140,7 +1140,8 @@
 
 WELS_ASM_FUNC_BEGIN McHorVer22WidthEq16_neon
 	push		{r4}
-	ldr			r4, [sp, #4]
+	vpush		{q4-q7}
+	ldr			r4, [sp, #68]
 
 	sub			r0, #2					//src[-2]
 	sub			r0, r0, r1, lsl #1		//src[-2*src_stride-2]
@@ -1246,6 +1247,7 @@
 	sub		r4, #4
 	cmp		r4, #0
 	bne		w16_hv_mc_luma_loop
+	vpop		{q4-q7}
 	pop		{r4}
 WELS_ASM_FUNC_END
 
@@ -1252,7 +1254,8 @@
 
 WELS_ASM_FUNC_BEGIN McHorVer22WidthEq8_neon
 	push		{r4}
-	ldr			r4, [sp, #4]
+	vpush		{q4}
+	ldr			r4, [sp, #20]
 
 	sub			r0, #2				//src[-2]
 	sub			r0, r0, r1, lsl #1	//src[-2*src_stride-2]
@@ -1275,59 +1278,60 @@
 
 w8_hv_mc_luma_loop:
 
-	vld1.u8	{q5}, [r0], r1	//use 13(8+5), =src[3]
+	vld1.u8	{q8}, [r0], r1	//use 13(8+5), =src[3]
 	//the 1st row
 	pld			[r0]
-	// vertical filtered into q6/q7
-	FILTER_6TAG_8BITS_TO_16BITS 	d0, d2, d4, d6, d8, d10, q6, q14, q15	// 8 avail
-	FILTER_6TAG_8BITS_TO_16BITS 	d1, d3, d5, d7, d9, d11, q7, q14, q15	// 5 avail
+	// vertical filtered into q9/q10
+	FILTER_6TAG_8BITS_TO_16BITS 	d0, d2, d4, d6, d8, d16, q9, q14, q15	// 8 avail
+	FILTER_6TAG_8BITS_TO_16BITS 	d1, d3, d5, d7, d9, d17, q10, q14, q15	// 5 avail
 	// horizon filtered
-	UNPACK_2_16BITS_TO_ABC	q6, q7, q11, q12, q13
-	FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d12	//output to q6[0]
-	vst1.u8	d12, [r2], r3			//write 8Byte
+	UNPACK_2_16BITS_TO_ABC	q9, q10, q11, q12, q13
+	FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18	//output to q9[0]
+	vst1.u8	d18, [r2], r3			//write 8Byte
 
 	vld1.u8	{q0}, [r0], r1		//read 2nd row
 	//the 2nd row
 	pld			[r0]
-	// vertical filtered into q6/q7
-	FILTER_6TAG_8BITS_TO_16BITS 	d2, d4, d6, d8, d10, d0, q6, q14, q15	// 8 avail
-	FILTER_6TAG_8BITS_TO_16BITS 	d3, d5, d7, d9, d11, d1, q7, q14, q15	// 5 avail
+	// vertical filtered into q9/q10
+	FILTER_6TAG_8BITS_TO_16BITS 	d2, d4, d6, d8, d16, d0, q9, q14, q15	// 8 avail
+	FILTER_6TAG_8BITS_TO_16BITS 	d3, d5, d7, d9, d17, d1, q10, q14, q15	// 5 avail
 	// horizon filtered
-	UNPACK_2_16BITS_TO_ABC	q6, q7, q11, q12, q13
-	FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d12	//output to q6[0]
-	vst1.u8	d12, [r2], r3		//write 8Byte
+	UNPACK_2_16BITS_TO_ABC	q9, q10, q11, q12, q13
+	FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18	//output to q9[0]
+	vst1.u8	d18, [r2], r3		//write 8Byte
 
 	vld1.u8	{q1}, [r0], r1		//read 3rd row
 	//the 3rd row
 	pld			[r0]
-	// vertical filtered into q6/q7
-	FILTER_6TAG_8BITS_TO_16BITS 	d4, d6, d8, d10, d0, d2, q6, q14, q15	// 8 avail
-	FILTER_6TAG_8BITS_TO_16BITS 	d5, d7, d9, d11, d1, d3, q7, q14, q15	// 5 avail
+	// vertical filtered into q9/q10
+	FILTER_6TAG_8BITS_TO_16BITS 	d4, d6, d8, d16, d0, d2, q9, q14, q15	// 8 avail
+	FILTER_6TAG_8BITS_TO_16BITS 	d5, d7, d9, d17, d1, d3, q10, q14, q15	// 5 avail
 	// horizon filtered
-	UNPACK_2_16BITS_TO_ABC	q6, q7, q11, q12, q13
-	FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d12	//output to q6[0]
-	vst1.u8	d12, [r2], r3			//write 8Byte
+	UNPACK_2_16BITS_TO_ABC	q9, q10, q11, q12, q13
+	FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18	//output to q9[0]
+	vst1.u8	d18, [r2], r3			//write 8Byte
 
 	vld1.u8	{q2}, [r0], r1		//read 4th row
 	//the 4th row
 	pld			[r0]
-	// vertical filtered into q6/q7
-	FILTER_6TAG_8BITS_TO_16BITS 	d6, d8, d10, d0, d2, d4, q6, q14, q15	// 8 avail
-	FILTER_6TAG_8BITS_TO_16BITS 	d7, d9, d11, d1, d3, d5, q7, q14, q15	// 5 avail
+	// vertical filtered into q9/q10
+	FILTER_6TAG_8BITS_TO_16BITS 	d6, d8, d16, d0, d2, d4, q9, q14, q15	// 8 avail
+	FILTER_6TAG_8BITS_TO_16BITS 	d7, d9, d17, d1, d3, d5, q10, q14, q15	// 5 avail
 	// horizon filtered
-	UNPACK_2_16BITS_TO_ABC	q6, q7, q11, q12, q13
-	FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d12	//output to q6[0]
-	vst1.u8	d12, [r2], r3			//write 8Byte
+	UNPACK_2_16BITS_TO_ABC	q9, q10, q11, q12, q13
+	FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18	//output to q9[0]
+	vst1.u8	d18, [r2], r3			//write 8Byte
 
 	//q4~q5, q0~q2, --> q0~q4
 	vswp	q0, q4
 	vswp	q2, q4
 	vmov	q3, q1
-	vmov	q1, q5
+	vmov	q1, q8
 
 	sub		r4, #4
 	cmp		r4, #0
 	bne		w8_hv_mc_luma_loop
+	vpop		{q4}
 	pop		{r4}
 WELS_ASM_FUNC_END
 
@@ -1334,7 +1338,8 @@
 
 WELS_ASM_FUNC_BEGIN McHorVer22WidthEq4_neon
 	push		{r4 ,r5, r6}
-	ldr			r6, [sp, #12]
+	vpush		{q4-q7}
+	ldr			r6, [sp, #76]
 
 	sub			r0, #2				//src[-2]
 	sub			r0, r0, r1, lsl #1	//src[-2*src_stride-2]
@@ -1417,6 +1422,7 @@
 	cmp		r6, #0
 	bne		w4_hv_mc_luma_loop
 
+	vpop		{q4-q7}
 	pop		{r4, r5, r6}
 WELS_ASM_FUNC_END
 
@@ -1889,7 +1895,8 @@
 
 WELS_ASM_FUNC_BEGIN McHorVer22Width17_neon
 	push		{r4}
-	ldr			r4, [sp, #4]
+	vpush		{q4-q7}
+	ldr			r4, [sp, #68]
 
 	sub			r0, #2					//src[-2]
 	sub			r0, r0, r1, lsl #1		//src[-2*src_stride-2]
@@ -2016,6 +2023,7 @@
 	UNPACK_1_IN_8x16BITS_TO_8BITS	d2, d22, d23, q11 //output to d2[0]
 	vst1.u8	{d2[0]}, [r2], r3		//write 16th Byte
 
+	vpop		{q4-q7}
 	pop		{r4}
 WELS_ASM_FUNC_END
 
@@ -2022,7 +2030,8 @@
 
 WELS_ASM_FUNC_BEGIN McHorVer22Width9_neon
 	push		{r4}
-	ldr			r4, [sp, #4]
+	vpush		{q4}
+	ldr			r4, [sp, #20]
 
 	sub			r0, #2				//src[-2]
 	sub			r0, r0, r1, lsl #1	//src[-2*src_stride-2]
@@ -2046,78 +2055,79 @@
 
 w9_hv_mc_luma_loop:
 
-	vld1.u8	{q5}, [r0], r1	//use 14(9+5), =src[3]
+	vld1.u8	{q8}, [r0], r1	//use 14(9+5), =src[3]
 	//the 1st row
 	pld			[r0]
-	// vertical filtered into q6/q7
-	FILTER_6TAG_8BITS_TO_16BITS 	d0, d2, d4, d6, d8, d10, q6, q14, q15	// 8 avail
-	FILTER_6TAG_8BITS_TO_16BITS 	d1, d3, d5, d7, d9, d11, q7, q14, q15	// 6 avail
+	// vertical filtered into q9/q10
+	FILTER_6TAG_8BITS_TO_16BITS 	d0, d2, d4, d6, d8, d16, q9, q14, q15	// 8 avail
+	FILTER_6TAG_8BITS_TO_16BITS 	d1, d3, d5, d7, d9, d17, q10, q14, q15	// 6 avail
 	// horizon filtered
-	UNPACK_2_16BITS_TO_ABC	q6, q7, q11, q12, q13
-	FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d12	//output to q6[0]
-	vst1.u8	d12, [r2]!				//write 8Byte
-	UNPACK_1_IN_8x16BITS_TO_8BITS	d13, d14, d15, q7 //output to d13[0]
-	vst1.u8	{d13[0]}, [r2], r3	//write 8th Byte
+	UNPACK_2_16BITS_TO_ABC	q9, q10, q11, q12, q13
+	FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18	//output to q9[0]
+	vst1.u8	d18, [r2]!				//write 8Byte
+	UNPACK_1_IN_8x16BITS_TO_8BITS	d19, d20, d21, q10 //output to d19[0]
+	vst1.u8	{d19[0]}, [r2], r3	//write 8th Byte
 
 	vld1.u8	{q0}, [r0], r1		//read 2nd row
 	//the 2nd row
 	pld			[r0]
-	// vertical filtered into q6/q7
-	FILTER_6TAG_8BITS_TO_16BITS 	d2, d4, d6, d8, d10, d0, q6, q14, q15	// 8 avail
-	FILTER_6TAG_8BITS_TO_16BITS 	d3, d5, d7, d9, d11, d1, q7, q14, q15	// 6 avail
+	// vertical filtered into q9/q10
+	FILTER_6TAG_8BITS_TO_16BITS 	d2, d4, d6, d8, d16, d0, q9, q14, q15	// 8 avail
+	FILTER_6TAG_8BITS_TO_16BITS 	d3, d5, d7, d9, d17, d1, q10, q14, q15	// 6 avail
 	// horizon filtered
-	UNPACK_2_16BITS_TO_ABC	q6, q7, q11, q12, q13
-	FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d12	//output to q6[0]
-	vst1.u8	d12, [r2]!				//write 8Byte
-	UNPACK_1_IN_8x16BITS_TO_8BITS	d13, d14, d15, q7 //output to d13[0]
-	vst1.u8	{d13[0]}, [r2], r3	//write 8th Byte
+	UNPACK_2_16BITS_TO_ABC	q9, q10, q11, q12, q13
+	FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18	//output to q9[0]
+	vst1.u8	d18, [r2]!				//write 8Byte
+	UNPACK_1_IN_8x16BITS_TO_8BITS	d19, d20, d21, q10 //output to d19[0]
+	vst1.u8	{d19[0]}, [r2], r3	//write 8th Byte
 
 	vld1.u8	{q1}, [r0], r1		//read 3rd row
 	//the 3rd row
 	pld			[r0]
-	// vertical filtered into q6/q7
-	FILTER_6TAG_8BITS_TO_16BITS 	d4, d6, d8, d10, d0, d2, q6, q14, q15	// 8 avail
-	FILTER_6TAG_8BITS_TO_16BITS 	d5, d7, d9, d11, d1, d3, q7, q14, q15	// 6 avail
+	// vertical filtered into q9/q10
+	FILTER_6TAG_8BITS_TO_16BITS 	d4, d6, d8, d16, d0, d2, q9, q14, q15	// 8 avail
+	FILTER_6TAG_8BITS_TO_16BITS 	d5, d7, d9, d17, d1, d3, q10, q14, q15	// 6 avail
 	// horizon filtered
-	UNPACK_2_16BITS_TO_ABC	q6, q7, q11, q12, q13
-	FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d12	//output to q6[0]
-	vst1.u8	d12, [r2]!				//write 8Byte
-	UNPACK_1_IN_8x16BITS_TO_8BITS	d13, d14, d15, q7 //output to d13[0]
-	vst1.u8	{d13[0]}, [r2], r3	//write 8th Byte
+	UNPACK_2_16BITS_TO_ABC	q9, q10, q11, q12, q13
+	FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18	//output to q9[0]
+	vst1.u8	d18, [r2]!				//write 8Byte
+	UNPACK_1_IN_8x16BITS_TO_8BITS	d19, d20, d21, q10 //output to d19[0]
+	vst1.u8	{d19[0]}, [r2], r3	//write 8th Byte
 
 	vld1.u8	{q2}, [r0], r1		//read 4th row
 	//the 4th row
 	pld			[r0]
-	// vertical filtered into q6/q7
-	FILTER_6TAG_8BITS_TO_16BITS 	d6, d8, d10, d0, d2, d4, q6, q14, q15	// 8 avail
-	FILTER_6TAG_8BITS_TO_16BITS 	d7, d9, d11, d1, d3, d5, q7, q14, q15	// 6 avail
+	// vertical filtered into q9/q10
+	FILTER_6TAG_8BITS_TO_16BITS 	d6, d8, d16, d0, d2, d4, q9, q14, q15	// 8 avail
+	FILTER_6TAG_8BITS_TO_16BITS 	d7, d9, d17, d1, d3, d5, q10, q14, q15	// 6 avail
 	// horizon filtered
-	UNPACK_2_16BITS_TO_ABC	q6, q7, q11, q12, q13
-	FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d12	//output to q6[0]
-	vst1.u8	d12, [r2]!			//write 8Byte
-	UNPACK_1_IN_8x16BITS_TO_8BITS	d13, d14, d15, q7 //output to d13[0]
-	vst1.u8	{d13[0]}, [r2], r3	//write 8th Byte
+	UNPACK_2_16BITS_TO_ABC	q9, q10, q11, q12, q13
+	FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18	//output to q9[0]
+	vst1.u8	d18, [r2]!			//write 8Byte
+	UNPACK_1_IN_8x16BITS_TO_8BITS	d19, d20, d21, q10 //output to d19[0]
+	vst1.u8	{d19[0]}, [r2], r3	//write 8th Byte
 
-	//q4~q5, q0~q2, --> q0~q4
+	//q4~q8, q0~q2, --> q0~q4
 	vswp	q0, q4
 	vswp	q2, q4
 	vmov	q3, q1
-	vmov	q1, q5
+	vmov	q1, q8
 
 	sub		r4, #4
 	cmp		r4, #1
 	bne		w9_hv_mc_luma_loop
 	//the last row
-	vld1.u8	{q5}, [r0], r1	//use 14(9+5), =src[3]
-	// vertical filtered into q6/q7
-	FILTER_6TAG_8BITS_TO_16BITS 	d0, d2, d4, d6, d8, d10, q6, q14, q15	// 8 avail
-	FILTER_6TAG_8BITS_TO_16BITS 	d1, d3, d5, d7, d9, d11, q7, q14, q15	// 6 avail
+	vld1.u8	{q8}, [r0], r1	//use 14(9+5), =src[3]
+	// vertical filtered into q9/q10
+	FILTER_6TAG_8BITS_TO_16BITS 	d0, d2, d4, d6, d8, d16, q9, q14, q15	// 8 avail
+	FILTER_6TAG_8BITS_TO_16BITS 	d1, d3, d5, d7, d9, d17, q10, q14, q15	// 6 avail
 	// horizon filtered
-	UNPACK_2_16BITS_TO_ABC	q6, q7, q11, q12, q13
-	FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d12	//output to q6[0]
-	vst1.u8	d12, [r2]!				//write 8Byte
-	UNPACK_1_IN_8x16BITS_TO_8BITS	d13, d14, d15, q7 //output to d13[0]
-	vst1.u8	{d13[0]}, [r2], r3	//write 8th Byte
+	UNPACK_2_16BITS_TO_ABC	q9, q10, q11, q12, q13
+	FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18	//output to q9[0]
+	vst1.u8	d18, [r2]!				//write 8Byte
+	UNPACK_1_IN_8x16BITS_TO_8BITS	d19, d20, d21, q10 //output to d19[0]
+	vst1.u8	{d19[0]}, [r2], r3	//write 8th Byte
+	vpop		{q4}
 	pop		{r4}
 WELS_ASM_FUNC_END
 
--- a/codec/encoder/core/arm/intra_pred_sad_3_opt_neon.S
+++ b/codec/encoder/core/arm/intra_pred_sad_3_opt_neon.S
@@ -535,10 +535,11 @@
 
 WELS_ASM_FUNC_BEGIN WelsIntra8x8Combined3Satd_neon
     stmdb sp!, {r4-r7, lr}
+    vpush {q4-q7}
 
 	//Get the data from stack
-	ldr r4, [sp, #32] //p_dec_cr
-	ldr r5, [sp, #36] //p_enc_cr
+	ldr r4, [sp, #96] //p_dec_cr
+	ldr r5, [sp, #100] //p_enc_cr
 
 	//Get the top line data to 'd29(cb), d31(cr)'(16 bytes)
 	sub  r6, r0, r1
@@ -637,8 +638,8 @@
     HDM_TRANSFORM_4X4_L0 d7, d9, d25, d21, d13, d11, d10, d28, d30
 
 	//Get the data from stack
-	ldr r5, [sp, #20] //the addr of Best_mode
-	ldr r6, [sp, #24] //the value of i_lambda
+	ldr r5, [sp, #84] //the addr of Best_mode
+	ldr r6, [sp, #88] //the value of i_lambda
 
 	vrshr.u16  d11, #1
 	vpaddl.u16 d11, d11
@@ -668,6 +669,7 @@
     str r6, [r5]
     mov r0, lr
 
+	vpop {q4-q7}
 	ldmia sp!, {r4-r7, lr}
 WELS_ASM_FUNC_END
 
--- a/codec/encoder/core/arm/pixel_neon.S
+++ b/codec/encoder/core/arm/pixel_neon.S
@@ -38,86 +38,86 @@
     vld1.64     {q0}, [r0,:128], r1
     vld1.64     {q1}, [r2], r3
 
-    vsubl.u8    q4,  d0,  d2
+    vsubl.u8    q8,  d0,  d2
     vld1.64     {q2}, [r0,:128], r1
 
-    vsubl.u8    q6, d1,  d3
+    vsubl.u8    q10, d1,  d3
     vld1.64     {q3}, [r2], r3
 
-    vsubl.u8    q5,  d4,  d6
+    vsubl.u8    q9,  d4,  d6
     vld1.64     {q0}, [r0,:128], r1
 
-    vsubl.u8    q7, d5,  d7
+    vsubl.u8    q11, d5,  d7
     vld1.64     {q1}, [r2], r3
 
-    vsubl.u8    q8, d0,  d2
+    vsubl.u8    q12, d0,  d2
     vld1.64     {q2}, [r0,:128], r1
 
-    vsubl.u8    q10, d1,  d3
-    vadd.s16    q0,  q4,  q5
+    vsubl.u8    q14, d1,  d3
+    vadd.s16    q0,  q8,  q9
 
     vld1.64     {q3}, [r2], r3
-    vsub.s16    q1,  q4,  q5
+    vsub.s16    q1,  q8,  q9
 
-    vsubl.u8    q9, d4,  d6
-    vsubl.u8    q11, d5,  d7
+    vsubl.u8    q13, d4,  d6
+    vsubl.u8    q15, d5,  d7
 
-    vadd.s16    q2, q8, q9
-    vsub.s16    q3, q8, q9
+    vadd.s16    q2, q12, q13
+    vsub.s16    q3, q12, q13
 
-    vadd.s16    q4, q6, q7
-    vsub.s16	q5, q6, q7
+    vadd.s16    q8, q10, q11
+    vsub.s16	q9, q10, q11
 
-    vadd.s16    q6, q10, q11
-    vsub.s16	q7, q10, q11
+    vadd.s16    q10, q14, q15
+    vsub.s16	q11, q14, q15
 
-    vadd.s16    q8, q0, q2
-    vsub.s16    q10, q0, q2
+    vadd.s16    q12, q0, q2
+    vsub.s16    q14, q0, q2
 
-    vadd.s16    q9, q4, q6
-    vsub.s16    q11, q4, q6
+    vadd.s16    q13, q8, q10
+    vsub.s16    q15, q8, q10
 
     vsub.s16    q0, q1, q3
     vadd.s16    q2, q1, q3
 
-    vsub.s16    q1, q5, q7
-    vadd.s16    q3, q5, q7
+    vsub.s16    q1, q9, q11
+    vadd.s16    q3, q9, q11
 
-    vtrn.16 q8, q10
-    vtrn.16 q9, q11
+    vtrn.16 q12, q14
+    vtrn.16 q13, q15
 
-    vadd.s16 q4, q8, q10
-    vabd.s16 q6, q8, q10
+    vadd.s16 q8, q12, q14
+    vabd.s16 q10, q12, q14
 
-    vadd.s16 q5, q9, q11
-    vabd.s16 q7, q9, q11
+    vadd.s16 q9, q13, q15
+    vabd.s16 q11, q13, q15
 
-    vabs.s16 q4, q4
-    vabs.s16 q5, q5
+    vabs.s16 q8, q8
+    vabs.s16 q9, q9
 
     vtrn.16 q0, q2
     vtrn.16 q1, q3
 
-    vadd.s16 q8, q0, q2
-    vabd.s16 q10, q0, q2
+    vadd.s16 q12, q0, q2
+    vabd.s16 q14, q0, q2
 
-    vadd.s16 q9, q1, q3
-    vabd.s16 q11, q1, q3
+    vadd.s16 q13, q1, q3
+    vabd.s16 q15, q1, q3
 
-    vabs.s16 q8, q8
-    vabs.s16 q9, q9
+    vabs.s16 q12, q12
+    vabs.s16 q13, q13
 
-    vtrn.32 q4, q6
-    vtrn.32 q5, q7
-
     vtrn.32 q8, q10
     vtrn.32 q9, q11
 
-    vmax.s16    q0, q4,  q6
-    vmax.s16    q1, q5,  q7
-    vmax.s16    q2, q8,  q10
-    vmax.s16    q3, q9,  q11
+    vtrn.32 q12, q14
+    vtrn.32 q13, q15
 
+    vmax.s16    q0, q8,  q10
+    vmax.s16    q1, q9,  q11
+    vmax.s16    q2, q12,  q14
+    vmax.s16    q3, q13,  q15
+
     vadd.u16 q0, q0, q1
     vadd.u16 q2, q2, q3
 .endm
@@ -128,49 +128,49 @@
     vld1.64     {d1}, [r2], r3
 
     vld1.64     {d2}, [r0,:64], r1
-    vsubl.u8    q4, d0, d1
+    vsubl.u8    q8, d0, d1
 
     vld1.64     {d3}, [r2], r3
-    vsubl.u8    q5, d2, d3
+    vsubl.u8    q9, d2, d3
 
     vld1.64     {d4}, [r0,:64], r1
     vld1.64     {d5}, [r2], r3
 
-    vadd.s16    q8, q4, q5
-    vsubl.u8    q6, d4, d5
+    vadd.s16    q12, q8, q9
+    vsubl.u8    q10, d4, d5
 
     vld1.64     {d6}, [r0,:64], r1
     vld1.64     {d7}, [r2], r3
 
-    vsubl.u8    q7, d6,  d7
-    vsub.s16    q9, q4, q5
+    vsubl.u8    q11, d6,  d7
+    vsub.s16    q13, q8, q9
 
-    vadd.s16    q10, q6, q7
-    vsub.s16    q11, q6, q7
+    vadd.s16    q14, q10, q11
+    vsub.s16    q15, q10, q11
 
-    vadd.s16    q0, q8, q10
-    vsub.s16    q1, q8, q10
+    vadd.s16    q0, q12, q14
+    vsub.s16    q1, q12, q14
 
-    vsub.s16    q2, q9, q11
-    vadd.s16    q3, q9, q11
+    vsub.s16    q2, q13, q15
+    vadd.s16    q3, q13, q15
 
     vtrn.16     q0, q1
     vtrn.16     q2, q3
 
-    vadd.s16    q4, q0, q1
-    vabd.s16    q5, q0, q1
+    vadd.s16    q8, q0, q1
+    vabd.s16    q9, q0, q1
 
-    vabs.s16    q4, q4
-    vadd.s16    q6, q2, q3
+    vabs.s16    q8, q8
+    vadd.s16    q10, q2, q3
 
-    vabd.s16    q7, q2, q3
-    vabs.s16    q6, q6
+    vabd.s16    q11, q2, q3
+    vabs.s16    q10, q10
 
-    vtrn.32     q4, q5
-    vtrn.32     q6, q7
+    vtrn.32     q8, q9
+    vtrn.32     q10, q11
 
-    vmax.s16    q0, q4, q5
-    vmax.s16    q1, q6, q7
+    vmax.s16    q0, q8, q9
+    vmax.s16    q1, q10, q11
 .endm
 
 .macro SAD_16x4
@@ -221,6 +221,7 @@
 
 
 WELS_ASM_FUNC_BEGIN WelsSampleSad16x16_neon
+    vpush {q4-q7}
 
     vld1.64 {q0}, [r0, :128], r1
     vld1.64 {q1}, [r2], r3
@@ -257,10 +258,13 @@
     vpaddl.u16 d0, d0
     vpaddl.u32 d0, d0
     vmov.u32   r0, d0[0]
+
+    vpop {q4-q7}
 WELS_ASM_FUNC_END
 
 
 WELS_ASM_FUNC_BEGIN WelsSampleSad16x8_neon
+    vpush {q4-q7}
 
     vld1.64 {q0}, [r0, :128], r1
     vld1.64 {q1}, [r2], r3
@@ -295,6 +299,7 @@
     vpaddl.u16 d0, d0
     vpaddl.u32 d0, d0
     vmov.u32   r0, d0[0]
+    vpop {q4-q7}
 WELS_ASM_FUNC_END
 
 
@@ -735,86 +740,94 @@
 
 
 WELS_ASM_FUNC_BEGIN WelsSampleSatd16x16_neon
+    vpush       {q7}
 
     SATD_16x4
-    vadd.u16    q15,  q0, q2
+    vadd.u16    q7,  q0, q2
 
     SATD_16x4
-    vadd.u16    q15,  q15, q0
-    vadd.u16    q15,  q15, q2
+    vadd.u16    q7,  q7, q0
+    vadd.u16    q7,  q7, q2
 
     SATD_16x4
-    vadd.u16    q15,  q15, q0
-    vadd.u16    q15,  q15, q2
+    vadd.u16    q7,  q7, q0
+    vadd.u16    q7,  q7, q2
 
     SATD_16x4
-    vadd.u16    q15,  q15, q0
-    vadd.u16    q15,  q15, q2
+    vadd.u16    q7,  q7, q0
+    vadd.u16    q7,  q7, q2
 
-    vadd.u16  d0, d30, d31
+    vadd.u16  d0, d14, d15
     vpaddl.u16  d0, d0
     vpaddl.u32  d0, d0
 
     vmov.32     r0,  d0[0]
+    vpop        {q7}
 WELS_ASM_FUNC_END
 
 
 WELS_ASM_FUNC_BEGIN WelsSampleSatd16x8_neon
+    vpush       {q7}
 
     SATD_16x4
-    vadd.u16    q15,  q0, q2
+    vadd.u16    q7,  q0, q2
 
     SATD_16x4
-    vadd.u16    q15,  q15, q0
-    vadd.u16    q15,  q15, q2
+    vadd.u16    q7,  q7, q0
+    vadd.u16    q7,  q7, q2
 
-    vadd.u16  d0, d30, d31
+    vadd.u16  d0, d14, d15
     vpaddl.u16  d0, d0
     vpaddl.u32  d0, d0
 
     vmov.32     r0,  d0[0]
+    vpop        {q7}
 WELS_ASM_FUNC_END
 
 
 WELS_ASM_FUNC_BEGIN WelsSampleSatd8x16_neon
+    vpush       {q7}
 
     SATD_8x4
-    vadd.u16    q15,  q0, q1
+    vadd.u16    q7,  q0, q1
 
     SATD_8x4
-    vadd.u16    q15,  q15, q0
-    vadd.u16    q15,  q15, q1
+    vadd.u16    q7,  q7, q0
+    vadd.u16    q7,  q7, q1
 
     SATD_8x4
-    vadd.u16    q15,  q15, q0
-    vadd.u16    q15,  q15, q1
+    vadd.u16    q7,  q7, q0
+    vadd.u16    q7,  q7, q1
 
     SATD_8x4
-    vadd.u16    q15,  q15, q0
-    vadd.u16    q15,  q15, q1
+    vadd.u16    q7,  q7, q0
+    vadd.u16    q7,  q7, q1
 
-    vadd.u16  d0, d30, d31
+    vadd.u16  d0, d14, d15
     vpaddl.u16  d0, d0
     vpaddl.u32  d0, d0
 
     vmov.32     r0,  d0[0]
+    vpop        {q7}
 WELS_ASM_FUNC_END
 
 
 WELS_ASM_FUNC_BEGIN WelsSampleSatd8x8_neon
+    vpush       {q7}
 
     SATD_8x4
-    vadd.u16    q15,  q0, q1
+    vadd.u16    q7,  q0, q1
 
     SATD_8x4
-    vadd.u16    q15,  q15, q0
-    vadd.u16    q15,  q15, q1
+    vadd.u16    q7,  q7, q0
+    vadd.u16    q7,  q7, q1
 
-    vadd.u16  d0, d30, d31
+    vadd.u16  d0, d14, d15
     vpaddl.u16  d0, d0
     vpaddl.u32  d0, d0
 
     vmov.32     r0,  d0[0]
+    vpop        {q7}
 WELS_ASM_FUNC_END
 
 
--- a/codec/processing/src/arm/vaa_calc_neon.S
+++ b/codec/processing/src/arm/vaa_calc_neon.S
@@ -635,8 +635,9 @@
 
 WELS_ASM_FUNC_BEGIN VAACalcSadSsdBgd_neon
 	stmdb sp!, {r0-r12, r14}
+	vpush {q4-q7}
 
-	ldr r4, [sp, #56] //r4 keeps the pic_stride
+	ldr r4, [sp, #120] //r4 keeps the pic_stride
 
 	sub r5, r4, #1
 	lsl r5, r5, #4 //r5 keeps the little step
@@ -645,12 +646,12 @@
 	sub r6, r2, r6	//r6 keeps the big step
 
 
-	ldr r8, [sp, #64]//psad8x8
-	ldr r9, [sp, #68]//psum16x16
-	ldr r10, [sp, #72]//psqsum16x16
-	ldr r11, [sp, #76]//psqdiff16x16
-	ldr r12, [sp, #80]//p_sd8x8
-	ldr r14, [sp, #84]//p_mad8x8
+	ldr r8, [sp, #128]//psad8x8
+	ldr r9, [sp, #132]//psum16x16
+	ldr r10, [sp, #136]//psqsum16x16
+	ldr r11, [sp, #140]//psqdiff16x16
+	ldr r12, [sp, #144]//p_sd8x8
+	ldr r14, [sp, #148]//p_mad8x8
 
 	vmov.i8 q12, #0
 
@@ -700,11 +701,12 @@
 bne vaa_calc_sad_ssd_bgd_height_loop
 
 	//psadframe
-	ldr r7, [sp, #60]//psadframe
+	ldr r7, [sp, #124]//psadframe
 
 	vadd.i32 d24, d24, d25
 	vst1.32 {d24[0]}, [r7]
 
+	vpop {q4-q7}
 	ldmia sp!, {r0-r12, r14}
 
 WELS_ASM_FUNC_END
@@ -912,8 +914,10 @@
 
 WELS_ASM_FUNC_BEGIN VAACalcSadVar_neon
 	stmdb sp!, {r4-r11}
+	vpush {q4}
+	vpush {q6-q7}
 
-	ldr r4, [sp, #32] //r4 keeps the pic_stride
+	ldr r4, [sp, #80] //r4 keeps the pic_stride
 
 	sub r5, r4, #1
 	lsl r5, r5, #4 //r5 keeps the little step
@@ -921,10 +925,10 @@
 	lsl r6, r4, #4
 	sub r6, r2, r6	//r6 keeps the big step
 
-	ldr r7,		[sp, #36]	//psadframe
-	ldr r8,		[sp, #40]	//psad8x8
-	ldr r9,		[sp, #44]	//psum16x16
-	ldr r10,	[sp, #48]	//psqsum16x16
+	ldr r7,		[sp, #84]	//psadframe
+	ldr r8,		[sp, #88]	//psad8x8
+	ldr r9,		[sp, #92]	//psum16x16
+	ldr r10,	[sp, #96]	//psqsum16x16
 
 	vmov.i8 q12, #0
 vaa_calc_sad_var_height_loop:
@@ -961,6 +965,8 @@
 	vadd.i32 d24, d24, d25
 	vst1.32 {d24[0]}, [r7]
 
+	vpop {q6-q7}
+	vpop {q4}
 	ldmia sp!, {r4-r11}
 WELS_ASM_FUNC_END
 
@@ -1080,8 +1086,10 @@
 
 WELS_ASM_FUNC_BEGIN VAACalcSadSsd_neon
 	stmdb sp!, {r4-r12}
+	vpush {q4}
+	vpush {q6-q7}
 
-	ldr r4, [sp, #36] //r4 keeps the pic_stride
+	ldr r4, [sp, #84] //r4 keeps the pic_stride
 
 	sub r5, r4, #1
 	lsl r5, r5, #4 //r5 keeps the little step
@@ -1089,11 +1097,11 @@
 	lsl r6, r4, #4
 	sub r6, r2, r6	//r6 keeps the big step
 
-	ldr r7,		[sp, #40]	//psadframe
-	ldr r8,		[sp, #44]	//psad8x8
-	ldr r9,		[sp, #48]	//psum16x16
-	ldr r10,	[sp, #52]	//psqsum16x16
-	ldr r11,	[sp, #56]	//psqdiff16x16
+	ldr r7,		[sp, #88]	//psadframe
+	ldr r8,		[sp, #92]	//psad8x8
+	ldr r9,		[sp, #96]	//psum16x16
+	ldr r10,	[sp, #100]	//psqsum16x16
+	ldr r11,	[sp, #104]	//psqdiff16x16
 
 	vmov.i8 q12, #0
 vaa_calc_sad_ssd_height_loop:
@@ -1137,6 +1145,8 @@
 	vadd.i32 d24, d24, d25
 	vst1.32 {d24[0]}, [r7]
 
+	vpop {q6-q7}
+	vpop {q4}
 	ldmia sp!, {r4-r12}
 WELS_ASM_FUNC_END