[patch] newlib: Tweak setjmp for E500

Jeff Johnston jjohnstn@redhat.com
Wed Jan 17 15:19:00 GMT 2007


Ok.  Patch checked in.

-- Jeff J.

Kazu Hirata wrote:
> Hi,
> 
> Attached is a patch to tweak setjmp for E500.
> 
> On E500V1 and E500V2, GPRs (general purpose registers) are 64-bit
> wide, so we need to modify setjmp and longjmp to save and restore
> 64-bit registers.  I've put various comments in the code, so I hope
> the rest is fairly obvious.
> 
> Tested by running setjmp and lonjmp on a simulator.  OK to apply?
> 
> Kazu Hirata
> 
> 2007-01-12  Joseph Myers  <joseph@codesourcery.com>
> 	    Kazu Hirata  <kazu@codesourcery.com>
> 
> 	newlib/
> 	* libc/machine/powerpc/setjmp.S (setjmp, longjmp): Add support
> 	for E500V1 and E500V2.
> 
> Index: newlib/libc/machine/powerpc/setjmp.S
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/machine/powerpc/setjmp.S,v
> retrieving revision 1.2
> diff -u -d -p -r1.2 setjmp.S
> --- newlib/libc/machine/powerpc/setjmp.S	19 Apr 2002 19:16:17 -0000	1.2
> +++ newlib/libc/machine/powerpc/setjmp.S	12 Jan 2007 23:24:19 -0000
> @@ -12,6 +12,35 @@ FUNC_START(setjmp)
>  	addi	3,3,7		# align to 8 byte boundary
>  	rlwinm	3,3,0,0,28
>  #endif
> +#if __SPE__
> +	/* If we are E500, then save 64-bit registers.  */
> +	evstdd	1,0(3)		# offset 0
> +	evstdd	2,8(3)		# offset 8
> +	evstdd	13,16(3)	# offset 16
> +	evstdd	14,24(3)	# offset 24
> +	evstdd	15,32(3)	# offset 32
> +	evstdd	16,40(3)	# offset 40
> +	evstdd	17,48(3)	# offset 48
> +	evstdd	18,56(3)	# offset 56
> +	evstdd	19,64(3)	# offset 64
> +	evstdd	20,72(3)	# offset 72
> +	evstdd	21,80(3)	# offset 80
> +	evstdd	22,88(3)	# offset 88
> +	evstdd	23,96(3)	# offset 96
> +	evstdd	24,104(3)	# offset 104
> +	evstdd	25,112(3)	# offset 112
> +	evstdd	26,120(3)	# offset 120
> +	evstdd	27,128(3)	# offset 128
> +	evstdd	28,136(3)	# offset 136
> +	evstdd	29,144(3)	# offset 144
> +	evstdd	30,152(3)	# offset 152
> +	evstdd	31,160(3)	# offset 160
> +
> +	/* Add 164 to r3 to account for the amount of data we just
> +	   stored.  Note that we are not adding 168 because the next
> +	   store instruction uses an offset of 4.  */
> +	addi	3,3,164
> +#else
>  	stw	1,0(3)		# offset 0
>  	stwu	2,4(3)		# offset 4
>  	stwu	13,4(3)		# offset 8
> @@ -33,12 +62,22 @@ FUNC_START(setjmp)
>  	stwu	29,4(3)		# offset 72
>  	stwu	30,4(3)		# offset 76
>  	stwu	31,4(3)		# offset 80
> +#endif
> +
> +	/* From this point on until the end of this function, add 84
> +	   to the offset shown if __SPE__.  This difference comes from
> +	   the fact that we save 21 64-bit registers instead of 21
> +	   32-bit registers above.  */
>  	mflr	4
>  	stwu	4,4(3)		# offset 84
>  	mfcr	4
>  	stwu	4,4(3)		# offset 88
>  				# one word pad to get floating point aligned on 8 byte boundary
> -#ifndef _SOFT_FLOAT
> +
> +	/* Check whether we need to save FPRs.  Checking __NO_FPRS__
> +	   on its own would be enough for GCC 4.1 and above, but older
> +	   compilers only define _SOFT_FLOAT, so check both.  */
> +#if !defined (__NO_FPRS__) && !defined (_SOFT_FLOAT)
>  	stfdu	14,8(3)		# offset 96
>  	stfdu	15,8(3)		# offset 104
>  	stfdu	16,8(3)		# offset 112
> @@ -106,6 +145,35 @@ FUNC_START(longjmp)
>  	addi	3,3,7		# align to 8 byte boundary
>  	rlwinm	3,3,0,0,28
>  #endif
> +#if __SPE__
> +	/* If we are E500, then restore 64-bit registers.  */
> +	evldd	1,0(3)		# offset 0
> +	evldd	2,8(3)		# offset 8
> +	evldd	13,16(3)	# offset 16
> +	evldd	14,24(3)	# offset 24
> +	evldd	15,32(3)	# offset 32
> +	evldd	16,40(3)	# offset 40
> +	evldd	17,48(3)	# offset 48
> +	evldd	18,56(3)	# offset 56
> +	evldd	19,64(3)	# offset 64
> +	evldd	20,72(3)	# offset 72
> +	evldd	21,80(3)	# offset 80
> +	evldd	22,88(3)	# offset 88
> +	evldd	23,96(3)	# offset 96
> +	evldd	24,104(3)	# offset 104
> +	evldd	25,112(3)	# offset 112
> +	evldd	26,120(3)	# offset 120
> +	evldd	27,128(3)	# offset 128
> +	evldd	28,136(3)	# offset 136
> +	evldd	29,144(3)	# offset 144
> +	evldd	30,152(3)	# offset 152
> +	evldd	31,160(3)	# offset 160
> +
> +	/* Add 164 to r3 to account for the amount of data we just
> +	   loaded.  Note that we are not adding 168 because the next
> +	   load instruction uses an offset of 4.  */
> +	addi	3,3,164
> +#else
>  	lwz	1,0(3)		# offset 0 
>  	lwzu	2,4(3)		# offset 4 
>  	lwzu	13,4(3)		# offset 8 
> @@ -127,12 +195,22 @@ FUNC_START(longjmp)
>  	lwzu	29,4(3)		# offset 72
>  	lwzu	30,4(3)		# offset 76
>  	lwzu	31,4(3)		# offset 80
> +#endif
> +	/* From this point on until the end of this function, add 84
> +	   to the offset shown if __SPE__.  This difference comes from
> +	   the fact that we restore 21 64-bit registers instead of 21
> +	   32-bit registers above.  */
>  	lwzu	5,4(3)		# offset 84
>  	mtlr	5
>  	lwzu	5,4(3)		# offset 88
>  	mtcrf	255,5
>  				# one word pad to get floating point aligned on 8 byte boundary
> -#ifndef _SOFT_FLOAT
> +
> +	/* Check whether we need to restore FPRs.  Checking
> +	   __NO_FPRS__ on its own would be enough for GCC 4.1 and
> +	   above, but older compilers only define _SOFT_FLOAT, so
> +	   check both.  */
> +#if !defined (__NO_FPRS__) && !defined (_SOFT_FLOAT)
>  	lfdu	14,8(3)         # offset 96 
>  	lfdu	15,8(3)         # offset 104
>  	lfdu	16,8(3)         # offset 112



More information about the Newlib mailing list