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,
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 a.surati. 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.
EnricoTabanelli said: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.
EnricoTabanelli said: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:
./../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
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
Anyway there is still something missing...
Enrico,
Thanks
EnricoTabanelli said: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.aThat 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.bz2gcc-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