This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
ARM/Thumb interworking supporting in libgcc.a
- To: gcc-patches at gcc dot gnu dot org
- Subject: ARM/Thumb interworking supporting in libgcc.a
- From: Nick Clifton <nickc at redhat dot com>
- Date: Thu, 10 Aug 2000 17:29:42 -0700
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 */
+