This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Compiling libgcc not optimized

Good moorning,

I am trying to compile libgcc for arm-none-eabi target from scratch, since I need to compare Floating Point SW emulation on an ARM Cortex-M4 and Risc-V based processors. The problem is that by default GCC includes the optimized version of FP SW emulation functions which is ieee754-sf.S. 

Does anyone knows how to exclude ieee754-sf.S in the libgcc compilation process? In particular how to configure GCC?

Thanks,

Parents
  • IANAE, but below is a hack one can try. No warranty of any kind.

    The asm sources for the optimized routines are collected inside the LIB1ASMFUNCS make variable.

    gccsrc/libgcc/Makefile.in has

    libgcc-objects += $(lib1asmfuncs-o)
    ...
    ...
    libgcc-s-objects += $(lib1asmfuncs-s-o)

    Comment the two lines to avoid including the optimized routines.

    The inclusion of softftp routines is controlled by gccsrc/libgcc/config/arm/t-softfp:

    softfp_wrap_start := '\#if !__ARM_ARCH_ISA_ARM && __ARM_ARCH_ISA_THUMB == 1'
    softfp_wrap_end := '\#endif'

    Change it to:

    softfp_wrap_start := '\#if 1'
    softfp_wrap_end := '\#endif'

    Build.


    Or, one may rely on utilizing -nostdlib on unmodified builds to prevent linking with -lgcc. You may also want to consult gcc dev's mailing lists.

Reply
  • IANAE, but below is a hack one can try. No warranty of any kind.

    The asm sources for the optimized routines are collected inside the LIB1ASMFUNCS make variable.

    gccsrc/libgcc/Makefile.in has

    libgcc-objects += $(lib1asmfuncs-o)
    ...
    ...
    libgcc-s-objects += $(lib1asmfuncs-s-o)

    Comment the two lines to avoid including the optimized routines.

    The inclusion of softftp routines is controlled by gccsrc/libgcc/config/arm/t-softfp:

    softfp_wrap_start := '\#if !__ARM_ARCH_ISA_ARM && __ARM_ARCH_ISA_THUMB == 1'
    softfp_wrap_end := '\#endif'

    Change it to:

    softfp_wrap_start := '\#if 1'
    softfp_wrap_end := '\#endif'

    Build.


    Or, one may rely on utilizing -nostdlib on unmodified builds to prevent linking with -lgcc. You may also want to consult gcc dev's mailing lists.

Children
  • Hi @a.surati, thanks for the answer. I tried your advice but unfortunately the result was negative. Using the new generated libgcc.a, from your solution, and compiling the source code of my application GCC gives the error: "undefined reference to __aeabi_fadd". It seems there are no more the optimized SP routines in libgcc.a, but the compiler is still using the names of the optimized routines. Instead of using __aeabi_fadd it should use addsf3, which the standard name. 

  • Okay. Those steps replaced the optimized code with the unoptimized one, afaics within the libgcc.a built.

    Additionally, libgcc.a and gcc compiler redefine __addsf3 to __aeabi_fadd. Such redefinitions are applied to other functions too.

    For the sake of testing a single function __addsf3, these additional changes (on top of earlier ones) were made:

    gccsrc/gcc/config/arm/arm.c has:
    ...
    set_optab_libfunc (add_optab, SFmode, "__aeabi_fadd");
    ...

    Comment that line.

    gccsrc/libgcc/config/arm/sfp-machine.h has at the end of the file:
    #ifdef __ARM_EABI__
    ...
    #endif


    Change the #ifdef to #ifdef 0.

    I only tested that gcc -c emitted __addsf3, and that libgcc.a had addsf3.0 with __addsf3 function inside it.

  • Edit: I had mistakenly built the a-profile toolchain, hence the mix of thumb and arm instructions for armv7e-m. The toolchain (built with the diff below) did work for compiling a small test program for armv7-a, as verified by running a statically built binary with qemu-arm.

    The diff remains as before, and is given below. I will attempt to build an arm-none-eabi with libgcc.a to see if the diff needs any changes.

    diff -ru org/gcc-10.2.0/gcc/config/arm/arm.c gcc-10.2.0/gcc/config/arm/arm.c
    --- org/gcc-10.2.0/gcc/config/arm/arm.c	2020-07-23 12:05:17.344384552 +0530
    +++ gcc-10.2.0/gcc/config/arm/arm.c	2020-11-26 12:50:11.121893412 +0530
    @@ -2531,6 +2531,7 @@
       /* For Linux, we have access to kernel support for atomic operations.  */
       if (arm_abi == ARM_ABI_AAPCS_LINUX)
         init_sync_libfuncs (MAX_SYNC_LIBFUNC_SIZE);
    +  return;
     
       /* There are no special library functions unless we are using the
          ARM BPABI.  */
    diff -ru org/gcc-10.2.0/libgcc/config/arm/sfp-machine.h gcc-10.2.0/libgcc/config/arm/sfp-machine.h
    --- org/gcc-10.2.0/libgcc/config/arm/sfp-machine.h	2020-07-23 12:05:18.752400064 +0530
    +++ gcc-10.2.0/libgcc/config/arm/sfp-machine.h	2020-11-26 13:31:10.565636471 +0530
    @@ -67,7 +67,7 @@
     # define _strong_alias(name, aliasname) \
       extern __typeof (name) aliasname __attribute__ ((alias (#name)));
     
    -#ifdef __ARM_EABI__
    +#if 0
     /* Rename functions to their EABI names.  */
     /* The comparison functions need wrappers for EABI semantics, so
        leave them unmolested.  */
    diff -ru org/gcc-10.2.0/libgcc/config/arm/t-arm gcc-10.2.0/libgcc/config/arm/t-arm
    --- org/gcc-10.2.0/libgcc/config/arm/t-arm	2020-07-23 12:05:18.752400064 +0530
    +++ gcc-10.2.0/libgcc/config/arm/t-arm	2020-11-26 12:18:01.909926794 +0530
    @@ -1,6 +1,7 @@
     LIB1ASMSRC = arm/lib1funcs.S
     LIB1ASMFUNCS = _thumb1_case_sqi _thumb1_case_uqi _thumb1_case_shi \
     	_thumb1_case_uhi _thumb1_case_si _speculation_barrier
    +LIB2ADD += $(srcdir)/udivmodsi4.c $(srcdir)/udivmod.c $(srcdir)/divmod.c
     
     HAVE_CMSE:=$(findstring __ARM_FEATURE_CMSE,$(shell $(gcc_compile_bare) -dM -E - </dev/null))
     HAVE_V81M:=$(findstring armv8.1-m.main,$(gcc_compile_bare))
    diff -ru org/gcc-10.2.0/libgcc/config/arm/t-softfp gcc-10.2.0/libgcc/config/arm/t-softfp
    --- org/gcc-10.2.0/libgcc/config/arm/t-softfp	2020-07-23 12:05:18.752400064 +0530
    +++ gcc-10.2.0/libgcc/config/arm/t-softfp	2020-11-26 13:28:39.584201073 +0530
    @@ -1,2 +1,3 @@
    -softfp_wrap_start := '\#if !__ARM_ARCH_ISA_ARM && __ARM_ARCH_ISA_THUMB == 1'
    +softfp_wrap_start := '\#if 1'
     softfp_wrap_end := '\#endif'
    +softfp_exclude_libgcc2 := n
    diff -ru org/gcc-10.2.0/libgcc/Makefile.in gcc-10.2.0/libgcc/Makefile.in
    --- org/gcc-10.2.0/libgcc/Makefile.in	2020-07-23 12:05:18.748400018 +0530
    +++ gcc-10.2.0/libgcc/Makefile.in	2020-11-26 13:30:50.989201425 +0530
    @@ -484,14 +484,14 @@
     	$(gcc_compile) -DL$* -xassembler-with-cpp -c $< -include $*.vis
     $(patsubst %,%.vis,$(LIB1ASMFUNCS)): %.vis: %_s$(objext)
     	$(gen-hide-list)
    -libgcc-objects += $(lib1asmfuncs-o)
    +#libgcc-objects += $(lib1asmfuncs-o)
     
     lib1asmfuncs-s-o = $(patsubst %,%_s$(objext),$(LIB1ASMFUNCS))
     $(lib1asmfuncs-s-o): %_s$(objext): $(srcdir)/config/$(LIB1ASMSRC)
     	$(gcc_s_compile) -DL$* -xassembler-with-cpp -c $<
     ifeq ($(enable_shared),yes)
     
    -libgcc-s-objects += $(lib1asmfuncs-s-o)
    +#libgcc-s-objects += $(lib1asmfuncs-s-o)
     
     endif
     
    diff -ru org/gcc-10.2.0/libsanitizer/asan/asan_linux.cpp gcc-10.2.0/libsanitizer/asan/asan_linux.cpp
    --- org/gcc-10.2.0/libsanitizer/asan/asan_linux.cpp	2020-07-23 12:05:19.124404163 +0530
    +++ gcc-10.2.0/libsanitizer/asan/asan_linux.cpp	2020-11-26 07:06:35.712906746 +0530
    @@ -199,7 +199,9 @@
         Die();
       }
     }
    -
    +#ifndef PATH_MAX
    +#define PATH_MAX 1024
    +#endif
     void AsanCheckIncompatibleRT() {
       if (ASAN_DYNAMIC) {
         if (__asan_rt_version == ASAN_RT_VERSION_UNDEFINED) {

  • Fixed the diff and the build.

    diff -ru gcc-10.2.0.org/gcc/config/arm/arm.c gcc-10.2.0/gcc/config/arm/arm.c
    --- gcc-10.2.0.org/gcc/config/arm/arm.c	2020-07-23 12:05:17.344384552 +0530
    +++ gcc-10.2.0/gcc/config/arm/arm.c	2020-11-27 10:31:23.706272741 +0530
    @@ -2527,7 +2527,7 @@
     arm_init_libfuncs (void)
     {
       machine_mode mode_iter;
    -
    +  return;
       /* For Linux, we have access to kernel support for atomic operations.  */
       if (arm_abi == ARM_ABI_AAPCS_LINUX)
         init_sync_libfuncs (MAX_SYNC_LIBFUNC_SIZE);
    diff -ru gcc-10.2.0.org/libgcc/config/arm/sfp-machine.h gcc-10.2.0/libgcc/config/arm/sfp-machine.h
    --- gcc-10.2.0.org/libgcc/config/arm/sfp-machine.h	2020-07-23 12:05:18.752400064 +0530
    +++ gcc-10.2.0/libgcc/config/arm/sfp-machine.h	2020-11-27 10:31:23.712939386 +0530
    @@ -67,7 +67,7 @@
     # define _strong_alias(name, aliasname) \
       extern __typeof (name) aliasname __attribute__ ((alias (#name)));
     
    -#ifdef __ARM_EABI__
    +#if 0
     /* Rename functions to their EABI names.  */
     /* The comparison functions need wrappers for EABI semantics, so
        leave them unmolested.  */
    diff -ru gcc-10.2.0.org/libgcc/config/arm/t-arm gcc-10.2.0/libgcc/config/arm/t-arm
    --- gcc-10.2.0.org/libgcc/config/arm/t-arm	2020-07-23 12:05:18.752400064 +0530
    +++ gcc-10.2.0/libgcc/config/arm/t-arm	2020-11-27 10:31:23.719606030 +0530
    @@ -1,7 +1,7 @@
     LIB1ASMSRC = arm/lib1funcs.S
     LIB1ASMFUNCS = _thumb1_case_sqi _thumb1_case_uqi _thumb1_case_shi \
     	_thumb1_case_uhi _thumb1_case_si _speculation_barrier
    -
    +LIB2ADD += $(srcdir)/udivmodsi4.c $(srcdir)/udivmod.c $(srcdir)/divmod.c
     HAVE_CMSE:=$(findstring __ARM_FEATURE_CMSE,$(shell $(gcc_compile_bare) -dM -E - </dev/null))
     HAVE_V81M:=$(findstring armv8.1-m.main,$(gcc_compile_bare))
     ifeq ($(shell $(gcc_compile_bare) -E -mcmse - </dev/null >/dev/null 2>/dev/null; echo $?),0)
    diff -ru gcc-10.2.0.org/libgcc/config/arm/t-softfp gcc-10.2.0/libgcc/config/arm/t-softfp
    --- gcc-10.2.0.org/libgcc/config/arm/t-softfp	2020-07-23 12:05:18.752400064 +0530
    +++ gcc-10.2.0/libgcc/config/arm/t-softfp	2020-11-27 10:31:23.722939352 +0530
    @@ -1,2 +1,3 @@
    -softfp_wrap_start := '\#if !__ARM_ARCH_ISA_ARM && __ARM_ARCH_ISA_THUMB == 1'
    +softfp_wrap_start := '\#if 1'
     softfp_wrap_end := '\#endif'
    +softfp_exclude_libgcc2 := n
    diff -ru gcc-10.2.0.org/libgcc/Makefile.in gcc-10.2.0/libgcc/Makefile.in
    --- gcc-10.2.0.org/libgcc/Makefile.in	2020-07-23 12:05:18.748400018 +0530
    +++ gcc-10.2.0/libgcc/Makefile.in	2020-11-27 11:10:24.692592239 +0530
    @@ -471,29 +471,14 @@
     # Remove any objects from lib2funcs and LIB2_DIVMOD_FUNCS that are
     # defined as optimized assembly code in LIB1ASMFUNCS or as C code
     # in LIB2FUNCS_EXCLUDE.
    -lib2funcs := $(filter-out $(LIB2FUNCS_EXCLUDE) $(LIB1ASMFUNCS),$(lib2funcs))
    -LIB2_DIVMOD_FUNCS := $(filter-out $(LIB2FUNCS_EXCLUDE) $(LIB1ASMFUNCS), \
    +lib2funcs := $(filter-out $(LIB2FUNCS_EXCLUDE),$(lib2funcs))
    +LIB2_DIVMOD_FUNCS := $(filter-out $(LIB2FUNCS_EXCLUDE), \
     		       $(LIB2_DIVMOD_FUNCS))
     
     LIB2FUNCS_ST := $(filter-out $(LIB2FUNCS_EXCLUDE),$(LIB2FUNCS_ST))
     
     # Build "libgcc1" (assembly) components.
     
    -lib1asmfuncs-o = $(patsubst %,%$(objext),$(LIB1ASMFUNCS))
    -$(lib1asmfuncs-o): %$(objext): $(srcdir)/config/$(LIB1ASMSRC) %.vis
    -	$(gcc_compile) -DL$* -xassembler-with-cpp -c $< -include $*.vis
    -$(patsubst %,%.vis,$(LIB1ASMFUNCS)): %.vis: %_s$(objext)
    -	$(gen-hide-list)
    -libgcc-objects += $(lib1asmfuncs-o)
    -
    -lib1asmfuncs-s-o = $(patsubst %,%_s$(objext),$(LIB1ASMFUNCS))
    -$(lib1asmfuncs-s-o): %_s$(objext): $(srcdir)/config/$(LIB1ASMSRC)
    -	$(gcc_s_compile) -DL$* -xassembler-with-cpp -c $<
    -ifeq ($(enable_shared),yes)
    -
    -libgcc-s-objects += $(lib1asmfuncs-s-o)
    -
    -endif
     
     # Build lib2funcs.  For the static library also include LIB2FUNCS_ST.
     lib2funcs-o = $(patsubst %,%$(objext),$(lib2funcs) $(LIB2FUNCS_ST))

    With soft-float toolchain:

    void _start(){double a,b=20,c=3;a=b+c;a=b/c;for(;;);}
    
    
    arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=soft -c a.c
    arm-none-eabi-ld a.o -L /home/user/tools/cross/lib/gcc/arm-none-eabi/10.2.0/thumb -lgcc
    qemu-arm a.out # should loop forever
    
    00008000 <_start>:
        8000:	b580      	push	{r7, lr}
        8002:	b086      	sub	sp, #24
        8004:	af00      	add	r7, sp, #0
    ...
        8022:	f000 f813 	bl	804c <__adddf3>
    ...
        8036:	f000 fb25 	bl	8684 <__divdf3>
    ...
    
    
    0000804c <__adddf3>:
        804c:	e92d 43f0 	stmdb	sp!, {r4, r5, r6, r7, r8, r9, lr}
        8050:	4696      	mov	lr, r2
        8052:	461a      	mov	r2, r3
        8054:	f3c1 0613 	ubfx	r6, r1, #0, #20
    ...
    
    
    00008684 <__divdf3>:
        8684:	e92d 4ff0 	stmdb	sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
        8688:	460c      	mov	r4, r1
        868a:	4605      	mov	r5, r0
        868c:	f3c4 560a 	ubfx	r6, r4, #20, #11    
    ...

  • Hi . I have tried your solution, but it implies building from scratch the arm-none-eabi-gcc toolchain. I would like to build the not-optimized libgcc version and deploy it with a pre-built toolchain. Why? because I am using the STM32Cube IDE to measure the performance of some benchmarks running on ARM Cortex-M4 based STM board. Deploying a new GCC toolchain makes it hard. Changing libgcc.a is easy, but changing the toolchain not.
    Do you think is it possible to do it with a work around?
    Sadly I guess not, since your solution make changes in the GCC back-end...

  • One doesn't need to build the entire toolchain - for e.g. binutils can remain as they are. The diff changes gcc and libgcc.a, so these two components need rebuilding.

    but the compiler is still using the names of the optimized routines.

    The arm-none-eabi-gcc needs to be changed if it is expected to not use the names of the optimized routines. This step is accomplished by the change in the arm.c file. The rest of the changes are all inside libgcc.

    I would like to build the not-optimized libgcc version and deploy it with a pre-built toolchain

    If the arm-none-eabi-gcc isn't changed, it will emit the names of the optimized routines.

    Assuming that we are okay with using the optimized labels for unoptimized code, you can try to build libgcc.a with the same diff posted last, but ignoring the changes to sfp-machine.h and arm.c files. This ensures that arm-none-eabi-gcc remains untouched, and that libgcc.a complies with the labels that arm-none-eabi-gcc emits by default. Then, you don't have to build anything other than libgcc.a.

    The result might look like so:

    00008000 <_start>:
        8000:	b580      	push	{r7, lr}
        8002:	b086      	sub	sp, #24
        8004:	af00      	add	r7, sp, #0
    ...
        8022:	f000 f813 	bl	804c <__aeabi_dadd>
    ...
        8036:	f000 fb25 	bl	8684 <__aeabi_ddiv>
    ...
    
    
    
    0000804c <__aeabi_dadd>:
        804c:	e92d 43f0 	stmdb	sp!, {r4, r5, r6, r7, r8, r9, lr}
        8050:	4696      	mov	lr, r2
        8052:	461a      	mov	r2, r3
        8054:	f3c1 0613 	ubfx	r6, r1, #0, #20
    ...
    
    00008684 <__aeabi_ddiv>:
        8684:	e92d 4ff0 	stmdb	sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
        8688:	460c      	mov	r4, r1
        868a:	4605      	mov	r5, r0
        868c:	f3c4 560a 	ubfx	r6, r4, #20, #11
    ...

    Labels of the optimized routines, with actual unoptimized code underneath.

  • I have tried your solution, but disassembling libgcc.a there is no function with optimized or unoptimized labels only:

    addsf3.o:     file format elf32-littlearm
    
    
    divsf3.o:     file format elf32-littlearm
    
    
    eqsf2.o:     file format elf32-littlearm
    
    
    gesf2.o:     file format elf32-littlearm
    
    
    lesf2.o:     file format elf32-littlearm
    
    
    mulsf3.o:     file format elf32-littlearm
    
    
    negsf2.o:     file format elf32-littlearm
    
    
    subsf3.o:     file format elf32-littlearm
    
    
    unordsf2.o:     file format elf32-littlearm
    
    
    fixsfsi.o:     file format elf32-littlearm
    
    
    fixunssfsi.o:     file format elf32-littlearm

    To recap what I did is:

    • Cloning GCC 11.0.0 repository
    • inside a build directory configure with the following line command:

    ./../configure --target=arm-none-eabi  CC_FOR_TARGET=/opt/st/stm32cubeide_1.4.0_2/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.linux64_1.4.0.202007081208/tools/bin/arm-none-eabi-gcc-7.3.1 AR_FOR_TARGET=/opt/st/stm32cubeide_1.4.0_2/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.linux64_1.4.0.202007081208/tools/bin/arm-none-eabi-gcc-ar --prefix=/home/enrico/Desktop/gcc/build/install/ --with-multilib --with-multilib-list=rmprofile

    • make your changes, this is the diff:

    diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
    index d6075d3..f3885c9 100644
    --- a/libgcc/Makefile.in
    +++ b/libgcc/Makefile.in
    @@ -471,29 +471,29 @@ LIB2_DIVMOD_FUNCS = _divdi3 _moddi3 _divmoddi4 \
     # Remove any objects from lib2funcs and LIB2_DIVMOD_FUNCS that are
     # defined as optimized assembly code in LIB1ASMFUNCS or as C code
     # in LIB2FUNCS_EXCLUDE.
    -lib2funcs := $(filter-out $(LIB2FUNCS_EXCLUDE) $(LIB1ASMFUNCS),$(lib2funcs))
    -LIB2_DIVMOD_FUNCS := $(filter-out $(LIB2FUNCS_EXCLUDE) $(LIB1ASMFUNCS), \
    +lib2funcs := $(filter-out $(LIB2FUNCS_EXCLUDE) ,$(lib2funcs))
    +LIB2_DIVMOD_FUNCS := $(filter-out $(LIB2FUNCS_EXCLUDE), \
     		       $(LIB2_DIVMOD_FUNCS))
     
     LIB2FUNCS_ST := $(filter-out $(LIB2FUNCS_EXCLUDE),$(LIB2FUNCS_ST))
     
     # Build "libgcc1" (assembly) components.
     
    -lib1asmfuncs-o = $(patsubst %,%$(objext),$(LIB1ASMFUNCS))
    -$(lib1asmfuncs-o): %$(objext): $(srcdir)/config/$(LIB1ASMSRC) %.vis
    -	$(gcc_compile) -DL$* -xassembler-with-cpp -c $< -include $*.vis
    -$(patsubst %,%.vis,$(LIB1ASMFUNCS)): %.vis: %_s$(objext)
    -	$(gen-hide-list)
    -libgcc-objects += $(lib1asmfuncs-o)
    +# lib1asmfuncs-o = $(patsubst %,%$(objext),$(LIB1ASMFUNCS))
    +# $(lib1asmfuncs-o): %$(objext): $(srcdir)/config/$(LIB1ASMSRC) %.vis
    +# 	$(gcc_compile) -DL$* -xassembler-with-cpp -c $< -include $*.vis
    +# $(patsubst %,%.vis,$(LIB1ASMFUNCS)): %.vis: %_s$(objext)
    +# 	$(gen-hide-list)
    +# libgcc-objects += $(lib1asmfuncs-o)
     
    -lib1asmfuncs-s-o = $(patsubst %,%_s$(objext),$(LIB1ASMFUNCS))
    -$(lib1asmfuncs-s-o): %_s$(objext): $(srcdir)/config/$(LIB1ASMSRC)
    -	$(gcc_s_compile) -DL$* -xassembler-with-cpp -c $<
    -ifeq ($(enable_shared),yes)
    +# lib1asmfuncs-s-o = $(patsubst %,%_s$(objext),$(LIB1ASMFUNCS))
    +# $(lib1asmfuncs-s-o): %_s$(objext): $(srcdir)/config/$(LIB1ASMSRC)
    +# 	$(gcc_s_compile) -DL$* -xassembler-with-cpp -c $<
    +# ifeq ($(enable_shared),yes)
     
    -libgcc-s-objects += $(lib1asmfuncs-s-o)
    +# libgcc-s-objects += $(lib1asmfuncs-s-o)
     
    -endif
    +# endif
     
     # Build lib2funcs.  For the static library also include LIB2FUNCS_ST.
     lib2funcs-o = $(patsubst %,%$(objext),$(lib2funcs) $(LIB2FUNCS_ST))
    diff --git a/libgcc/config/arm/t-arm b/libgcc/config/arm/t-arm
    index 364f40e..8c98dd6 100644
    --- a/libgcc/config/arm/t-arm
    +++ b/libgcc/config/arm/t-arm
    @@ -2,6 +2,8 @@ LIB1ASMSRC = arm/lib1funcs.S
     LIB1ASMFUNCS = _thumb1_case_sqi _thumb1_case_uqi _thumb1_case_shi \
     	_thumb1_case_uhi _thumb1_case_si _speculation_barrier
     
    +LIB2ADD += $(srcdir)/udivmodsi4.c $(srcdir)/udivmod.c $(srcdir)/divmod.c
    +
     HAVE_CMSE:=$(findstring __ARM_FEATURE_CMSE,$(shell $(gcc_compile_bare) -dM -E - </dev/null))
     HAVE_V81M:=$(findstring armv8.1-m.main,$(gcc_compile_bare))
     ifeq ($(shell $(gcc_compile_bare) -E -mcmse - </dev/null >/dev/null 2>/dev/null; echo $?),0)
    diff --git a/libgcc/config/arm/t-softfp b/libgcc/config/arm/t-softfp
    index 554ec9b..ef862a9 100644
    --- a/libgcc/config/arm/t-softfp
    +++ b/libgcc/config/arm/t-softfp
    @@ -1,2 +1,3 @@
    -softfp_wrap_start := '\#if !__ARM_ARCH_ISA_ARM && __ARM_ARCH_ISA_THUMB == 1'
    +softfp_wrap_start := '\#if 1'
     softfp_wrap_end := '\#endif'
    +softfp_exclude_libgcc2 := n
    \ No newline at end of file
    

    • Then make all-target-libgcc and install-target-libgcc
    • Inside the install folder there are several libgcc built for different target and i take the one for the v7e-m

    Anyway there is still something missing...

    Enrico,

    Thanks

  • Cloning GCC 11.0.0 repository

    How old is the toolchain's compiler? Trying to build libgcc.a from gcc-11.0.0 using gcc-7.3.1 might not work. The arm-none-eabi-gcc version 7.3.1 doesn't understand:

    -Wno-error=format-diag
    #pragma GCC target ("general-regs-only")

    etc. that are in the gcc-10.2.0 source. The build fails.


    Even though CC_FOR_TARGET is specified, the configuration insists on building the compiler and using this in-tree, freshly built compiler for building libgcc.a

    That can be seen in the configuration messages:

    checking where to find the target as... pre-installed
    checking where to find the target cc... just compiled
    checking where to find the target gcc... just compiled

    and inside the gcc/configure script:

      if test $ok = yes; then
        # An in-tree tool is available and we can use it
        CC_FOR_TARGET='$$r/$(HOST_SUBDIR)/gcc/xgcc -B$$r/$(HOST_SUBDIR)/gcc/'
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: just compiled" >&5
    $as_echo "just compiled" >&6; }


    It seems that libgcc.a wants to be built with the in-tree compiler.

    If you allow that, then libgcc.a from gcc-11.0.0 can be built using the in-tree gcc-11.0.0 compiler (which the build process first builds).

    If you don't allow that, then ensure that the source code corresponds to the prebuilt toolchain version you want to use. This resolves the errors about unsupported code fragments.

    But it still compiles libgcc.a using the in-tree compiler and not using the prebuilt toolchain's compiler. To achieve that, a change must be made inside gcc/configure file; that change is shown some lines below.


    st couldn't download st-stm32cubeide_1-5-0_8698_20201117_1050_amd64_sh.zip for me; threw a 504 Gateway timeout.

    So decided to use "GNU Arm Embedded Toolchain: Version 7-2018-q2-update" from Arm instead, which seems to be the one on which the st's toolchain is based:

    gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2
    gcc-arm-none-eabi-7-2018-q2-update-src.tar.bz2


    Test with unmodified prebuilt toolchain:

    # Extract the prebuilt toolchain as /home/user/prebuilt
    
    arm-none-eabi-gcc -nostdlib -mcpu=cortex-m4 -mthumb -mfloat-abi=soft a.c -lgcc -Wl,-cref
    
    Cross Reference Table
    
    Symbol          File
    __adddf3		/home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(_arm_addsubdf3.o)
    __aeabi_dadd	/home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(_arm_addsubdf3.o)
                    /tmp/cc6LutZe.o
    __aeabi_ddiv	/home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(_arm_muldivdf3.o)
                    /tmp/cc6LutZe.o
    __aeabi_dmul	/home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(_arm_muldivdf3.o)
    __aeabi_drsub   /home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(_arm_addsubdf3.o)
    __aeabi_dsub    /home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(_arm_addsubdf3.o)
    __aeabi_f2d     /home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(_arm_addsubdf3.o)
    __aeabi_i2d     /home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(_arm_addsubdf3.o)
    __aeabi_l2d     /home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(_arm_addsubdf3.o)
    __aeabi_ui2d    /home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(_arm_addsubdf3.o)
    __aeabi_ul2d    /home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(_arm_addsubdf3.o)
    __divdf3        /home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(_arm_muldivdf3.o)
    __extendsfdf2   /home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(_arm_addsubdf3.o)
    __floatdidf     /home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(_arm_addsubdf3.o)
    __floatsidf     /home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(_arm_addsubdf3.o)
    __floatundidf   /home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(_arm_addsubdf3.o)
    __floatunsidf   /home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(_arm_addsubdf3.o)
    __muldf3        /home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(_arm_muldivdf3.o)
    __subdf3        /home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(_arm_addsubdf3.o)
    _start          /tmp/cc6LutZe.o
    
    
    strings -a a.out | grep GCC:
    GCC: (GNU Tools for Arm Embedded Processors 7-2018-q2-update) 7.3.1 20180622 (release) [ARM/embedded-7-branch revision 261907]
    
    
    # Dissasembly snippets. You can confirm that these are optimized by
    # comparing them with the ieee754-df.S file
    00008000 <_start>:
        8022:	f000 f819 	bl	8058 <__adddf3>
        8036:	f000 faef 	bl	8618 <__aeabi_ddiv>
    00008058 <__adddf3>:
        8082:	ea4f 5454 	mov.w	r4, r4, lsr #21
        8086:	ebd4 5555 	rsbs	r5, r4, r5, lsr #21
        808a:	bfb8      	it	lt
        808c:	426d      	neglt	r5, r5
        808e:	dd0c      	ble.n	80aa <__adddf3+0x52>
        8090:	442c      	add	r4, r5
        8092:	ea80 0202 	eor.w	r2, r0, r2
        8096:	ea81 0303 	eor.w	r3, r1, r3
        809a:	ea82 0000 	eor.w	r0, r2, r0
        809e:	ea83 0101 	eor.w	r1, r3, r1
        80a2:	ea80 0202 	eor.w	r2, r0, r2
        80a6:	ea81 0303 	eor.w	r3, r1, r3
    00008618 <__aeabi_ddiv>:
        864c:	ea4f 3303 	mov.w	r3, r3, lsl #12
        8650:	f04f 5580 	mov.w	r5, #268435456	; 0x10000000
        8654:	ea45 1313 	orr.w	r3, r5, r3, lsr #4
        8658:	ea43 6312 	orr.w	r3, r3, r2, lsr #24
        865c:	ea4f 2202 	mov.w	r2, r2, lsl #8
        8660:	ea45 1511 	orr.w	r5, r5, r1, lsr #4
        8664:	ea45 6510 	orr.w	r5, r5, r0, lsr #24
        8668:	ea4f 2600 	mov.w	r6, r0, lsl #8


    Build libgcc.a

    # gcc has the source of the compiler included in the toolchain
    
    cd gcc
    ./contrib/download_prerequisites
    
    # Now apply the diff/patch to libgcc files
    
    # Modify gcc/configure.
    
    $as_echo_n "checking where to find the target cc... " >&6; }
    ...
    else
      ok=yes # <----- change this to no
      case " ${configdirs} " in
    ...
    $as_echo_n "checking where to find the target gcc... " >&6; }
    ...
    else
      ok=yes # <----- change this to no
      case " ${configdirs} " in
    ...
    
    # If this change isn't made, the libgcc.a will be built with the freshly
    # built compiler, not with the one shipped with the prebuilt toolchain.
    # That may not create problems, so this is another option available if
    # it is okay to build libgcc.a with the freshly built complier, given that
    # the gcc source used corresponds to the toolchain.
    
    # With this change, the in-tree gcc compiler will still be
    # built (so some time is wasted on it), but libgcc.a will be built using
    # the compiler shipped with the prebuilt toolchain.
    
    
    export PATH=$PATH:/home/user/prebuilt/bin
    mkdir ./build
    cd ./build
    
    ../gcc/configure \
    CC_FOR_TARGET=arm-none-eabi-gcc \
    GCC_FOR_TARGET=arm-none-eabi-gcc \
    --target=arm-none-eabi --prefix=/home/user/cross \
    --with-multilib --with-multilib-list=rmprofile --enable-languages=c
    
    make all-target-libgcc && make install-strip-target-libgcc
    
    # The build will still make a fresh gcc, but it will use the prebuilt's
    # gcc when building the libgcc.a. Confirm that by reading the build output/
    # config logs. The prefix/installation directory contains only the lib
    # directory and no binaries.


    Test the new libgcc.a

    # Copy
    # /home/user/cross/lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a
    # to
    # /home/user/prebuilt/lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a
    
    # Build the sample again with prebuilt's compiler
    arm-none-eabi-gcc -nostdlib -mcpu=cortex-m4 -mthumb -mfloat-abi=soft a.c -lgcc -Wl,-cref
    Cross Reference Table
    
    Symbol          File
    __aeabi_dadd    /home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(adddf3.o)
                    /tmp/ccF8QeNy.o
    __aeabi_ddiv    /home/user/prebuilt/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/libgcc.a(divdf3.o)
                    /tmp/ccF8QeNy.o
    _start          /tmp/ccF8QeNy.o
    
    strings -a a.out | grep GCC:
    GCC: (GNU Tools for Arm Embedded Processors 7-2018-q2-update) 7.3.1 20180622 (release) [ARM/embedded-7-branch revision 261907]
    
    # Dissasembly snippets. Not the same as optimized ones above.
    00008000 <_start>:
        8022:	f000 f813 	bl	804c <__aeabi_dadd>
        8036:	f000 fb1b 	bl	8670 <__aeabi_ddiv>
    0000804c <__aeabi_dadd>:
        804c:	e92d 43f0 	stmdb	sp!, {r4, r5, r6, r7, r8, r9, lr}
        8050:	0fcf      	lsrs	r7, r1, #31
        8052:	ea4f 7ed3 	mov.w	lr, r3, lsr #31
        8056:	f3c1 0513 	ubfx	r5, r1, #0, #20
    00008670 <__aeabi_ddiv>:
        8670:	e92d 4ff0 	stmdb	sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
        8674:	f3c1 560a 	ubfx	r6, r1, #20, #11
        8678:	f3c1 0413 	ubfx	r4, r1, #0, #20
        867c:	4605      	mov	r5, r0