---
gcc/common/config/riscv/riscv-common.cc | 118 ++++++++++++++++--------
gcc/config/riscv/linux.h | 13 ++-
2 files changed, 90 insertions(+), 41 deletions(-)
diff --git a/gcc/common/config/riscv/riscv-common.cc
b/gcc/common/config/riscv/riscv-common.cc
index 309a52def75f..75bfe198d4c6 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -1597,6 +1597,73 @@ riscv_check_conds (
return match_score + ok_count * 100;
}
+static const char *
+riscv_select_multilib_by_abi (
+ const std::string &riscv_current_arch_str,
+ const std::string &riscv_current_abi_str,
+ const riscv_subset_list *subset_list,
+ const struct switchstr *switches,
+ int n_switches,
+ const std::vector<riscv_multi_lib_info_t> &multilib_infos
+ )
+{
+ for (size_t i = 0; i < multilib_infos.size (); ++i)
+ if (riscv_current_abi_str == multilib_infos[i].abi_str)
+ return xstrdup (multilib_infos[i].path.c_str ());
+
+ return NULL;
+}
+
+
+static const char *
+riscv_select_multilib (
+ const std::string &riscv_current_arch_str,
+ const std::string &riscv_current_abi_str,
+ const riscv_subset_list *subset_list,
+ const struct switchstr *switches,
+ int n_switches,
+ const std::vector<riscv_multi_lib_info_t> &multilib_infos
+ )
+{
+ int match_score = 0;
+ int max_match_score = 0;
+ int best_match_multi_lib = -1;
+ /* Try to decision which set we should used. */
+ /* We have 3 level decision tree here, ABI, check input arch/ABI must
+ be superset of multi-lib arch, and other rest option checking. */
+ for (size_t i = 0; i < multilib_infos.size (); ++i)
+ {
+ /* Check ABI is same first. */
+ if (riscv_current_abi_str != multilib_infos[i].abi_str)
+ continue;
+
+ /* Found a potential compatible multi-lib setting!
+ Calculate the match score. */
+ match_score = subset_list->match_score (multilib_infos[i].subset_list);
+
+ /* Checking other cond in the multi-lib setting. */
+ match_score = riscv_check_conds (switches,
+ n_switches,
+ match_score,
+ multilib_infos[i].conds);
+
+ /* Record highest match score multi-lib setting. */
+ if (match_score > max_match_score)
+ {
+ best_match_multi_lib = i;
+ max_match_score = match_score;
+ }
+ }
+
+ if (best_match_multi_lib == -1)
+ {
+ riscv_no_matched_multi_lib = true;
+ return NULL;
+ }
+ else
+ return xstrdup (multilib_infos[best_match_multi_lib].path.c_str ());
+}
+
/* Implement TARGET_COMPUTE_MULTILIB. */
static const char *
riscv_compute_multilib (
@@ -1621,6 +1688,12 @@ riscv_compute_multilib (
std::string option_cond;
riscv_multi_lib_info_t multilib_info;
+ bool check_abi_only = false;
+
+#if TARGET_LINUX == 1
+ check_abi_only = true;
+#endif
+
/* Already found suitable, multi-lib, just use that. */
if (multilib_dir != NULL)
return multilib_dir;
@@ -1672,7 +1745,11 @@ riscv_compute_multilib (
}
this_path_len = p - this_path;
- multilib_info.path = std::string (this_path, this_path_len);
+ const char *multi_os_dir_pos = (const char*)memchr (this_path, ':',
this_path_len);
+ if (multi_os_dir_pos)
+ multilib_info.path = std::string (this_path, multi_os_dir_pos -
this_path);
+ else
+ multilib_info.path = std::string (this_path, this_path_len);
option_conds.clear ();
/* Pasrse option check list into vector<string>.
@@ -1707,43 +1784,10 @@ riscv_compute_multilib (
p++;
}
- int match_score = 0;
- int max_match_score = 0;
- int best_match_multi_lib = -1;
- /* Try to decision which set we should used. */
- /* We have 3 level decision tree here, ABI, check input arch/ABI must
- be superset of multi-lib arch, and other rest option checking. */
- for (size_t i = 0; i < multilib_infos.size (); ++i)
- {
- /* Check ABI is same first. */
- if (riscv_current_abi_str != multilib_infos[i].abi_str)
- continue;
-
- /* Found a potential compatible multi-lib setting!
- Calculate the match score. */
- match_score = subset_list->match_score (multilib_infos[i].subset_list);
-
- /* Checking other cond in the multi-lib setting. */
- match_score = riscv_check_conds (switches,
- n_switches,
- match_score,
- multilib_infos[i].conds);
-
- /* Record highest match score multi-lib setting. */
- if (match_score > max_match_score)
- {
- best_match_multi_lib = i;
- max_match_score = match_score;
- }
- }
-
- if (best_match_multi_lib == -1)
- {
- riscv_no_matched_multi_lib = true;
- return multilib_dir;
- }
+ if (check_abi_only)
+ return riscv_select_multilib_by_abi (riscv_current_arch_str,
riscv_current_abi_str, subset_list, switches, n_switches, multilib_infos);
else
- return xstrdup (multilib_infos[best_match_multi_lib].path.c_str ());
+ return riscv_select_multilib (riscv_current_arch_str,
riscv_current_abi_str, subset_list, switches, n_switches, multilib_infos);
}
#undef TARGET_COMPUTE_MULTILIB
diff --git a/gcc/config/riscv/linux.h b/gcc/config/riscv/linux.h
index b9557a75dc72..46256f78e5df 100644
--- a/gcc/config/riscv/linux.h
+++ b/gcc/config/riscv/linux.h
@@ -72,7 +72,12 @@ along with GCC; see the file COPYING3. If not see
#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
#define STARTFILE_PREFIX_SPEC \
- "/lib" XLEN_SPEC "/" ABI_SPEC "/ " \
- "/usr/lib" XLEN_SPEC "/" ABI_SPEC "/ " \
- "/lib/ " \
- "/usr/lib/ "
+ "%{mabi=lp64d: /lib64/lp64d/ /usr/lib64/lp64d/ /lib/ /usr/lib/}" \
+ "%{mabi=lp64f: /lib64/lp64f/ /usr/lib64/lp64f/ /lib/ /usr/lib/}" \
+ "%{mabi=lp64: /lib64/lp64/ /usr/lib64/lp64/ /lib/ /usr/lib/}" \
+ "%{mabi=ilp32d: /lib32/ilp32d /usr/lib32/ilp32d/ /lib/ /usr/lib/}" \
+ "%{mabi=ilp32f: /lib32/ilp32f/ /usr/lib32/ilp32f/ /lib/ /usr/lib/}" \
+ "%{mabi=ilp32: /lib32/ilp32/ /usr/lib32/ilp32/ /lib/ /usr/lib/}"
+
+#define RISCV_USE_CUSTOMISED_MULTI_LIB 1
+#define TARGET_LINUX 1
--
2.39.2