[patch] Arm Thumb-2 support

Jeff Johnston jjohnstn@redhat.com
Tue Feb 7 18:48:00 GMT 2006


Paul Brook wrote:
> The attached patch allows building Arm newlib/libgloss in Thumb-2 mode. Future 
> Arm CPUs will implement Thumb-2 only and not Arm mode, so the existing Thumb 
> support is not sufficient. The patch makes two changes:
> 
> - Add pure Thumb-2 startup code.
> - Use the BKPT instruction instead of SWI for semihosted syscalls.
> 
> Tested with cross to arm-none-eabi.
> Ok?
> 

Yes.  Patch checked in.

Thanks,

-- Jeff J.

> Paul
> 
> 2006-02-07  Paul Brook  <paul@codesourcery.com>
> 
> libgloss/
> 	* arm/crt0.S: Add Thumb-2 startup code.
> 	* arm/redboot-crt0.S: Ditto.
> 	* arm/libcfunc.c (do_AngelSWI): Use AngelSWIInsn.
> 	* arm/swi.h (AngelSWIInsn, AngelSWIAsm): Define.
> 	* arm/trap.S: Disable for Thumb-2.
> newlib/
> 	* libc/machine/arm/setjmp.S: Add Thumb-2 support.
> 	* libc/sys/arm/crt0.S: Add Thumb-2 startup code.
> 	* libc/sys/arm/libcfunc.c (do_AngelSWI): Use AngelSWIInsn.
> 	* libc/sys/arm/swi.h (AngelSWIInsn, AngelSWIAsm): Define.
> 	* libc/sys/arm/trap.S: Disable for Thumb-2.
> 
> 
> ------------------------------------------------------------------------
> 
> Index: libgloss/arm/crt0.S
> ===================================================================
> RCS file: /var/cvsroot/src-cvs/src/libgloss/arm/crt0.S,v
> retrieving revision 1.4
> diff -u -p -r1.4 crt0.S
> --- libgloss/arm/crt0.S	19 Jul 2005 15:15:25 -0000	1.4
> +++ libgloss/arm/crt0.S	7 Feb 2006 16:44:11 -0000
> @@ -18,15 +18,26 @@
>  
>  /* .text is used instead of .section .text so it works with arm-aout too.  */
>  	.text
> +#if defined(__thumb2__)
> +	.syntax unified
> +	.thumb
> +.macro FUNC_START name
> +	.global \name
> +	.thumb_func
> +\name:
> +.endm
> +#else
>  	.code 32
> +.macro FUNC_START name
> +	.global \name
> +\name:
> +.endm
> +#endif
>  	.align 	0
>  
> -	.global	_mainCRTStartup
> -	.global	_start
> -	.global	start
> -start:
> -_start:
> -_mainCRTStartup:
> +	FUNC_START	_mainCRTStartup
> +	FUNC_START	_start
> +	FUNC_START	start
>  #if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__)
>  	/* Annotation for EABI unwinding tables.  */
>  	.fnstart
> @@ -45,7 +56,12 @@ _mainCRTStartup:
>  	/*  Issue Angel SWI to read stack info */
>  	mov	r0, #AngelSWI_Reason_HeapInfo
>  	adr	r1, .LC0	/*  point at ptr to 4 words to receive data */
> -	swi	AngelSWI_ARM	/*  We are always in ARM mode for startup */
> +#if defined(__thumb2__)
> +	bkpt	AngelSWI
> +#else
> +	/*  We are always in ARM mode for startup */
> +	AngelSWIAsm	AngelSWI_ARM
> +#endif
>  	ldr	r0, .LC0	/*  point at values read */
>  	ldr	sp, [r0, #8]
>  	ldr	sl, [r0, #12]
> @@ -124,8 +140,8 @@ _mainCRTStartup:
>  	sub	a3, a3, a1		/* Third arg: length of block */
>  	
>  
> -#ifdef __thumb__		/* Enter Thumb mode.... */
> -
> +#if defined(__thumb__) && !defined(__thumb2__)
> +	/* Enter Thumb mode.... */
>  	add	a4, pc, #1	/* Get the address of the Thumb block */
>  	bx	a4		/* Go there and start Thumb decoding  */
>  
> @@ -165,7 +181,7 @@ __change_mode:	
>  #else
>  	mov	r0, #AngelSWI_Reason_GetCmdLine
>  	adr	r1, .LC30	/*  Space for command line */
> -	swi	AngelSWI
> +	AngelSWIAsm	AngelSWI
>  	ldr	r1, .LC30
>  #endif
>  	/*  Parse string at r1 */
> @@ -287,7 +303,7 @@ __change_mode:	
>  
>  	bl	FUNCTION (exit)		/* Should not return.  */
>  
> -#ifdef __thumb__
> +#if defined(__thumb__) && !defined(__thumb2__)
>  	/* Come out of Thumb mode.  This code should be redundant.  */
>  
>  	mov	a4, pc
> Index: libgloss/arm/libcfunc.c
> ===================================================================
> RCS file: /var/cvsroot/src-cvs/src/libgloss/arm/libcfunc.c,v
> retrieving revision 1.6
> diff -u -p -r1.6 libcfunc.c
> --- libgloss/arm/libcfunc.c	30 Nov 2005 23:37:14 -0000	1.6
> +++ libgloss/arm/libcfunc.c	7 Feb 2006 16:04:27 -0000
> @@ -15,7 +15,7 @@ static inline int
>  do_AngelSWI (int reason, void * arg)
>  {
>    int value;
> -  asm volatile ("mov r0, %1; mov r1, %2; swi %a3; mov %0, r0"
> +  asm volatile ("mov r0, %1; mov r1, %2; " AngelSWIInsn " %a3; mov %0, r0"
>         : "=r" (value) /* Outputs */
>         : "r" (reason), "r" (arg), "i" (AngelSWI) /* Inputs */
>         : "r0", "r1", "lr"
> Index: libgloss/arm/redboot-crt0.S
> ===================================================================
> RCS file: /var/cvsroot/src-cvs/src/libgloss/arm/redboot-crt0.S,v
> retrieving revision 1.4
> diff -u -p -r1.4 redboot-crt0.S
> --- libgloss/arm/redboot-crt0.S	7 Nov 2002 00:25:57 -0000	1.4
> +++ libgloss/arm/redboot-crt0.S	2 Feb 2006 17:13:54 -0000
> @@ -12,11 +12,23 @@
>  
>      .text
>       /* Setup the assembly entry point.  */
> -    .code 32
> -    .globl SYM_NAME(start)
> -    .globl SYM_NAME(_start)
> -SYM_NAME(start):
> -SYM_NAME(_start):
> +#ifdef __thumb2__
> +.macro FUNC_START name
> +	.global \name
> +	.thumb_func
> +\name:
> +.endm
> +	.syntax unified
> +	.thumb
> +#else
> +.macro FUNC_START name
> +	.global \name
> +\name:
> +.endm
> +	.code 32
> +#endif
> +	FUNC_START SYM_NAME(start)
> +	FUNC_START SYM_NAME(_start)
>  	mov	fp, #0	/* Null frame pointer.  */
>  	mov	r7, #0	/* Null frame pointer for Thumb.  */
>  
> @@ -46,7 +58,7 @@ SYM_NAME(_start):
>  	/* Nothing to left to clear.  */
>  #endif
>  
> -#ifdef __thumb__		/* Enter Thumb mode. */
> +#if defined(__thumb__) && !defined(__thumb2__)	/* Enter Thumb mode. */
>  	add	a4, pc, #1	/* Get the address of the Thumb block.  */
>  	bx	a4		/* Go there and start Thumb decoding.   */
>  
> Index: libgloss/arm/swi.h
> ===================================================================
> RCS file: /var/cvsroot/src-cvs/src/libgloss/arm/swi.h,v
> retrieving revision 1.1
> diff -u -p -r1.1 swi.h
> --- libgloss/arm/swi.h	9 Jun 2004 19:06:50 -0000	1.1
> +++ libgloss/arm/swi.h	7 Feb 2006 16:44:39 -0000
> @@ -33,6 +33,14 @@
>  #else
>  #define AngelSWI 			AngelSWI_ARM
>  #endif
> +/* For Thumb-2 code use the BKPT instruction instead of SWI.  */
> +#ifdef __thumb2__
> +#define AngelSWIInsn			"bkpt"
> +#define AngelSWIAsm			bkpt
> +#else
> +#define AngelSWIInsn			"swi"
> +#define AngelSWIAsm			swi
> +#endif
>  
>  /* The reason codes:  */
>  #define AngelSWI_Reason_Open		0x01
> Index: libgloss/arm/syscalls.c
> ===================================================================
> RCS file: /var/cvsroot/src-cvs/src/libgloss/arm/syscalls.c,v
> retrieving revision 1.8
> diff -u -p -r1.8 syscalls.c
> --- libgloss/arm/syscalls.c	30 Nov 2005 23:37:14 -0000	1.8
> +++ libgloss/arm/syscalls.c	7 Feb 2006 16:34:58 -0000
> @@ -99,7 +99,7 @@ static inline int
>  do_AngelSWI (int reason, void * arg)
>  {
>    int value;
> -  asm volatile ("mov r0, %1; mov r1, %2; swi %a3; mov %0, r0"
> +  asm volatile ("mov r0, %1; mov r1, %2; " AngelSWIInsn " %a3; mov %0, r0"
>         : "=r" (value) /* Outputs */
>         : "r" (reason), "r" (arg), "i" (AngelSWI) /* Inputs */
>         : "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc"
> Index: libgloss/arm/trap.S
> ===================================================================
> RCS file: /var/cvsroot/src-cvs/src/libgloss/arm/trap.S,v
> retrieving revision 1.1
> diff -u -p -r1.1 trap.S
> --- libgloss/arm/trap.S	9 Jun 2004 19:06:50 -0000	1.1
> +++ libgloss/arm/trap.S	3 Feb 2006 17:42:28 -0000
> @@ -1,4 +1,5 @@
>          /* Run-time exception support */
> +#if !defined(__thumb2__)
>  #include "swi.h"
>  
>  /* .text is used instead of .section .text so it works with arm-aout too.  */
> @@ -91,3 +92,4 @@ __rt_stkovf_split_big:
>          @ We now know how much extra stack the function requires.
>          @ Terminate the program for the moment:
>          swi     SWI_Exit
> +#endif
> Index: newlib/libc/machine/arm/setjmp.S
> ===================================================================
> RCS file: /var/cvsroot/src-cvs/src/newlib/libc/machine/arm/setjmp.S,v
> retrieving revision 1.1
> diff -u -p -r1.1 setjmp.S
> --- newlib/libc/machine/arm/setjmp.S	9 Jun 2004 19:05:09 -0000	1.1
> +++ newlib/libc/machine/arm/setjmp.S	2 Feb 2006 16:52:52 -0000
> @@ -51,17 +51,39 @@
>     Function entry is much simpler.  If we are compiling for the Thumb we 
>     just switch into ARM mode and then drop through into the rest of the
>     function.  The function exit code will take care of the restore to
> -   Thumb mode.  */
> +   Thumb mode.
> +   
> +   For Thumb-2 do everything in Thumb mode.  */
>  
>  #ifdef __APCS_26__
>  #define RET	movs		pc, lr
> +#elif defined(__thumb2__)
> +#define RET	bx lr
>  #else
>  #define RET	tst		lr, #1; \
>  	        moveq		pc, lr ; \
>  .word           0xe12fff1e	/* bx lr */
>  #endif
>  
> -#ifdef __thumb__
> +#ifdef __thumb2__
> +.macro COND where when 
> +	i\where	\when
> +.endm
> +#else
> +.macro COND where when 
> +.endm
> +#endif
> +
> +#if defined(__thumb2__)
> +.syntax unified
> +.macro MODE
> +	.thumb
> +	.thumb_func
> +.endm
> +.macro PROLOGUE name
> +.endm
> +
> +#elif defined(__thumb__)
>  #define	MODE		.thumb_func
>  .macro PROLOGUE name
>  	.code 16
> @@ -70,7 +92,7 @@
>  	.code 32
>  SYM (.arm_start_of.\name):
>  .endm
> -#else
> +#else /* Arm */
>  #define	MODE		.code 32
>  .macro PROLOGUE name
>  .endm
> @@ -131,6 +153,9 @@ SYM (\name):
>  	/* Put the return value into the integer result register.
>  	   But if it is zero then return 1 instead.  */	
>  	movs		a1, a2
> +#ifdef __thumb2__
> +	it		eq
> +#endif
>  	moveq		a1, #1
>  
>  	FUNC_END longjmp
> Index: newlib/libc/sys/arm/crt0.S
> ===================================================================
> RCS file: /var/cvsroot/src-cvs/src/newlib/libc/sys/arm/crt0.S,v
> retrieving revision 1.11
> diff -u -p -r1.11 crt0.S
> --- newlib/libc/sys/arm/crt0.S	19 Jul 2005 15:14:16 -0000	1.11
> +++ newlib/libc/sys/arm/crt0.S	7 Feb 2006 16:43:32 -0000
> @@ -18,15 +18,26 @@
>  
>  /* .text is used instead of .section .text so it works with arm-aout too.  */
>  	.text
> +#if defined(__thumb2__)
> +	.syntax unified
> +	.thumb
> +.macro FUNC_START name
> +	.global	\name
> +	.thumb_func
> +\name:
> +.endm	
> +#else
>  	.code 32
> +.macro FUNC_START name
> +	.global	\name
> +\name:
> +.endm	
> +#endif
>  	.align 	0
>  
> -	.global	_mainCRTStartup
> -	.global	_start
> -	.global	start
> -start:
> -_start:
> -_mainCRTStartup:
> +	FUNC_START	_mainCRTStartup
> +	FUNC_START	_start
> +	FUNC_START	start
>  #if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__)
>  	/* Annotation for EABI unwinding tables.  */
>  	.fnstart
> @@ -45,7 +56,12 @@ _mainCRTStartup:
>  	/*  Issue Angel SWI to read stack info */
>  	mov	r0, #AngelSWI_Reason_HeapInfo
>  	adr	r1, .LC0	/*  point at ptr to 4 words to receive data */
> -	swi	AngelSWI_ARM	/*  We are always in ARM mode for startup */
> +#if defined(__thumb2__)
> +	bkpt	AngelSWI
> +#else
> +	/*  We are always in ARM mode for startup */
> +	AngelSWIAsm	AngelSWI_ARM
> +#endif
>  	ldr	r0, .LC0	/*  point at values read */
>  	ldr	sp, [r0, #8]
>  	ldr	sl, [r0, #12]
> @@ -75,8 +91,8 @@ _mainCRTStartup:
>  	sub	a3, a3, a1		/* Third arg: length of block */
>  	
>  
> -#ifdef __thumb__		/* Enter Thumb mode.... */
> -
> +#if defined(__thumb__) && !defined(__thumb2__)
> +	/* Enter Thumb mode.... */
>  	add	a4, pc, #1	/* Get the address of the Thumb block */
>  	bx	a4		/* Go there and start Thumb decoding  */
>  
> @@ -100,7 +116,7 @@ __change_mode:	
>  #else
>  	mov	r0, #AngelSWI_Reason_GetCmdLine
>  	adr	r1, .LC30	/*  Space for command line */
> -	swi	AngelSWI
> +	AngelSWIAsm	AngelSWI
>  	ldr	r1, .LC30
>  #endif
>  	/*  Parse string at r1 */
> @@ -222,7 +238,7 @@ __change_mode:	
>  
>  	bl	FUNCTION (exit)		/* Should not return.  */
>  
> -#ifdef __thumb__
> +#if defined(__thumb__) && !defined(__thumb2__)
>  	/* Come out of Thumb mode.  This code should be redundant.  */
>  
>  	mov	a4, pc
> Index: newlib/libc/sys/arm/libcfunc.c
> ===================================================================
> RCS file: /var/cvsroot/src-cvs/src/newlib/libc/sys/arm/libcfunc.c,v
> retrieving revision 1.1.1.1
> diff -u -p -r1.1.1.1 libcfunc.c
> --- newlib/libc/sys/arm/libcfunc.c	17 Feb 2000 19:39:49 -0000	1.1.1.1
> +++ newlib/libc/sys/arm/libcfunc.c	7 Feb 2006 16:03:37 -0000
> @@ -13,7 +13,7 @@ static inline int
>  do_AngelSWI (int reason, void * arg)
>  {
>    int value;
> -  asm volatile ("mov r0, %1; mov r1, %2; swi %a3; mov %0, r0"
> +  asm volatile ("mov r0, %1; mov r1, %2; " AngelSWIInsn " %a3; mov %0, r0"
>         : "=r" (value) /* Outputs */
>         : "r" (reason), "r" (arg), "i" (AngelSWI) /* Inputs */
>         : "r0", "r1", "lr"
> Index: newlib/libc/sys/arm/swi.h
> ===================================================================
> RCS file: /var/cvsroot/src-cvs/src/newlib/libc/sys/arm/swi.h,v
> retrieving revision 1.2
> diff -u -p -r1.2 swi.h
> --- newlib/libc/sys/arm/swi.h	21 Jun 2002 06:55:37 -0000	1.2
> +++ newlib/libc/sys/arm/swi.h	7 Feb 2006 16:46:54 -0000
> @@ -33,6 +33,14 @@
>  #else
>  #define AngelSWI 			AngelSWI_ARM
>  #endif
> +/* For Thumb-2 code use the BKPT instruction instead of SWI.  */
> +#ifdef __thumb2__
> +#define AngelSWIInsn			"bkpt"
> +#define AngelSWIAsm			bkpt
> +#else
> +#define AngelSWIInsn			"swi"
> +#define AngelSWIAsm			swi
> +#endif
>  
>  /* The reason codes:  */
>  #define AngelSWI_Reason_Open		0x01
> Index: newlib/libc/sys/arm/syscalls.c
> ===================================================================
> RCS file: /var/cvsroot/src-cvs/src/newlib/libc/sys/arm/syscalls.c,v
> retrieving revision 1.10
> diff -u -p -r1.10 syscalls.c
> --- newlib/libc/sys/arm/syscalls.c	8 Feb 2005 01:33:19 -0000	1.10
> +++ newlib/libc/sys/arm/syscalls.c	7 Feb 2006 15:56:02 -0000
> @@ -98,7 +98,7 @@ static inline int
>  do_AngelSWI (int reason, void * arg)
>  {
>    int value;
> -  asm volatile ("mov r0, %1; mov r1, %2; swi %a3; mov %0, r0"
> +  asm volatile ("mov r0, %1; mov r1, %2; " AngelSWIInsn " %a3; mov %0, r0"
>         : "=r" (value) /* Outputs */
>         : "r" (reason), "r" (arg), "i" (AngelSWI) /* Inputs */
>         : "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc"
> Index: newlib/libc/sys/arm/trap.S
> ===================================================================
> RCS file: /var/cvsroot/src-cvs/src/newlib/libc/sys/arm/trap.S,v
> retrieving revision 1.1.1.1
> diff -u -p -r1.1.1.1 trap.S
> --- newlib/libc/sys/arm/trap.S	17 Feb 2000 19:39:49 -0000	1.1.1.1
> +++ newlib/libc/sys/arm/trap.S	2 Feb 2006 15:31:27 -0000
> @@ -1,4 +1,5 @@
>          /* Run-time exception support */
> +#if !defined(__thumb2__)
>  #include "swi.h"
>  
>  /* .text is used instead of .section .text so it works with arm-aout too.  */
> @@ -91,3 +92,4 @@ __rt_stkovf_split_big:
>          @ We now know how much extra stack the function requires.
>          @ Terminate the program for the moment:
>          swi     SWI_Exit
> +#endif



More information about the Newlib mailing list