This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

ARM/Thumb interworking supporting in libgcc.a


Hi Guys,

  I am checking in the patch below to fix up interworking support in
  the assembler routines in libgcc.a for the ARM.  This patch was
  developed by Richard Earnshaw and tidied up by myself.  I also took
  the opportunity to tidy up lib1funcs.asm a bit by replacing some of
  the duplicated code with macros.

Cheers
	Nick

2000-08-10  Richard Earnshaw <rearnshaw@arm.com> & Nick Clifton  <nickc@cygnus.com>

	* arm.h (CPP_SPEC): Use sub-spec cpp_interwork.
	(CPP_INTERWORK_SPEC, CPP_INTERWORK_DEFAULT_SPEC): New sub-specs.
	(EXTRA_SPECS): Add them.
	* arm/lib1funcs.asm: Support builds for interworking.
	Use macros to eliminate duplicated pieces of code.

Index: gcc/config/arm/arm.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/arm/arm.h,v
retrieving revision 1.77
diff -p -r1.77 arm.h
*** arm.h	2000/06/27 02:26:15	1.77
--- arm.h	2000/08/11 00:26:00
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 127,133 ****
  
  #define CPP_SPEC "\
  %(cpp_cpu_arch) %(cpp_apcs_pc) %(cpp_float) \
! %(cpp_endian) %(subtarget_cpp_spec) %(cpp_isa)"
  
  #define CPP_ISA_SPEC "%{mthumb:-Dthumb -D__thumb__} %{!mthumb:-Darm -D__arm__}"
  
--- 127,133 ----
  
  #define CPP_SPEC "\
  %(cpp_cpu_arch) %(cpp_apcs_pc) %(cpp_float) \
! %(cpp_endian) %(subtarget_cpp_spec) %(cpp_isa) %(cpp_interwork)"
  
  #define CPP_ISA_SPEC "%{mthumb:-Dthumb -D__thumb__} %{!mthumb:-Darm -D__arm__}"
  
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 234,239 ****
--- 234,253 ----
  /* Default is little endian.  */
  #define CPP_ENDIAN_DEFAULT_SPEC "-D__ARMEL__ %{mthumb:-D__THUMBEL__}"
  
+ /* Add a define for interworking.  Needed when building libgcc.a.  
+    This must define __THUMB_INTERWORK__ to the pre-processor if
+    interworking is enabled by default.  */
+ #ifndef CPP_INTERWORK_DEFAULT_SPEC
+ #define CPP_INTERWORK_DEFAULT_SPEC ""
+ #endif
+ 
+ #define CPP_INTERWORK_SPEC "						\
+ %{mthumb-interwork:							\
+   %{mno-thumb-interwork: %eIncompatible interworking options}		\
+   -D__THUMB_INTERWORK__}						\
+ %{!mthumb-interwork:%{!mno-thumb-interwork:%(cpp_interwork_default)}}	\
+ "
+ 
  #define CC1_SPEC ""
  
  /* This macro defines names of additional specifications to put in the specs
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 255,260 ****
--- 269,276 ----
    { "cpp_endian",		CPP_ENDIAN_SPEC },		\
    { "cpp_endian_default",	CPP_ENDIAN_DEFAULT_SPEC },	\
    { "cpp_isa",			CPP_ISA_SPEC },			\
+   { "cpp_interwork",		CPP_INTERWORK_SPEC },		\
+   { "cpp_interwork_default",	CPP_INTERWORK_DEFAULT_SPEC },	\
    { "subtarget_cpp_spec",	SUBTARGET_CPP_SPEC },           \
    SUBTARGET_EXTRA_SPECS
  
Index: gcc/config/arm/lib1funcs.asm
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/arm/lib1funcs.asm,v
retrieving revision 1.10
diff -p -r1.10 lib1funcs.asm
*** lib1funcs.asm	2000/05/15 23:14:15	1.10
--- lib1funcs.asm	2000/08/11 00:26:00
*************** You should have received a copy of the G
*** 26,42 ****
  along with this program; see the file COPYING.  If not, write to
  the Free Software Foundation, 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */
! 
! #ifdef __APCS_26__
! #define RET	movs	pc, lr
! #define RETc(x)	mov##x##s	pc, lr
! #define RETCOND ^
! #else
! #define RET	mov	pc, lr
! #define RETc(x)	mov##x	pc, lr
! #define RETCOND
! #endif
! 
  #ifndef __USER_LABEL_PREFIX__
  #error  __USER_LABEL_PREFIX__ not defined
  #endif
--- 26,32 ----
  along with this program; see the file COPYING.  If not, write to
  the Free Software Foundation, 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */
! /* ------------------------------------------------------------------------ */
  #ifndef __USER_LABEL_PREFIX__
  #error  __USER_LABEL_PREFIX__ not defined
  #endif
*************** Boston, MA 02111-1307, USA.  */
*** 52,58 ****
  
  #ifdef __ELF__
  #ifdef __thumb__
! #define __PLT__  /* Not supported in thumb assembler (for now).  */
  #else
  #define __PLT__ (PLT)
  #endif
--- 42,48 ----
  
  #ifdef __ELF__
  #ifdef __thumb__
! #define __PLT__  /* Not supported in Thumb assembler (for now).  */
  #else
  #define __PLT__ (PLT)
  #endif
*************** Boston, MA 02111-1307, USA.  */
*** 64,69 ****
--- 54,108 ----
  #define SIZE(x)
  #endif
  
+ /* Function end macros.  Variants for 26 bit APCS and interworking.  */
+ #ifdef __APCS_26__
+ # define RET		movs	pc, lr
+ # define RETc(x)	mov##x##s	pc, lr
+ # define RETCOND 	^
+ .macro ARM_LDIV0
+ Ldiv0:
+ 	str	lr, [sp, #-4]!
+ 	bl	SYM (__div0) __PLT__
+ 	mov	r0, #0			@ About as wrong as it could be.
+ 	ldmia	sp!, {pc}^
+ .endm
+ #else
+ # ifdef __THUMB_INTERWORK__
+ #  define RET		bx	lr
+ #  define RETc(x)	bx##x	lr
+ .macro THUMB_LDIV0
+ 	push	{ lr }
+ 	bl	SYM (__div0)
+ 	mov	r0, #0			@ About as wrong as it could be.
+ 	pop	{ r1 }
+ 	bx	r1
+ .endm
+ .macro ARM_LDIV0
+ 	str	lr, [sp, #-4]!
+ 	bl	SYM (__div0) __PLT__
+ 	mov	r0, #0			@ About as wrong as it could be.
+ 	ldr	lr, [sp], #4
+ 	bx	lr
+ .endm	
+ # else
+ #  define RET		mov	pc, lr
+ #  define RETc(x)	mov##x	pc, lr
+ .macro THUMB_LDIV0
+ 	push	{ lr }
+ 	bl	SYM (__div0)
+ 	mov	r0, #0			@ About as wrong as it could be.
+ 	pop	{ pc }
+ .endm
+ .macro ARM_LDIV0
+ 	str	lr, [sp, #-4]!
+ 	bl	SYM (__div0) __PLT__
+ 	mov	r0, #0			@ About as wrong as it could be.
+ 	ldmia	sp!, {pc}
+ .endm	
+ # endif
+ # define RETCOND
+ #endif
+ 
  #ifdef __thumb__
  #define THUMB_FUNC .thumb_func
  #define THUMB_CODE .force_thumb
*************** Boston, MA 02111-1307, USA.  */
*** 83,91 ****
--- 122,148 ----
  SYM (__\name):
  .endm
  
+ .macro FUNC_END name
+ Ldiv0:
+ #ifdef __thumb__
+ 	THUMB_LDIV0
+ #else
+ 	ARM_LDIV0
+ #endif
+ 	SIZE (__\name)	
+ .endm
+ 
+ .macro THUMB_FUNC_START name
+ 	.globl	SYM (\name)
+ 	TYPE	(\name)
+ 	.thumb_func
+ SYM (\name):
+ .endm
+ 		
  /* Used for Thumb code.  */	
  work		.req	r4	@ XXXX is this safe ?
  
+ /* ------------------------------------------------------------------------ */
  #ifdef L_udivsi3
  
  dividend	.req	r0
*************** sp		.req	r13
*** 97,103 ****
  lr		.req	r14
  pc		.req	r15
  	
!  FUNC_START udivsi3
  
  #ifdef __thumb__
  
--- 154,160 ----
  lr		.req	r14
  pc		.req	r15
  	
! 	FUNC_START udivsi3
  
  #ifdef __thumb__
  
*************** Lgot_result:
*** 181,195 ****
  	mov	r0, result
  	pop	{ work }
  	RET
- 
- Ldiv0:
- 	push	{ lr }
- 	bl	SYM (__div0) __PLT__
- 	mov	r0, #0			@ about as wrong as it could be
- 	pop	{ pc }
- 
- #else /* arm version */
  	
  	cmp	divisor, #0
  	beq	Ldiv0
  	mov	curbit, #1
--- 238,246 ----
  	mov	r0, result
  	pop	{ work }
  	RET
  	
+ #else /* ARM version.  */
+ 	
  	cmp	divisor, #0
  	beq	Ldiv0
  	mov	curbit, #1
*************** Lgot_result:
*** 241,258 ****
  	mov	r0, result
  	RET	
  
! Ldiv0:
! 	str	lr, [sp, #-4]!
! 	bl	SYM (__div0) __PLT__
! 	mov	r0, #0			@ about as wrong as it could be
! 	ldmia	sp!, {pc}RETCOND
  
! #endif /* arm version */
! 	
!  SIZE	(__udivsi3)
  
  #endif /* L_udivsi3 */
! 
  #ifdef L_umodsi3
  
  dividend	.req	r0
--- 292,303 ----
  	mov	r0, result
  	RET	
  
! #endif /* ARM version */
  
! 	FUNC_END udivsi3	
  
  #endif /* L_udivsi3 */
! /* ------------------------------------------------------------------------ */
  #ifdef L_umodsi3
  
  dividend	.req	r0
*************** sp		.req	r13
*** 264,270 ****
  lr		.req	r14
  pc		.req	r15
  	
!  FUNC_START umodsi3
  
  #ifdef __thumb__
  
--- 309,315 ----
  lr		.req	r14
  pc		.req	r15
  	
! 	FUNC_START umodsi3
  
  #ifdef __thumb__
  
*************** Over9:
*** 391,404 ****
  	add	dividend, dividend, work
  Over10:
  	pop	{ work }
! 	RET	
! Ldiv0:
! 	push	{ lr }
! 	bl	SYM (__div0) __PLT__
! 	mov	r0, #0			@ about as wrong as it could be
! 	pop	{ pc }
! 
! #else  /* arm version */
  	
  	cmp	divisor, #0
  	beq	Ldiv0
--- 436,443 ----
  	add	dividend, dividend, work
  Over10:
  	pop	{ work }
! 	
! #else  /* ARM version.  */
  	
  	cmp	divisor, #0
  	beq	Ldiv0
*************** Loop3:
*** 463,480 ****
  	addne	dividend, dividend, divisor, lsr #1
  	RET	
  
- Ldiv0:
- 	str	lr, [sp, #-4]!
- 	bl	SYM (__div0) __PLT__
- 	mov	r0, #0			@ about as wrong as it could be
- 	ldmia	sp!, {pc}RETCOND
- 
  #endif /* arm version */
  	
!  SIZE	(__umodsi3)
  
  #endif /* L_umodsi3 */
! 
  #ifdef L_divsi3
  
  dividend	.req	r0
--- 502,513 ----
  	addne	dividend, dividend, divisor, lsr #1
  	RET	
  
  #endif /* arm version */
  	
! 	FUNC_END umodsi3
  
  #endif /* L_umodsi3 */
! /* ------------------------------------------------------------------------ */
  #ifdef L_divsi3
  
  dividend	.req	r0
*************** sp		.req	r13
*** 486,492 ****
  lr		.req	r14
  pc		.req	r15
  
!  FUNC_START divsi3	
  
  #ifdef __thumb__
  	cmp	divisor, #0
--- 519,525 ----
  lr		.req	r14
  pc		.req	r15
  
! 	FUNC_START divsi3	
  
  #ifdef __thumb__
  	cmp	divisor, #0
*************** Over7:
*** 585,597 ****
  	pop	{ work }
  	RET	
  
! Ldiv0:
! 	push	{ lr }
! 	bl	SYM (__div0) __PLT__
! 	mov	r0, #0			@ about as wrong as it could be
! 	pop	{ pc }
! 	
! #else /* arm version */
  	
  	eor	ip, dividend, divisor		@ Save the sign of the result.
  	mov	curbit, #1
--- 618,624 ----
  	pop	{ work }
  	RET	
  
! #else /* ARM version.  */
  	
  	eor	ip, dividend, divisor		@ Save the sign of the result.
  	mov	curbit, #1
*************** Lgot_result:
*** 651,668 ****
  	rsbmi	r0, r0, #0
  	RET	
  
! Ldiv0:
! 	str	lr, [sp, #-4]!
! 	bl	SYM (__div0) __PLT__
! 	mov	r0, #0			@ about as wrong as it could be
! 	ldmia	sp!, {pc}RETCOND
! 
! #endif /* arm version */
  	
!  SIZE	(__divsi3)
  
  #endif /* L_divsi3 */
! 
  #ifdef L_modsi3
  
  dividend	.req	r0
--- 678,689 ----
  	rsbmi	r0, r0, #0
  	RET	
  
! #endif /* ARM version */
  	
! 	FUNC_END divsi3
  
  #endif /* L_divsi3 */
! /* ------------------------------------------------------------------------ */
  #ifdef L_modsi3
  
  dividend	.req	r0
*************** sp		.req	r13
*** 674,680 ****
  lr		.req	r14
  pc		.req	r15
  	
!  FUNC_START modsi3
  
  #ifdef __thumb__
  
--- 695,701 ----
  lr		.req	r14
  pc		.req	r15
  	
! 	FUNC_START modsi3
  
  #ifdef __thumb__
  
*************** Lgot_result:
*** 814,827 ****
  Over10:
  	pop	{ work }
  	RET	
! 
! Ldiv0:
! 	push    { lr }
! 	bl	SYM (__div0) __PLT__
! 	mov	r0, #0			@ about as wrong as it could be
! 	pop	{ pc }
! 
! #else /* arm version */
  	
  	mov	curbit, #1
  	cmp	divisor, #0
--- 835,842 ----
  Over10:
  	pop	{ work }
  	RET	
! 	
! #else /* ARM version.  */
  	
  	mov	curbit, #1
  	cmp	divisor, #0
*************** Lgot_result:
*** 896,924 ****
  	cmp	ip, #0
  	rsbmi	dividend, dividend, #0
  	RET	
! 
! Ldiv0:
! 	str	lr, [sp, #-4]!
! 	bl	SYM (__div0) __PLT__
! 	mov	r0, #0			@ about as wrong as it could be
! 	ldmia	sp!, {pc}RETCOND
! 
! #endif /* arm version */
  	
!  SIZE	(__modsi3)
  
  #endif /* L_modsi3 */
! 
  #ifdef L_dvmd_tls
  
!  FUNC_START div0	
  
  	RET	
  
!  SIZE	(__div0)
  	
  #endif /* L_divmodsi_tools */
! 
  #ifdef L_dvmd_lnx
  @ GNU/Linux division-by zero handler.  Used in place of L_dvmd_tls
  
--- 911,933 ----
  	cmp	ip, #0
  	rsbmi	dividend, dividend, #0
  	RET	
! 	
! #endif /* ARM version */
  	
! 	FUNC_END modsi3
  
  #endif /* L_modsi3 */
! /* ------------------------------------------------------------------------ */
  #ifdef L_dvmd_tls
  
! 	FUNC_START div0	
  
  	RET	
  
! 	SIZE	(__div0)
  	
  #endif /* L_divmodsi_tools */
! /* ------------------------------------------------------------------------ */
  #ifdef L_dvmd_lnx
  @ GNU/Linux division-by zero handler.  Used in place of L_dvmd_tls
  
*************** Ldiv0:
*** 926,932 ****
  	
  #define SIGFPE	8			@ cant use <asm/signal.h> as it
  					@ contains too much C rubbish
!  FUNC_START div0	
  
  	stmfd	sp!, {r1, lr}
  	swi	__NR_getpid
--- 935,941 ----
  	
  #define SIGFPE	8			@ cant use <asm/signal.h> as it
  					@ contains too much C rubbish
! 	FUNC_START div0	
  
  	stmfd	sp!, {r1, lr}
  	swi	__NR_getpid
*************** Ldiv0:
*** 934,945 ****
  	ldmhsfd	sp!, {r1, pc}RETCOND	@ not much we can do
  	mov	r1, #SIGFPE
  	swi	__NR_kill
  	ldmfd	sp!, {r1, pc}RETCOND
! 
!  SIZE 	(__div0)
  	
  #endif /* L_dvmd_lnx */
! 
  /* These next two sections are here despite the fact that they contain Thumb 
     assembler because their presence allows interworked code to be linked even
     when the GCC library is this one.  */
--- 943,959 ----
  	ldmhsfd	sp!, {r1, pc}RETCOND	@ not much we can do
  	mov	r1, #SIGFPE
  	swi	__NR_kill
+ #ifdef __THUMB_INTERWORK__
+ 	ldmfd	sp!, {r1, lr}
+ 	bx	lr
+ #else
  	ldmfd	sp!, {r1, pc}RETCOND
! #endif
! 	
! 	SIZE 	(__div0)
  	
  #endif /* L_dvmd_lnx */
! /* ------------------------------------------------------------------------ */
  /* These next two sections are here despite the fact that they contain Thumb 
     assembler because their presence allows interworked code to be linked even
     when the GCC library is this one.  */
*************** Ldiv0:
*** 958,968 ****
  	.text
  	.align 0
          .force_thumb
  .macro call_via register
! 	.globl	SYM (_call_via_\register)
! 	TYPE	(_call_via_\register)
! 	.thumb_func
! SYM (_call_via_\register):
  	bx	\register
  	nop
  
--- 972,981 ----
  	.text
  	.align 0
          .force_thumb
+ 	
  .macro call_via register
! 	THUMB_FUNC_START _call_via_\register
! 
  	bx	\register
  	nop
  
*************** SYM (_call_via_\register):
*** 986,992 ****
  	call_via lr
  
  #endif /* L_call_via_rX */
! 
  /* Do not build the interworking functions when the target cpu
     is the arm v3 architecture.  (This is one of the multilib
     options).  */
--- 999,1005 ----
  	call_via lr
  
  #endif /* L_call_via_rX */
! /* ------------------------------------------------------------------------ */
  /* Do not build the interworking functions when the target cpu
     is the arm v3 architecture.  (This is one of the multilib
     options).  */
*************** _arm_return:		
*** 1015,1024 ****
  
  .macro interwork register					
  	.code   16
! 	.globl	SYM (_interwork_call_via_\register)
! 	TYPE	(_interwork_call_via_\register)
! 	.thumb_func
! SYM (_interwork_call_via_\register):
  	bx 	pc
  	nop
  	
--- 1028,1036 ----
  
  .macro interwork register					
  	.code   16
! 
! 	THUMB_FUNC_START _interwork_call_via_\register
! 
  	bx 	pc
  	nop
  	
*************** SYM (_interwork_call_via_\register):
*** 1048,1059 ****
  	interwork ip
  	interwork sp
  	
! 	/* The lr case has to be handled a little differently...*/
  	.code 16
! 	.globl	SYM (_interwork_call_via_lr)
! 	TYPE	(_interwork_call_via_lr)
! 	.thumb_func
! SYM (_interwork_call_via_lr):
  	bx 	pc
  	nop
  	
--- 1060,1070 ----
  	interwork ip
  	interwork sp
  	
! 	/* The LR case has to be handled a little differently...  */
  	.code 16
! 
! 	THUMB_FUNC_START _interwork_call_via_lr
! 
  	bx 	pc
  	nop
  	
*************** SYM (_interwork_call_via_lr):
*** 1069,1071 ****
--- 1080,1083 ----
  	SIZE	(_interwork_call_via_lr)
  	
  #endif /* L_interwork_call_via_rX */
+ 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]