[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