[PATCH, libgcc/ARM & testsuite] Optimize executable size when using softfloat fmul/dmul

Richard Earnshaw (lists) Richard.Earnshaw@arm.com
Fri Dec 7 14:14:00 GMT 2018


On 19/11/2018 09:57, Thomas Preudhomme wrote:
> Softfloat single precision and double precision floating-point
> multiplication routines in libgcc share some code with the
> floating-point division of their corresponding precision. As the code
> is structured now, this leads to *all* division code being pulled in an
> executable in softfloat mode even if only multiplication is
> performed.
> 
> This patch create some new LIB1ASMFUNCS macros to also build files with
> just the multiplication and shared code as weak symbols. By putting
> these earlier in the static library, they can then be picked up when
> only multiplication is used and they are overriden by the global
> definition in the existing file containing both multiplication and
> division code when division is needed.
> 
> The patch also removes changes made to the FUNC_START and ARM_FUNC_START
> macros in r218124 since the intent was to put multiplication and
> division code into their own section in a later patch to achieve the
> same size optimization. That approach relied on specific section layout
> to ensure multiplication and division were not too far from the shared
> bit of code in order to the branches to be within range. Due to lack of
> guarantee regarding section layout, in particular with all the
> possibility of linker scripts, this approach was chosen instead. This
> patch keeps the two testcases that were posted by Tony Wang (an Arm
> employee at the time) on the mailing list to implement this approach
> and adds a new one, hence the attribution.
> 
> ChangeLog entries are as follows:
> 
> *** gcc/ChangeLog ***
> 
> 2018-11-14  Thomas Preud'homme  <thomas.preudhomme@linaro.org>
> 
>     * config/arm/elf.h: Update comment about condition that need to
>     match with libgcc/config/arm/lib1funcs.S to also include
>     libgcc/config/arm/t-arm.
>     * doc/sourcebuild.texi (output-exists, output-exists-not): Rename
>     subsubsection these directives are in to "Check for output files".
>     Move scan-symbol to that section and add to it new scan-symbol-not
>     directive.
> 
> *** gcc/testsuite/ChangeLog ***
> 
> 2018-11-16  Tony Wang  <tony.wang@arm.com>
>         Thomas Preud'homme  <thomas.preudhomme@linaro.org>
> 
>     * lib/lto.exp (lto-execute): Define output_file and testname_with_flags
>     to same value as execname.
>     (scan-symbol): Move and rename to ...
>     * lib/gcc-dg.exp (scan-symbol-common): This.  Adapt into a
>     helper function returning true or false if a symbol is present.
>     (scan-symbol): New procedure.
>     (scan-symbol-not): Likewise.
>     * gcc.target/arm/size-optimization-ieee-1.c: New testcase.
>     * gcc.target/arm/size-optimization-ieee-2.c: Likewise.
>     * gcc.target/arm/size-optimization-ieee-3.c: Likewise.
> 
> *** libgcc/ChangeLog ***
> 
> 2018-11-16  Thomas Preud'homme  <thomas.preudhomme@linaro.org>
> 
>     * /config/arm/lib1funcs.S (FUNC_START): Remove unused sp_section
>     parameter and corresponding code.
>     (ARM_FUNC_START): Likewise in both definitions.
>     Also update footer comment about condition that need to match with
>     gcc/config/arm/elf.h to also include libgcc/config/arm/t-arm.
>     * config/arm/ieee754-df.S (muldf3): Also build it if L_arm_muldf3 is
>     defined.  Weakly define it in this case.
>     * config/arm/ieee754-sf.S (mulsf3): Likewise with L_arm_mulsf3.
>     * config/arm/t-elf (LIB1ASMFUNCS): Build _arm_muldf3.o and
>     _arm_mulsf3.o before muldiv versions if targeting Thumb-1 only. Add
>     comment to keep condition in sync with the one in
>     libgcc/config/arm/lib1funcs.S and gcc/config/arm/elf.h.
> 
> Testing: Bootstrapped on arm-linux-gnueabihf (Arm & Thumb-2) and
> testsuite shows no
> regression. Also built an arm-none-eabi cross compiler targeting
> soft-float which also shows no regression. In particular newly added
> tests and gcc.dg/lto/20081212-1 test pass.

Which non-elf targets have you tested?

R.

> 
> Is this ok for stage3?
> 
> Best regards,
> 
> Thomas
> 
> 
> Optimize-size-fpmul_without_div.patch
> 
> From 8740697791f99b7175e188f049663883c39e51b0 Mon Sep 17 00:00:00 2001
> From: Thomas Preud'homme <thomas.preudhomme@linaro.org>
> Date: Fri, 26 Oct 2018 16:21:09 +0100
> Subject: [PATCH] [PATCH, libgcc/ARM] Optimize executable size when using
>  softfloat fmul/dmul
> 
> Softfloat single precision and double precision floating-point
> multiplication routines in libgcc share some code with the
> floating-point division of their corresponding precision. As the code
> is structured now, this leads to *all* division code being pulled in an
> executable in softfloat mode even if only multiplication is
> performed.
> 
> This patch create some new LIB1ASMFUNCS macros to also build files with
> just the multiplication and shared code as weak symbols. By putting
> these earlier in the static library, they can then be picked up when
> only multiplication is used and they are overriden by the global
> definition in the existing file containing both multiplication and
> division code when division is needed.
> 
> The patch also removes changes made to the FUNC_START and ARM_FUNC_START
> macros in r218124 since the intent was to put multiplication and
> division code into their own section in a later patch to achieve the
> same size optimization. That approach relied on specific section layout
> to ensure multiplication and division were not too far from the shared
> bit of code in order to the branches to be within range. Due to lack of
> guarantee regarding section layout, in particular with all the
> possibility of linker scripts, this approach was chosen instead. This
> patch keeps the two testcases that were posted by Tony Wang (an Arm
> employee at the time) on the mailing list to implement this approach
> and adds a new one, hence the attribution.
> 
> ChangeLog entries are as follows:
> 
> *** gcc/ChangeLog ***
> 
> 2018-11-14  Thomas Preud'homme  <thomas.preudhomme@linaro.org>
> 
> 	* config/arm/elf.h: Update comment about condition that need to
> 	match with libgcc/config/arm/lib1funcs.S to also include
> 	libgcc/config/arm/t-arm.
> 	* doc/sourcebuild.texi (output-exists, output-exists-not): Rename
> 	subsubsection these directives are in to "Check for output files".
> 	Move scan-symbol to that section and add to it new scan-symbol-not
> 	directive.
> 
> *** gcc/testsuite/ChangeLog ***
> 
> 2018-11-16  Tony Wang  <tony.wang@arm.com>
> 	    Thomas Preud'homme  <thomas.preudhomme@linaro.org>
> 
> 	* lib/lto.exp (lto-execute): Define output_file and testname_with_flags
> 	to same value as execname.
> 	(scan-symbol): Move and rename to ...
> 	* lib/gcc-dg.exp (scan-symbol-common): This.  Adapt into a
> 	helper function returning true or false if a symbol is present.
> 	(scan-symbol): New procedure.
> 	(scan-symbol-not): Likewise.
> 	* gcc.target/arm/size-optimization-ieee-1.c: New testcase.
> 	* gcc.target/arm/size-optimization-ieee-2.c: Likewise.
> 	* gcc.target/arm/size-optimization-ieee-3.c: Likewise.
> 
> *** libgcc/ChangeLog ***
> 
> 2018-11-16  Thomas Preud'homme  <thomas.preudhomme@linaro.org>
> 
> 	* /config/arm/lib1funcs.S (FUNC_START): Remove unused sp_section
> 	parameter and corresponding code.
> 	(ARM_FUNC_START): Likewise in both definitions.
> 	Also update footer comment about condition that need to match with
> 	gcc/config/arm/elf.h to also include libgcc/config/arm/t-arm.
> 	* config/arm/ieee754-df.S (muldf3): Also build it if L_arm_muldf3 is
> 	defined.  Weakly define it in this case.
> 	* config/arm/ieee754-sf.S (mulsf3): Likewise with L_arm_mulsf3.
> 	* config/arm/t-elf (LIB1ASMFUNCS): Build _arm_muldf3.o and
> 	_arm_mulsf3.o before muldiv versions if targeting Thumb-1 only. Add
> 	comment to keep condition in sync with the one in
> 	libgcc/config/arm/lib1funcs.S and gcc/config/arm/elf.h.
> 
> Testing: Bootstrapped on arm-linux-gnueabihf and testsuite shows no
> regression. Also built an arm-none-eabi cross compiler targeting
> soft-float which also shows no regression. In particular newly added
> tests and gcc.dg/lto/20081212-1 test pass.
> 
> Is this ok for stage3?
> 
> Best regards,
> 
> Thomas
> ---
>  gcc/config/arm/elf.h                          |  2 +-
>  gcc/doc/sourcebuild.texi                      |  9 +--
>  .../gcc.target/arm/size-optimization-ieee-1.c | 33 ++++++++
>  .../gcc.target/arm/size-optimization-ieee-2.c | 31 ++++++++
>  .../gcc.target/arm/size-optimization-ieee-3.c | 33 ++++++++
>  gcc/testsuite/lib/gcc-dg.exp                  | 76 +++++++++++++++++++
>  gcc/testsuite/lib/lto.exp                     | 63 +++------------
>  libgcc/config/arm/ieee754-df.S                | 17 ++++-
>  libgcc/config/arm/ieee754-sf.S                | 16 +++-
>  libgcc/config/arm/lib1funcs.S                 | 19 ++---
>  libgcc/config/arm/t-elf                       | 16 ++++
>  11 files changed, 243 insertions(+), 72 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/arm/size-optimization-ieee-1.c
>  create mode 100644 gcc/testsuite/gcc.target/arm/size-optimization-ieee-2.c
>  create mode 100644 gcc/testsuite/gcc.target/arm/size-optimization-ieee-3.c
> 
> diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h
> index ad3651ba841..1e00e99afc6 100644
> --- a/gcc/config/arm/elf.h
> +++ b/gcc/config/arm/elf.h
> @@ -137,7 +137,7 @@
>  
>  /* Horrible hack: We want to prevent some libgcc routines being included
>     for some multilibs.  The condition should match the one in
> -   libgcc/config/arm/lib1funcs.S.  */
> +   libgcc/config/arm/lib1funcs.S and libgcc/config/arm/t-elf.  */
>  #if __ARM_ARCH_ISA_ARM || __ARM_ARCH_ISA_THUMB != 1
>  #undef L_fixdfsi
>  #undef L_fixunsdfsi
> diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
> index 89157079ffb..9bf59b81d87 100644
> --- a/gcc/doc/sourcebuild.texi
> +++ b/gcc/doc/sourcebuild.texi
> @@ -2638,7 +2638,7 @@ Passes if @var{regex} does not match demangled text in the dump file with
>  suffix @var{suffix}.
>  @end table
>  
> -@subsubsection Verify that an output files exists or not
> +@subsubsection Check for output files
>  
>  @table @code
>  @item output-exists [@{ target/xfail @var{selector} @}]
> @@ -2646,13 +2646,12 @@ Passes if compiler output file exists.
>  
>  @item output-exists-not [@{ target/xfail @var{selector} @}]
>  Passes if compiler output file does not exist.
> -@end table
> -
> -@subsubsection Check for LTO tests
>  
> -@table @code
>  @item scan-symbol @var{regexp} [@{ target/xfail @var{selector} @}]
>  Passes if the pattern is present in the final executable.
> +
> +@item scan-symbol-not @var{regexp} [@{ target/xfail @var{selector} @}]
> +Passes if the pattern is absent from the final executable.
>  @end table
>  
>  @subsubsection Checks for @command{gcov} tests
> diff --git a/gcc/testsuite/gcc.target/arm/size-optimization-ieee-1.c b/gcc/testsuite/gcc.target/arm/size-optimization-ieee-1.c
> new file mode 100644
> index 00000000000..34090f20fec
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/size-optimization-ieee-1.c
> @@ -0,0 +1,33 @@
> +/* { dg-do link { target arm_soft_ok } } */
> +/* { dg-options "-mfloat-abi=soft" } */
> +
> +int
> +foo (void)
> +{
> +  volatile float a;
> +  volatile float b;
> +  volatile float c = a * b;
> +  return 0;
> +}
> +
> +int
> +bar (void)
> +{
> +  volatile double a;
> +  volatile double b;
> +  volatile double c = a * b;
> +  return 0;
> +}
> +
> +int
> +main (void)
> +{
> +  foo ();
> +  bar ();
> +  return 0;
> +}
> +
> +/* { dg-final { scan-symbol "__aeabi_fmul" } } */
> +/* { dg-final { scan-symbol "__aeabi_dmul" } } */
> +/* { dg-final { scan-symbol-not "__aeabi_fdiv" } } */
> +/* { dg-final { scan-symbol-not "__aeabi_ddiv" } } */
> diff --git a/gcc/testsuite/gcc.target/arm/size-optimization-ieee-2.c b/gcc/testsuite/gcc.target/arm/size-optimization-ieee-2.c
> new file mode 100644
> index 00000000000..75337894a9c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/size-optimization-ieee-2.c
> @@ -0,0 +1,31 @@
> +/* { dg-do link { target arm_soft_ok } } */
> +/* { dg-options "-mfloat-abi=soft" } */
> +
> +int
> +foo (void)
> +{
> +  volatile float a;
> +  volatile float b;
> +  volatile float c = a / b;
> +  return 0;
> +}
> +
> +int
> +bar (void)
> +{
> +  volatile double a;
> +  volatile double b;
> +  volatile double c = a / b;
> +  return 0;
> +}
> +
> +int
> +main (void)
> +{
> +  foo ();
> +  bar ();
> +  return 0;
> +}
> +
> +/* { dg-final { scan-symbol "__aeabi_fdiv" } } */
> +/* { dg-final { scan-symbol "__aeabi_ddiv" } } */
> diff --git a/gcc/testsuite/gcc.target/arm/size-optimization-ieee-3.c b/gcc/testsuite/gcc.target/arm/size-optimization-ieee-3.c
> new file mode 100644
> index 00000000000..63c92b3bbb7
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/size-optimization-ieee-3.c
> @@ -0,0 +1,33 @@
> +/* { dg-do link { target arm_soft_ok } } */
> +/* { dg-options "-mfloat-abi=soft" } */
> +
> +int
> +foo (void)
> +{
> +  volatile float a;
> +  volatile float b;
> +  volatile float c = a * b + a / b;
> +  return 0;
> +}
> +
> +int
> +bar (void)
> +{
> +  volatile double a;
> +  volatile double b;
> +  volatile double c = a * b + a / b;
> +  return 0;
> +}
> +
> +int
> +main (void)
> +{
> +  foo ();
> +  bar ();
> +  return 0;
> +}
> +
> +/* { dg-final { scan-symbol "__aeabi_fmul" } } */
> +/* { dg-final { scan-symbol "__aeabi_dmul" } } */
> +/* { dg-final { scan-symbol "__aeabi_fdiv" } } */
> +/* { dg-final { scan-symbol "__aeabi_ddiv" } } */
> diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp
> index c33a50c0b13..0472b63f94c 100644
> --- a/gcc/testsuite/lib/gcc-dg.exp
> +++ b/gcc/testsuite/lib/gcc-dg.exp
> @@ -1236,5 +1236,81 @@ proc gdb-exists { args } {
>      return 0;
>  }
>  
> +# Helper function for scan-symbol and scan-symbol-not. It scans a symbol in
> +# the final executable and return 1 if present, otherwise fail.
> +#
> +# Argument 0 is the regexp to match.
> +# Argument 1 handles expected failures and the like
> +proc scan-symbol-common { scan_directive args } {
> +    global nm
> +    global base_dir
> +
> +    # Access variable from gcc-dg-test-1 or lto-execute.
> +    upvar 3 output_file output_file
> +
> +    if { [llength $args] >= 2 } {
> +	switch [dg-process-target [lindex $args 1]] {
> +	    "S" { }
> +	    "N" { return }
> +	    "F" { setup_xfail "*-*-*" }
> +	    "P" { }
> +	}
> +    }
> +
> +    # Find nm like we find g++ in g++.exp.
> +    if ![info exists nm]  {
> +	set nm [findfile $base_dir/../../../binutils/nm \
> +		$base_dir/../../../binutils/nm \
> +	        [findfile $base_dir/../../nm $base_dir/../../nm \
> +		      [findfile $base_dir/nm $base_dir/nm \
> +		       [transform nm]]]]
> +	verbose -log "nm is $nm"
> +    }
> +
> +    set output_file "[glob -nocomplain $output_file]"
> +    if { $output_file == "" } {
> +	fail "$scan_directive $args: output file does not exist"
> +	return
> +    }
> +
> +    set fd [open "| $nm $output_file" r]
> +    set text [read $fd]
> +    close $fd
> +
> +    if [regexp -- [lindex $args 0] $text] {
> +	return 1
> +    } else {
> +	return 0
> +    }
> +}
> +
> +# Utility for scanning a symbol in the final executable, invoked via dg-final.
> +# Call pass if pattern is present, otherwise fail.
> +#
> +# Argument 0 is the regexp to match.
> +# Argument 1 handles expected failures and the like
> +proc scan-symbol { args } {
> +    set testcase [testname-for-summary]
> +    if { [scan-symbol-common "scan-symbol" $args]} {
> +	pass "$testcase   scan-symbol $args"
> +    } else {
> +	fail "$testcase   scan-symbol $args"
> +    }
> +}
> +
> +# Utility for scanning a symbol in the final executable, invoked via dg-final.
> +# Call pass if pattern is absent, otherwise fail.
> +#
> +# Argument 0 is the regexp to match.
> +# Argument 1 handles expected failures and the like
> +proc scan-symbol-not { args } {
> +    set testcase [testname-for-summary]
> +    if { [scan-symbol-common "scan-symbol-not" $args]} {
> +	fail "$testcase   scan-symbol-not $args"
> +    } else {
> +	pass "$testcase   scan-symbol-not $args"
> +    }
> +}
> +
>  set additional_prunes ""
>  set dg_runtest_extra_prunes ""
> diff --git a/gcc/testsuite/lib/lto.exp b/gcc/testsuite/lib/lto.exp
> index 58a84aa1936..c2c35698827 100644
> --- a/gcc/testsuite/lib/lto.exp
> +++ b/gcc/testsuite/lib/lto.exp
> @@ -712,6 +712,17 @@ proc lto-execute { src1 sid } {
>  
>  	# There's a unique name for each executable we generate.
>  	set execname "${execbase}-${count}1.exe"
> +
> +	# The LTO tests don't use dg-test, so testname_with_flags and
> +	# output_file need to be defined explicitly for each file.  scan-symbol
> +	# directives rely on both of these to be defined to find the symbol to
> +	# scan and for the text to print in the PASS/FAIL since they can also
> +	# be called from dg-test.  testname_with_flags is also used via
> +	# testname-for-summary when calling into generic function below to
> +	# clean temporary files.
> +	set output_file $execname
> +	set testname_with_flags $execname
> +
>  	incr count
>  
>  	file_on_host delete $execname
> @@ -774,11 +785,7 @@ proc lto-execute { src1 sid } {
>  	    }
>  	}
>  
> -	# Clean up after -save-temps.  The LTO tests don't use dg-test, so
> -	# testname-for-summary needs to be defined explicitly for each
> -	# file that needs to be removed.
> -	set testname_with_flags $execname
> -
> +	# Clean up after -save-temps.
>  	eval "cleanup-saved-temps"
>  
>  	for {set i 0} {$i < $num_srcs} {incr i} {
> @@ -801,52 +808,6 @@ proc lto-execute { src1 sid } {
>      }
>  }
>  
> -# Utility for scanning a symbol in the final executable, invoked via dg-final.
> -# Call pass if pattern is present, otherwise fail.
> -#
> -# Argument 0 is the regexp to match.
> -# Argument 1 handles expected failures and the like
> -proc scan-symbol { args } {
> -    global nm
> -    global base_dir
> -    upvar 2 execname execname
> -
> -    if { [llength $args] >= 2 } {
> -	switch [dg-process-target [lindex $args 1]] {
> -	    "S" { }
> -	    "N" { return }
> -	    "F" { setup_xfail "*-*-*" }
> -	    "P" { }
> -	}
> -    }
> -
> -    # Find nm like we find g++ in g++.exp.
> -    if ![info exists nm]  {
> -	set nm [findfile $base_dir/../../../binutils/nm \
> -		$base_dir/../../../binutils/nm \
> -	        [findfile $base_dir/../../nm $base_dir/../../nm \
> -		      [findfile $base_dir/nm $base_dir/nm \
> -		       [transform nm]]]]
> -	verbose -log "nm is $nm"
> -    }
> -
> -    set output_file "[glob -nocomplain $execname]"
> -    if { $output_file == "" } {
> -	fail "scan-symbol $args: dump file does not exist"
> -	return
> -    }
> -
> -    set fd [open "| $nm $output_file" r]
> -    set text [read $fd]
> -    close $fd
> -
> -    if [regexp -- [lindex $args 0] $text] {
> -	pass "scan-symbol $args"
> -    } else {
> -	fail "scan-symbol $args"
> -    }
> -}
> -
>  # Call pass if object readelf is ok, otherwise fail.
>  # example: /* { dg-final { object-readelf Tag_ABI_enum_size int} } */
>  proc object-readelf { args } {
> diff --git a/libgcc/config/arm/ieee754-df.S b/libgcc/config/arm/ieee754-df.S
> index 480e33da31f..9f2ae9ed698 100644
> --- a/libgcc/config/arm/ieee754-df.S
> +++ b/libgcc/config/arm/ieee754-df.S
> @@ -617,7 +617,18 @@ ARM_FUNC_ALIAS aeabi_l2d floatdidf
>  
>  #endif /* L_addsubdf3 */
>  
> -#ifdef L_arm_muldivdf3
> +#if defined(L_arm_muldf3) || defined(L_arm_muldivdf3)
> +
> +@ Define multiplication as weak in _arm_muldf3.o so that it can be overriden
> +@ by the global definition in _arm_muldivdf3.o.  This allows a program only
> +@ using multiplication to take the weak definition which does not contain the
> +@ division code. Programs using only division or both division and
> +@ multiplication will pull _arm_muldivdf3.o from which both the multiplication
> +@ and division are taken thanks to the override.
> +#ifdef L_arm_muldf3
> +WEAK muldf3
> +WEAK aeabi_dmul
> +#endif
>  
>  ARM_FUNC_START muldf3
>  ARM_FUNC_ALIAS aeabi_dmul muldf3
> @@ -719,6 +730,7 @@ LSYM(Lml_1):
>  	orr	xh, xh, #0x00100000
>  	mov	lr, #0
>  	subs	r4, r4, #1
> +
>  LSYM(Lml_u):
>  	@ Overflow?
>  	bgt	LSYM(Lml_o)
> @@ -870,6 +882,8 @@ LSYM(Lml_n):
>  	FUNC_END aeabi_dmul
>  	FUNC_END muldf3
>  
> +#ifdef L_arm_muldivdf3
> +
>  ARM_FUNC_START divdf3
>  ARM_FUNC_ALIAS aeabi_ddiv divdf3
>  	CFI_START_FUNCTION
> @@ -1067,6 +1081,7 @@ LSYM(Ldv_s):
>  	FUNC_END divdf3
>  
>  #endif /* L_muldivdf3 */
> +#endif /* L_arm_muldf3 || L_arm_muldivdf3 */
>  
>  #ifdef L_arm_cmpdf2
>  
> diff --git a/libgcc/config/arm/ieee754-sf.S b/libgcc/config/arm/ieee754-sf.S
> index 28e0d793281..0b4d1ab377d 100644
> --- a/libgcc/config/arm/ieee754-sf.S
> +++ b/libgcc/config/arm/ieee754-sf.S
> @@ -428,7 +428,18 @@ ARM_FUNC_ALIAS aeabi_l2f floatdisf
>  
>  #endif /* L_addsubsf3 */
>  
> -#ifdef L_arm_muldivsf3
> +#if defined(L_arm_mulsf3) || defined(L_arm_muldivsf3)
> +
> +@ Define multiplication as weak in _arm_mulsf3.o so that it can be overriden
> +@ by the global definition in _arm_muldivsf3.o.  This allows a program only
> +@ using multiplication to take the weak definition which does not contain the
> +@ division code. Programs using only division or both division and
> +@ multiplication will pull _arm_muldivsf3.o from which both the multiplication
> +@ and division are taken thanks to the override.
> +#ifdef L_arm_mulsf3
> +WEAK mulsf3
> +WEAK aeabi_fmul
> +#endif
>  
>  ARM_FUNC_START mulsf3
>  ARM_FUNC_ALIAS aeabi_fmul mulsf3
> @@ -613,6 +624,8 @@ LSYM(Lml_n):
>  	FUNC_END aeabi_fmul
>  	FUNC_END mulsf3
>  
> +#ifdef L_arm_muldivsf3
> +
>  ARM_FUNC_START divsf3
>  ARM_FUNC_ALIAS aeabi_fdiv divsf3
>  	CFI_START_FUNCTION
> @@ -756,6 +769,7 @@ LSYM(Ldv_s):
>  	FUNC_END divsf3
>  
>  #endif /* L_muldivsf3 */
> +#endif /* L_arm_mulsf3 || L_arm_muldivsf3 */
>  
>  #ifdef L_arm_cmpsf2
>  
> diff --git a/libgcc/config/arm/lib1funcs.S b/libgcc/config/arm/lib1funcs.S
> index ff06d504a4c..193fb251fdb 100644
> --- a/libgcc/config/arm/lib1funcs.S
> +++ b/libgcc/config/arm/lib1funcs.S
> @@ -359,12 +359,8 @@ SYM (\name):
>  #define THUMB_SYNTAX
>  #endif
>  
> -.macro FUNC_START name sp_section=
> -  .ifc \sp_section, function_section
> -	.section	.text.__\name,"ax",%progbits
> -  .else
> +.macro FUNC_START name
>  	.text
> -  .endif
>  	.globl SYM (__\name)
>  	TYPE (__\name)
>  	.align 0
> @@ -390,8 +386,8 @@ SYM (\name):
>  #if defined(__thumb2__)
>  
>  /* For Thumb-2 we build everything in thumb mode.  */
> -.macro ARM_FUNC_START name sp_section=
> -       FUNC_START \name \sp_section
> +.macro ARM_FUNC_START name
> +       FUNC_START \name
>         .syntax unified
>  .endm
>  #define EQUIV .thumb_set
> @@ -422,12 +418,8 @@ _L__\name:
>  #ifdef NOT_ISA_TARGET_32BIT
>  #define EQUIV .thumb_set
>  #else
> -.macro	ARM_FUNC_START name sp_section=
> -  .ifc \sp_section, function_section
> -	.section	.text.__\name,"ax",%progbits
> -  .else
> +.macro	ARM_FUNC_START name
>  	.text
> -  .endif
>  	.globl SYM (__\name)
>  	TYPE (__\name)
>  	.align 0
> @@ -2169,7 +2161,8 @@ LSYM(Lchange_\register):
>  .endm
>  
>  #ifndef __symbian__
> -/* The condition here must match the one in gcc/config/arm/elf.h.  */
> +/* The condition here must match the one in gcc/config/arm/elf.h and
> +   libgcc/config/arm/t-elf.  */
>  #ifndef NOT_ISA_TARGET_32BIT
>  #include "ieee754-df.S"
>  #include "ieee754-sf.S"
> diff --git a/libgcc/config/arm/t-elf b/libgcc/config/arm/t-elf
> index 9e7a3170f17..9da6cd37054 100644
> --- a/libgcc/config/arm/t-elf
> +++ b/libgcc/config/arm/t-elf
> @@ -1,3 +1,19 @@
> +ifeq (,$(findstring __symbian__,$(shell $(gcc_compile_bare) -dM -E - </dev/null)))
> +
> +ARM_ISA:=$(findstring __ARM_ARCH_ISA_ARM,$(shell $(gcc_compile_bare) -dM -E - </dev/null))
> +THUMB1_ISA:=$(findstring __ARM_ARCH_ISA_THUMB 1,$(shell $(gcc_compile_bare) -dM -E - </dev/null))
> +
> +# The condition here must match the one in gcc/config/arm/elf.h and
> +# libgcc/config/arm/lib1funcs.S.  _arm_muldf3 and _arm_mulsf3 must be included
> +# first so that the weak multiplication symbols in the corresponding files are
> +# chosen over the global symbols that _arm_muldivdf3 and _arm_muldivsf3
> +# inclusion create when only multiplication is used, thus avoiding pulling in
> +# useless division code.
> +ifneq (__ARM_ARCH_ISA_THUMB 1,$(ARM_ISA)$(THUMB1_ISA))
> +LIB1ASMFUNCS += _arm_muldf3 _arm_mulsf3
> +endif
> +endif # !__symbian__
> +
>  # For most CPUs we have an assembly soft-float implementations.
>  # However this is not true for ARMv6M.  Here we want to use the soft-fp C
>  # implementation.  The soft-fp code is only build for ARMv6M.  This pulls
> 



More information about the Gcc-patches mailing list