diff options
Diffstat (limited to 'bfd/elfxx-riscv.c')
-rw-r--r-- | bfd/elfxx-riscv.c | 142 |
1 files changed, 76 insertions, 66 deletions
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index 43d3c0d..1200032 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -1178,9 +1178,20 @@ static bool check_implicit_for_zcf (riscv_parse_subset_t *rps, const riscv_subset_t *subset ATTRIBUTE_UNUSED) { - riscv_subset_t *tmp = NULL; - return *rps->xlen == 32 - && riscv_lookup_subset (rps->subset_list, "f", &tmp); + return (rps != NULL + && rps->xlen != NULL + && *rps->xlen == 32 + && riscv_subset_supports (rps, "f")); +} + +/* Add the implicit only when 'd' extension is also available. */ + +static bool +check_implicit_for_zcd (riscv_parse_subset_t *rps, + const riscv_subset_t *subset ATTRIBUTE_UNUSED) +{ + return (rps != NULL + && riscv_subset_supports (rps, "d")); } /* Record all implicit information for the subsets. */ @@ -1237,15 +1248,6 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] = {"zvl128b", "+zvl64b", check_implicit_always}, {"zvl64b", "+zvl32b", check_implicit_always}, - {"zce", "+zca,+zcb,+zcmp,+zcmt", check_implicit_always}, - {"zce", "+zcf", check_implicit_for_zcf}, - {"zcb", "+zca", check_implicit_always}, - {"zcd", "+d,+zca", check_implicit_always}, - {"zcf", "+f,+zca", check_implicit_always}, - {"zcmp", "+zca", check_implicit_always}, - {"zcmop", "+zca", check_implicit_always}, - {"zcmt", "+zca,+zicsr", check_implicit_always}, - {"zicfilp", "+zicsr", check_implicit_always}, {"zicfiss", "+zimop,+zicsr", check_implicit_always}, {"zclsd", "+zca,+zilsd", check_implicit_always}, @@ -1262,6 +1264,9 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] = {"zhinx", "+zhinxmin", check_implicit_always}, {"zhinxmin", "+zfinx", check_implicit_always}, + {"zcd", "+d,+zca", check_implicit_always}, + {"zcf", "+f,+zca", check_implicit_always}, + {"q", "+d", check_implicit_always}, {"zqinx", "+zdinx", check_implicit_always}, @@ -1275,6 +1280,16 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] = {"zfinx", "+zicsr", check_implicit_always}, {"f", "+zicsr", check_implicit_always}, + {"zce", "+zcb,+zcmp,+zcmt", check_implicit_always}, + {"zce", "+zcf", check_implicit_for_zcf}, + {"zcb", "+zca", check_implicit_always}, + {"zcmp", "+zca", check_implicit_always}, + {"zcmop", "+zca", check_implicit_always}, + {"zcmt", "+zca,+zicsr", check_implicit_always}, + {"c", "+zcf", check_implicit_for_zcf}, + {"c", "+zcd", check_implicit_for_zcd}, + {"c", "+zca", check_implicit_always}, + {"b", "+zba,+zbb,+zbs", check_implicit_always}, {"zk", "+zkn,+zkr,+zkt", check_implicit_always}, @@ -2208,7 +2223,7 @@ riscv_parse_check_conflicts (riscv_parse_subset_t *rps) && riscv_subset_supports (rps, "zcd")) { rps->error_handler - (_("zcmp' is incompatible with `d/zcd' extension")); + (_("zcmp' is incompatible with `d' and `c', or `zcd' extension")); no_conflict = false; } if (riscv_lookup_subset (rps->subset_list, "zcf", &subset) @@ -2602,7 +2617,7 @@ riscv_remove_subset (riscv_subset_list_t *subset_list, called from riscv_update_subset./ The IMPLICIT_EXTS, +extension[version] [,...,+extension_n[version_n]] - -extension [,...,-extension_n], + (Deprecated) -extension [,...,-extension_n], full ISA. */ static bool @@ -2694,16 +2709,26 @@ riscv_update_subset1 (riscv_parse_subset_t *rps, return false; } - if (explicit_subset == NULL - && (strcmp (subset, "i") == 0 - || strcmp (subset, "e") == 0 - || strcmp (subset, "g") == 0)) + if (explicit_subset == NULL) { - rps->error_handler - (_("%scannot + or - base extension `%s' in %s `%s'"), - errmsg_internal, subset, errmsg_caller, implicit_exts); - free (subset); - return false; + if (removed) + { + rps->error_handler + (_("%sdeprecated - extension `%s' in %s `%s'"), + errmsg_internal, subset, errmsg_caller, implicit_exts); + free (subset); + return false; + } + else if (strcmp (subset, "i") == 0 + || strcmp (subset, "e") == 0 + || strcmp (subset, "g") == 0) + { + rps->error_handler + (_("%scannot + base extension `%s' in %s `%s'"), + errmsg_internal, subset, errmsg_caller, implicit_exts); + free (subset); + return false; + } } if (removed) @@ -2729,8 +2754,8 @@ riscv_update_subset1 (riscv_parse_subset_t *rps, return no_conflict; } -/* Add/Remove an extension to/from the subset list. This is used for - the .option rvc or norvc, and .option arch directives. */ +/* Add an extension to/from the subset list. This is used for the .option rvc + and .option arch directives. */ bool riscv_update_subset (riscv_parse_subset_t *rps, @@ -2739,6 +2764,16 @@ riscv_update_subset (riscv_parse_subset_t *rps, return riscv_update_subset1 (rps, NULL, str); } +/* Called from .option norvc directives. */ + +bool +riscv_update_subset_norvc (riscv_parse_subset_t *rps) +{ + return riscv_update_subset1 (rps, rps->subset_list->head, + "-c,-zca,-zcd,-zcf,-zcb,-zce,-zcmp,-zcmt," + "-zcmop,-zclsd"); +} + /* Check if the FEATURE subset is supported or not in the subset list. Return true if it is supported; Otherwise, return false. */ @@ -2775,10 +2810,9 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps, return riscv_subset_supports (rps, "zifencei"); case INSN_CLASS_ZIHINTNTL: return riscv_subset_supports (rps, "zihintntl"); - case INSN_CLASS_ZIHINTNTL_AND_C: - return (riscv_subset_supports (rps, "zihintntl") - && (riscv_subset_supports (rps, "c") - || riscv_subset_supports (rps, "zca"))); + case INSN_CLASS_ZIHINTNTL_AND_ZCA: + return riscv_subset_supports (rps, "zihintntl") + && riscv_subset_supports (rps, "zca"); case INSN_CLASS_ZIHINTPAUSE: return riscv_subset_supports (rps, "zihintpause"); case INSN_CLASS_ZIMOP: @@ -2813,17 +2847,12 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps, return riscv_subset_supports (rps, "d"); case INSN_CLASS_Q: return riscv_subset_supports (rps, "q"); - case INSN_CLASS_C: - return (riscv_subset_supports (rps, "c") - || riscv_subset_supports (rps, "zca")); - case INSN_CLASS_F_AND_C: - return (riscv_subset_supports (rps, "f") - && (riscv_subset_supports (rps, "c") - || riscv_subset_supports (rps, "zcf"))); - case INSN_CLASS_D_AND_C: - return (riscv_subset_supports (rps, "d") - && (riscv_subset_supports (rps, "c") - || riscv_subset_supports (rps, "zcd"))); + case INSN_CLASS_ZCA: + return riscv_subset_supports (rps, "zca"); + case INSN_CLASS_ZCF: + return riscv_subset_supports (rps, "zcf"); + case INSN_CLASS_ZCD: + return riscv_subset_supports (rps, "zcd"); case INSN_CLASS_F_INX: return (riscv_subset_supports (rps, "f") || riscv_subset_supports (rps, "zfinx")); @@ -3070,11 +3099,10 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps, return "zicfilp"; case INSN_CLASS_ZIHINTNTL: return "zihintntl"; - case INSN_CLASS_ZIHINTNTL_AND_C: + case INSN_CLASS_ZIHINTNTL_AND_ZCA: if (!riscv_subset_supports (rps, "zihintntl")) { - if (!riscv_subset_supports (rps, "c") - && !riscv_subset_supports (rps, "zca")) + if (!riscv_subset_supports (rps, "zca")) return _("zihintntl' and `c', or `zihintntl' and `zca"); else return "zihintntl"; @@ -3105,30 +3133,12 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps, return "d"; case INSN_CLASS_Q: return "q"; - case INSN_CLASS_C: + case INSN_CLASS_ZCA: return _("c' or `zca"); - case INSN_CLASS_F_AND_C: - if (!riscv_subset_supports (rps, "f")) - { - if (!riscv_subset_supports (rps, "c") - && !riscv_subset_supports (rps, "zcf")) - return _("f' and `c', or `f' and `zcf"); - else - return "f"; - } - else - return _("c' or `zcf"); - case INSN_CLASS_D_AND_C: - if (!riscv_subset_supports (rps, "d")) - { - if (!riscv_subset_supports (rps, "c") - && !riscv_subset_supports (rps, "zcd")) - return _("d' and `c', or `d' and `zcd"); - else - return "d"; - } - else - return _("c' or `zcd"); + case INSN_CLASS_ZCF: + return _("f' and `c', or `zcf"); + case INSN_CLASS_ZCD: + return _("d' and `c', or `zcd"); case INSN_CLASS_F_INX: return _("f' or `zfinx"); case INSN_CLASS_D_INX: |