aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorKito Cheng <kito.cheng@sifive.com>2020-11-20 15:55:58 +0800
committerKito Cheng <kito.cheng@sifive.com>2022-09-02 17:25:30 +0800
commitd72ca12b846a9f5c01674b280b1817876c77888f (patch)
treee1927e05aa17a1658d3def80c50f33d47630e4f3 /gcc/config
parent5ca9980fc86242505ffdaaf62bca1fd5db26550b (diff)
downloadgcc-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.h6
-rw-r--r--gcc/config/riscv/riscv-subset.h2
-rw-r--r--gcc/config/riscv/riscv.h4
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.