diff options
author | Kito Cheng <kito.cheng@sifive.com> | 2020-11-20 15:55:58 +0800 |
---|---|---|
committer | Kito Cheng <kito.cheng@sifive.com> | 2022-09-02 17:25:30 +0800 |
commit | d72ca12b846a9f5c01674b280b1817876c77888f (patch) | |
tree | e1927e05aa17a1658d3def80c50f33d47630e4f3 /gcc/config | |
parent | 5ca9980fc86242505ffdaaf62bca1fd5db26550b (diff) | |
download | gcc-d72ca12b846a9f5c01674b280b1817876c77888f.zip gcc-d72ca12b846a9f5c01674b280b1817876c77888f.tar.gz gcc-d72ca12b846a9f5c01674b280b1817876c77888f.tar.bz2 |
RISC-V: Implement TARGET_COMPUTE_MULTILIB
Use TARGET_COMPUTE_MULTILIB to search the multi-lib reuse for riscv*-*-elf*,
according following rules:
1. Check ABI is same.
2. Check both has atomic extension or both don't have atomic extension.
- Because mix soft and hard atomic operation doesn't make sense and
won't work as expect.
3. Check current arch is superset of the target multi-lib arch.
- It might result slower performance or larger code size, but it
safe to run.
4. Pick most match multi-lib set if more than one multi-lib are pass
the above checking.
Example for how to select multi-lib:
We build code with -march=rv32imaf and -mabi=ilp32, and we have
following 5 multi-lib set:
1. rv32ia/ilp32
2. rv32ima/ilp32
3. rv32imf/ilp32
4. rv32imaf/ilp32f
5. rv32imafd/ilp32
The first and second multi-lib is safe to like, 3rd multi-lib can't
re-use becasue it don't have atomic extension, which is mismatch according
rule 2, and the 4th multi-lib can't re-use too due to the ABI mismatch,
the last multi-lib can't use since current arch is not superset of the
arch of multi-lib.
And emit error if not found suitable multi-lib set, the error message
only emit when link with standard libraries.
Example for when error will be emitted:
$ riscv64-unknown-elf-gcc -print-multi-lib
.;
rv32i/ilp32;@march=rv32i@mabi=ilp32
rv32im/ilp32;@march=rv32im@mabi=ilp32
rv32iac/ilp32;@march=rv32iac@mabi=ilp32
rv32imac/ilp32;@march=rv32imac@mabi=ilp32
rv32imafc/ilp32f;@march=rv32imafc@mabi=ilp32f
rv64imac/lp64;@march=rv64imac@mabi=lp64
// No actual linking, so no error emitted.
$ riscv64-unknown-elf-gcc -print-multi-directory -march=rv32ia -mabi=ilp32
.
// Link to default libc and libgcc, so check the multi-lib, and emit
// error because not found suitable multilib.
$ riscv64-unknown-elf-gcc -march=rv32ia -mabi=ilp32 ~/hello.c
riscv64-unknown-elf-gcc: fatal error: can't found suitable multilib set for '-march=rv32ia'/'-mabi=ilp32'
compilation terminated.
// No error emitted, because not link to stdlib.
$ riscv64-unknown-elf-gcc -march=rv32ia -mabi=ilp32 ~/hello.c -nostdlib
// No error emitted, because compile only.
$ riscv64-unknown-elf-gcc -march=rv32ia -mabi=ilp32 ~/hello.c -c
gcc/ChangeLog:
* common/config/riscv/riscv-common.cc: Include <vector>.
(struct riscv_multi_lib_info_t): New.
(riscv_subset_list::match_score): Ditto.
(find_last_appear_switch): Ditto.
(prefixed_with): Ditto.
(struct multi_lib_info_t): Ditto.
(riscv_current_arch_str): Ditto.
(riscv_current_abi_str): Ditto.
(riscv_multi_lib_info_t::parse): Ditto.
(riscv_check_cond): Ditto.
(riscv_check_conds): Ditto.
(riscv_compute_multilib): Ditto.
(TARGET_COMPUTE_MULTILIB): Defined.
* config/riscv/elf.h (LIB_SPEC): Call riscv_multi_lib_check if
doing link.
(RISCV_USE_CUSTOMISED_MULTI_LIB): New.
* config/riscv/riscv.h (riscv_multi_lib_check): New.
(EXTRA_SPEC_FUNCTIONS): Add riscv_multi_lib_check.
* config/riscv/riscv-subset.h (riscv_subset_list::match_score): New.
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/riscv/elf.h | 6 | ||||
-rw-r--r-- | gcc/config/riscv/riscv-subset.h | 2 | ||||
-rw-r--r-- | gcc/config/riscv/riscv.h | 4 |
3 files changed, 10 insertions, 2 deletions
diff --git a/gcc/config/riscv/elf.h b/gcc/config/riscv/elf.h index f0e865d..f3d767c 100644 --- a/gcc/config/riscv/elf.h +++ b/gcc/config/riscv/elf.h @@ -27,10 +27,14 @@ along with GCC; see the file COPYING3. If not see /* Link against Newlib libraries, because the ELF backend assumes Newlib. Handle the circular dependence between libc and libgloss. */ #undef LIB_SPEC -#define LIB_SPEC "--start-group -lc %{!specs=nosys.specs:-lgloss} --end-group" +#define LIB_SPEC \ + "--start-group -lc %{!specs=nosys.specs:-lgloss} --end-group " \ + "%{!nostartfiles:%{!nodefaultlibs:%{!nolibc:%{!nostdlib:%:riscv_multi_lib_check()}}}}" #undef STARTFILE_SPEC #define STARTFILE_SPEC "crt0%O%s crtbegin%O%s" #undef ENDFILE_SPEC #define ENDFILE_SPEC "crtend%O%s" + +#define RISCV_USE_CUSTOMISED_MULTI_LIB 1 diff --git a/gcc/config/riscv/riscv-subset.h b/gcc/config/riscv/riscv-subset.h index c592650..0bb3a9d 100644 --- a/gcc/config/riscv/riscv-subset.h +++ b/gcc/config/riscv/riscv-subset.h @@ -89,6 +89,8 @@ public: const riscv_subset_t *begin () const {return m_head;}; const riscv_subset_t *end () const {return NULL;}; + + int match_score (riscv_subset_list *) const; }; extern const riscv_subset_list *riscv_current_subset_list (void); diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 3ee5a93..e35aaa7 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -50,11 +50,13 @@ along with GCC; see the file COPYING3. If not see extern const char *riscv_expand_arch (int argc, const char **argv); extern const char *riscv_expand_arch_from_cpu (int argc, const char **argv); extern const char *riscv_default_mtune (int argc, const char **argv); +extern const char *riscv_multi_lib_check (int argc, const char **argv); # define EXTRA_SPEC_FUNCTIONS \ { "riscv_expand_arch", riscv_expand_arch }, \ { "riscv_expand_arch_from_cpu", riscv_expand_arch_from_cpu }, \ - { "riscv_default_mtune", riscv_default_mtune }, + { "riscv_default_mtune", riscv_default_mtune }, \ + { "riscv_multi_lib_check", riscv_multi_lib_check }, /* Support for a compile-time default CPU, et cetera. The rules are: --with-arch is ignored if -march or -mcpu is specified. |