From a92c0cb2ce6fa58939331549bfb9e8110ec86a11 Mon Sep 17 00:00:00 2001 From: Kito Cheng Date: Wed, 19 Apr 2023 11:54:42 +0800 Subject: [PATCH] RISC-V: Handle multi-lib path correclty for linux [DRAFT] --- 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 2fc0f8bffc1..f40b1b617c2 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 &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 &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. @@ -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 b9557a75dc7..46256f78e5d 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