diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index c070394a366..940fd43c0ba 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -1064,11 +1064,25 @@ riscv_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, return bfd_reloc_ok; } +/* Record all implicit information for the subsets. */ + +typedef struct riscv_implicit_subset +{ + const char *subset_name; + const char *implicit_name; + /* A function to determine if we need to add the implicit subset. */ + bool (*check_func) (riscv_parse_subset_t *, + const struct riscv_implicit_subset *, + const riscv_subset_t *); +} riscv_implicit_subset_t; + /* Always add the IMPLICIT for the SUBSET. */ static bool -check_implicit_always (const char *implicit ATTRIBUTE_UNUSED, - riscv_subset_t *subset ATTRIBUTE_UNUSED) +check_implicit_always (riscv_parse_subset_t *rps ATTRIBUTE_UNUSED, + const riscv_implicit_subset_t *implicit + ATTRIBUTE_UNUSED, + const riscv_subset_t *subset ATTRIBUTE_UNUSED) { return true; } @@ -1076,23 +1090,41 @@ check_implicit_always (const char *implicit ATTRIBUTE_UNUSED, /* Add the IMPLICIT only when the version of SUBSET less than 2.1. */ static bool -check_implicit_for_i (const char *implicit ATTRIBUTE_UNUSED, - riscv_subset_t *subset) +check_implicit_for_i (riscv_parse_subset_t *rps ATTRIBUTE_UNUSED, + const riscv_implicit_subset_t *implicit ATTRIBUTE_UNUSED, + const riscv_subset_t *subset) { return (subset->major_version < 2 || (subset->major_version == 2 && subset->minor_version < 1)); } -/* Record all implicit information for the subsets. */ -struct riscv_implicit_subset +/* Add the IMPLICIT only when the 'C' extension is also available. */ + +static bool +check_implicit_for_d_c (riscv_parse_subset_t *rps, + const riscv_implicit_subset_t *implicit + ATTRIBUTE_UNUSED, + const riscv_subset_t *subset ATTRIBUTE_UNUSED) { - const char *subset_name; - const char *implicit_name; - /* A function to determine if we need to add the implicit subset. */ - bool (*check_func) (const char *, riscv_subset_t *); -}; -static struct riscv_implicit_subset riscv_implicit_subsets[] = + return riscv_subset_supports (rps, "c"); +} + +/* Add the IMPLICIT only when the 'C' extension is also available + and XLEN is 32. */ + +static bool +check_implicit_for_f_c (riscv_parse_subset_t *rps, + const riscv_implicit_subset_t *implicit + ATTRIBUTE_UNUSED, + const riscv_subset_t *subset ATTRIBUTE_UNUSED) +{ + return *rps->xlen == 32 && check_implicit_for_d_c (rps, implicit, subset); +} + +/* All extension implications. */ + +static riscv_implicit_subset_t riscv_implicit_subsets[] = { {"e", "i", check_implicit_always}, {"i", "zicsr", check_implicit_for_i}, @@ -1179,6 +1211,7 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] = {"zvksg", "zvkg", check_implicit_always}, {"zvksc", "zvks", check_implicit_always}, {"zvksc", "zvbc", check_implicit_always}, + {"c", "zca", check_implicit_always}, {"zcf", "zca", check_implicit_always}, {"zcd", "zca", check_implicit_always}, {"zcb", "zca", check_implicit_always}, @@ -1191,6 +1224,10 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] = {"ssstateen", "zicsr", check_implicit_always}, {"sstc", "zicsr", check_implicit_always}, {"svadu", "zicsr", check_implicit_always}, + /* Complex implications (that should be checked after others). */ + {"d", "zcd", check_implicit_for_d_c}, + {"f", "zcf", check_implicit_for_f_c}, + /* Tail of the list. */ {NULL, NULL, NULL} }; @@ -1909,7 +1946,7 @@ riscv_parse_extensions (riscv_parse_subset_t *rps, static void riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps) { - struct riscv_implicit_subset *t = riscv_implicit_subsets; + riscv_implicit_subset_t *t = riscv_implicit_subsets; bool finished = false; while (!finished) { @@ -1921,7 +1958,7 @@ riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps) if (riscv_lookup_subset (rps->subset_list, t->subset_name, &subset) && !riscv_lookup_subset (rps->subset_list, t->implicit_name, &implicit_subset) - && t->check_func (t->implicit_name, subset)) + && t->check_func (rps, t, subset)) { riscv_parse_add_subset (rps, t->implicit_name, RISCV_UNKNOWN_VERSION, diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index 5759d3a5fc4..557b5297ba3 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -4339,7 +4339,11 @@ s_riscv_option (int x ATTRIBUTE_UNUSED) } else if (strcmp (name, "norvc") == 0) { - riscv_update_subset (&riscv_rps_as, "-c"); + /* Compatibility: + Disable classic 'C' extension and its subsets. + It won't completely disable them if other enabled extensions + depend on 'C' or 'Zc*'. */ + riscv_update_subset (&riscv_rps_as, "-c,-zca,-zcf,-zcd"); riscv_reset_subsets_list_arch_str (); riscv_set_rvc (false); } diff --git a/gas/testsuite/gas/riscv/attribute-10.d b/gas/testsuite/gas/riscv/attribute-10.d index f46692275f1..d93b42a98fa 100644 --- a/gas/testsuite/gas/riscv/attribute-10.d +++ b/gas/testsuite/gas/riscv/attribute-10.d @@ -3,4 +3,4 @@ #source: empty.s Attribute Section: riscv File Attributes - Tag_RISCV_arch: "rv32i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0" + Tag_RISCV_arch: "rv32i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zca1p0_zcd1p0_zcf1p0" diff --git a/gas/testsuite/gas/riscv/dis-addr-overflow-32.d b/gas/testsuite/gas/riscv/dis-addr-overflow-32.d index 43f712a2263..c581a285366 100644 --- a/gas/testsuite/gas/riscv/dis-addr-overflow-32.d +++ b/gas/testsuite/gas/riscv/dis-addr-overflow-32.d @@ -1,4 +1,4 @@ -#as: -march=rv32ic +#as: -march=rv32i_zca #source: dis-addr-overflow.s #objdump: -d diff --git a/gas/testsuite/gas/riscv/dis-addr-overflow-64.d b/gas/testsuite/gas/riscv/dis-addr-overflow-64.d index 065ee2591e7..b8f9d1339a3 100644 --- a/gas/testsuite/gas/riscv/dis-addr-overflow-64.d +++ b/gas/testsuite/gas/riscv/dis-addr-overflow-64.d @@ -1,4 +1,4 @@ -#as: -march=rv64ic -defsym rv64=1 +#as: -march=rv64i_zca -defsym rv64=1 #source: dis-addr-overflow.s #objdump: -d diff --git a/gas/testsuite/gas/riscv/dis-addr-overflow.s b/gas/testsuite/gas/riscv/dis-addr-overflow.s index 77ca39c07b6..2ce3a904c1a 100644 --- a/gas/testsuite/gas/riscv/dis-addr-overflow.s +++ b/gas/testsuite/gas/riscv/dis-addr-overflow.s @@ -24,7 +24,7 @@ topbase = 0 target: .option push - .option arch, -c + .option arch, -zca ## Use hi_addr # Load lui t0, 0xfffff @@ -50,7 +50,7 @@ target: c.addi t6, -20 .ifdef rv64 .option push - .option arch, -c + .option arch, -zca # ADDIW (not compressed) lui s6, 0xffff8 addiw s7, s6, -24 diff --git a/gas/testsuite/gas/riscv/mapping-symbols.d b/gas/testsuite/gas/riscv/mapping-symbols.d index 40df3409736..3008157dc04 100644 --- a/gas/testsuite/gas/riscv/mapping-symbols.d +++ b/gas/testsuite/gas/riscv/mapping-symbols.d @@ -9,44 +9,44 @@ SYMBOL TABLE: 0+00 l d .data 0+00 .data 0+00 l d .bss 0+00 .bss 0+00 l d .text.cross.section.A 0+00 .text.cross.section.A -0+00 l .text.cross.section.A 0+00 \$xrv32i2p1_c2p0 +0+00 l .text.cross.section.A 0+00 \$xrv32i2p1_zca1p0 0+00 l d .text.corss.section.B 0+00 .text.corss.section.B -0+00 l .text.corss.section.B 0+00 \$xrv32i2p1_c2p0 +0+00 l .text.corss.section.B 0+00 \$xrv32i2p1_zca1p0 0+02 l .text.corss.section.B 0+00 \$xrv32i2p1 0+00 l d .text.data 0+00 .text.data 0+00 l .text.data 0+00 \$d -0+08 l .text.data 0+00 \$xrv32i2p1_c2p0 +0+08 l .text.data 0+00 \$xrv32i2p1_zca1p0 0+0c l .text.data 0+00 \$d 0+00 l d .text.odd.align.start.insn 0+00 .text.odd.align.start.insn -0+00 l .text.odd.align.start.insn 0+00 \$xrv32i2p1_c2p0 +0+00 l .text.odd.align.start.insn 0+00 \$xrv32i2p1_zca1p0 0+02 l .text.odd.align.start.insn 0+00 \$d 0+08 l .text.odd.align.start.insn 0+00 \$xrv32i2p1 0+00 l d .text.odd.align.start.data 0+00 .text.odd.align.start.data 0+00 l .text.odd.align.start.data 0+00 \$d 0+00 l d .text.zero.fill.first 0+00 .text.zero.fill.first -0+00 l .text.zero.fill.first 0+00 \$xrv32i2p1_c2p0 +0+00 l .text.zero.fill.first 0+00 \$xrv32i2p1_zca1p0 0+00 l d .text.zero.fill.last 0+00 .text.zero.fill.last -0+00 l .text.zero.fill.last 0+00 \$xrv32i2p1_c2p0 +0+00 l .text.zero.fill.last 0+00 \$xrv32i2p1_zca1p0 0+02 l .text.zero.fill.last 0+00 \$x 0+00 l d .text.zero.fill.align.A 0+00 .text.zero.fill.align.A -0+00 l .text.zero.fill.align.A 0+00 \$xrv32i2p1_c2p0 +0+00 l .text.zero.fill.align.A 0+00 \$xrv32i2p1_zca1p0 0+00 l d .text.zero.fill.align.B 0+00 .text.zero.fill.align.B 0+00 l .text.zero.fill.align.B 0+00 \$xrv32i2p1 0+00 l d .text.last.section 0+00 .text.last.section 0+00 l .text.last.section 0+00 \$xrv32i2p1 0+04 l .text.last.section 0+00 \$d 0+00 l d .text.section.padding 0+00 .text.section.padding -0+00 l .text.section.padding 0+00 \$xrv32i2p1_c2p0 -0+04 l .text.section.padding 0+00 \$xrv32i2p1_a2p1_c2p0 +0+00 l .text.section.padding 0+00 \$xrv32i2p1_zca1p0 +0+04 l .text.section.padding 0+00 \$xrv32i2p1_a2p1_zca1p0 0+06 l .text.section.padding 0+00 \$d 0+00 l d .text.relax.align 0+00 .text.relax.align -0+00 l .text.relax.align 0+00 \$xrv32i2p1_c2p0 +0+00 l .text.relax.align 0+00 \$xrv32i2p1_zca1p0 0+08 l .text.relax.align 0+00 \$xrv32i2p1 0+0a l .text.section.padding 0+00 \$x 0+03 l .text.odd.align.start.insn 0+00 \$d 0+04 l .text.odd.align.start.insn 0+00 \$x 0+01 l .text.odd.align.start.data 0+00 \$d -0+02 l .text.odd.align.start.data 0+00 \$xrv32i2p1_c2p0 +0+02 l .text.odd.align.start.data 0+00 \$xrv32i2p1_zca1p0 0+00 l d .riscv.attributes 0+00 .riscv.attributes 0+00 g .text.cross.section.A 0+00 funcA 0+00 g .text.corss.section.B 0+00 funcB diff --git a/gas/testsuite/gas/riscv/mapping.s b/gas/testsuite/gas/riscv/mapping.s index 3014a69e792..2fbb62977c3 100644 --- a/gas/testsuite/gas/riscv/mapping.s +++ b/gas/testsuite/gas/riscv/mapping.s @@ -1,4 +1,4 @@ -.attribute arch, "rv32ic" +.attribute arch, "rv32i_zca" .option norelax # FIXME: assembler fill the paddings after parsing everything, # so we probably won't fill anything for the norelax region when # the riscv_opts.relax is enabled at somewhere. @@ -8,13 +8,13 @@ .global funcA funcA: addi a0, zero, 1 # rv32i -.option arch, +c -j funcA # rv32ic +.option arch, +zca +j funcA # rv32i_zca .section .text.corss.section.B, "ax" .globl funcB funcB: -addi a0, zero, 2 # rv32ic, need to be added since start of section -.option arch, -c +addi a0, zero, 2 # rv32i_zca, need to be added since start of section +.option arch, -zca j funcB # rv32i .option pop @@ -22,7 +22,7 @@ j funcB # rv32i .option push .word 0 # $d .long 1 -addi a0, zero, 1 # rv32ic +addi a0, zero, 1 # rv32i_zca .data .word 2 # don't add mapping symbols for non-text section .section .text.data @@ -35,10 +35,10 @@ addi a0, zero, 2 # $x, but same as previous addi, so removed .section .text.odd.align.start.insn, "ax" .option push .option norelax -.option arch, +c -addi a0, zero, 1 # $xrv32ic +.option arch, +zca +addi a0, zero, 1 # $xrv32i_zca .byte 1 # $d -.option arch, -c +.option arch, -zca .align 3 # odd alignment, $x replaced by $d + $x addi a0, zero, 2 # $xrv32i .option pop @@ -46,9 +46,9 @@ addi a0, zero, 2 # $xrv32i .section .text.odd.align.start.data, "ax" .option push .option norelax -.option arch, +c +.option arch, +zca .byte 1 # $d -.align 2 # odd alignment, $xrv32ic replaced by $d + $xrv32ic +.align 2 # odd alignment, $xrv32i_zca replaced by $d + $xrv32i_zca addi a0, zero, 1 .option pop @@ -56,13 +56,13 @@ addi a0, zero, 1 .option push .option norelax .fill 1, 0, 0 # $d with zero size, removed in make_mapping_symbol -addi a0, zero, 1 # $xrv32ic +addi a0, zero, 1 # $xrv32i_zca .option pop .section .text.zero.fill.last, "ax" .option push .option norelax -addi a0, zero, 1 # $xrv32ic +addi a0, zero, 1 # $xrv32i_zca .fill 1, 0, 0 # $d with zero size, removed in make_mapping_symbol addi a0, zero, 2 # $x, FIXME: need find a way to remove? .option pop @@ -71,8 +71,8 @@ addi a0, zero, 2 # $x, FIXME: need find a way to remove? .section .text.zero.fill.align.A, "ax" .option push .option norelax -.align 2 # $xrv32ic, .align and .fill are in the different frag, so neither be removed -.fill 1, 0, 0 # $d with zero size, removed in make_mapping_symbol when adding $xrv32ic +.align 2 # $xrv32i_zca, .align and .fill are in the different frag, so neither be removed +.fill 1, 0, 0 # $d with zero size, removed in make_mapping_symbol when adding $xrv32i_zca addi a0, zero, 1 # $x, should be removed in riscv_check_mapping_symbols addi a0, zero, 2 .option pop @@ -81,10 +81,10 @@ addi a0, zero, 2 .section .text.zero.fill.align.B, "ax" .option push .option norelax -.align 2 # $xrv32ic, .align and .fill are in the different frag, so neither be removed, +.align 2 # $xrv32i_zca, .align and .fill are in the different frag, so neither be removed, # but will be removed in riscv_check_mapping_symbols -.fill 1, 0, 0 # $d with zero size, removed in make_mapping_symbol when adding $xrv32ic -.option arch, -c +.fill 1, 0, 0 # $d with zero size, removed in make_mapping_symbol when adding $xrv32i_zca +.option arch, -zca addi a0, zero, 1 # $xrv32i addi a0, zero, 2 .option pop @@ -92,7 +92,7 @@ addi a0, zero, 2 .section .text.last.section, "ax" .option push .option norelax -.option arch, -c +.option arch, -zca addi a0, zero, 1 # $xrv32i .word 1 # $d .align 2 # zero section padding, $x at the end of section, removed in riscv_check_mapping_symbols @@ -102,20 +102,20 @@ addi a0, zero, 1 # $xrv32i .option push .option norelax .align 2 -addi a0, zero, 1 # $rv32ic +addi a0, zero, 1 # $rv32i_zca .option arch, +a .align 2 # 2-byte padding, $x, removed -addi a0, zero, 2 # $xrv32iac +addi a0, zero, 2 # $xrv32ia_zca .word 1 # $d .option pop # 2-byte padding, $x .section .text.relax.align, "ax" .option push .option relax -.option arch, rv32ic -.balign 4 # $xrv32ic, add at the start of section +.option arch, rv32i_zca +.balign 4 # $xrv32i_zca, add at the start of section addi a0, zero, 1 # $x, won't added -.option arch, -c +.option arch, -zca .align 3 # $x, won't added addi a0, zero, 2 # $xrv32i .option pop diff --git a/gas/testsuite/gas/riscv/march-imply-c-d-32.d b/gas/testsuite/gas/riscv/march-imply-c-d-32.d new file mode 100644 index 00000000000..8d9877b6396 --- /dev/null +++ b/gas/testsuite/gas/riscv/march-imply-c-d-32.d @@ -0,0 +1,6 @@ +#as: -march=rv32idc -march-attr -misa-spec=20191213 +#readelf: -A +#source: empty.s +Attribute Section: riscv +File Attributes + Tag_RISCV_arch: "rv32i2p1_f2p2_d2p2_c2p0_zicsr2p0_zca1p0_zcd1p0_zcf1p0" diff --git a/gas/testsuite/gas/riscv/march-imply-c-d-64.d b/gas/testsuite/gas/riscv/march-imply-c-d-64.d new file mode 100644 index 00000000000..31f8fad00da --- /dev/null +++ b/gas/testsuite/gas/riscv/march-imply-c-d-64.d @@ -0,0 +1,6 @@ +#as: -march=rv64idc -march-attr -misa-spec=20191213 +#readelf: -A +#source: empty.s +Attribute Section: riscv +File Attributes + Tag_RISCV_arch: "rv64i2p1_f2p2_d2p2_c2p0_zicsr2p0_zca1p0_zcd1p0" diff --git a/gas/testsuite/gas/riscv/march-imply-c.d b/gas/testsuite/gas/riscv/march-imply-c.d new file mode 100644 index 00000000000..830dd9f2acc --- /dev/null +++ b/gas/testsuite/gas/riscv/march-imply-c.d @@ -0,0 +1,6 @@ +#as: -march=rv32ic -march-attr -misa-spec=20191213 +#readelf: -A +#source: empty.s +Attribute Section: riscv +File Attributes + Tag_RISCV_arch: "rv32i2p1_c2p0_zca1p0" diff --git a/gas/testsuite/gas/riscv/march-ok-reorder.d b/gas/testsuite/gas/riscv/march-ok-reorder.d index 030f8b15018..db92029e759 100644 --- a/gas/testsuite/gas/riscv/march-ok-reorder.d +++ b/gas/testsuite/gas/riscv/march-ok-reorder.d @@ -4,4 +4,4 @@ Attribute Section: riscv File Attributes - Tag_RISCV_arch: "rv32i2p0_m1p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zba1p0_xbar2p0_xfoo2p0" + Tag_RISCV_arch: "rv32i2p0_m1p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zca1p0_zcd1p0_zcf1p0_zba1p0_xbar2p0_xfoo2p0" diff --git a/gas/testsuite/gas/riscv/option-arch-01.s b/gas/testsuite/gas/riscv/option-arch-01.s index 50285fc8c73..1bde865d1ff 100644 --- a/gas/testsuite/gas/riscv/option-arch-01.s +++ b/gas/testsuite/gas/riscv/option-arch-01.s @@ -1,7 +1,7 @@ -.attribute arch, "rv64ic" +.attribute arch, "rv64i_zca" add a0, a0, a1 .option push -.option arch, +d2p0, -c, +xvendor1p0 +.option arch, +d2p0, -zca, +xvendor1p0 add a0, a0, a1 frcsr a0 # Should add mapping symbol with ISA here, and then dump it to frcsr. .option push diff --git a/gas/testsuite/gas/riscv/option-arch-01b.d b/gas/testsuite/gas/riscv/option-arch-01b.d index 8f4284d5f15..5d717697506 100644 --- a/gas/testsuite/gas/riscv/option-arch-01b.d +++ b/gas/testsuite/gas/riscv/option-arch-01b.d @@ -4,5 +4,5 @@ Attribute Section: riscv File Attributes - Tag_RISCV_arch: "rv64i2p0_c2p0" + Tag_RISCV_arch: "rv64i2p0_zca1p0" #... diff --git a/gas/testsuite/gas/riscv/option-arch-02.d b/gas/testsuite/gas/riscv/option-arch-02.d index 3c27419f9d3..8d75b468b25 100644 --- a/gas/testsuite/gas/riscv/option-arch-02.d +++ b/gas/testsuite/gas/riscv/option-arch-02.d @@ -4,5 +4,5 @@ Attribute Section: riscv File Attributes - Tag_RISCV_arch: "rv64i2p0_m3p0_f2p0_d3p0_c2p0_zmmul1p0_xvendor32x3p0" + Tag_RISCV_arch: "rv64i2p0_m3p0_f2p0_d3p0_zmmul1p0_zca1p0_xvendor32x3p0" #... diff --git a/gas/testsuite/gas/riscv/option-arch-02.s b/gas/testsuite/gas/riscv/option-arch-02.s index e0f5de321d6..109875985f4 100644 --- a/gas/testsuite/gas/riscv/option-arch-02.s +++ b/gas/testsuite/gas/riscv/option-arch-02.s @@ -1,7 +1,7 @@ -.attribute arch, "rv64ic" +.attribute arch, "rv64i_zca" add a0, a0, a1 .option push -.option arch, +d2p0, -c, +xvendor1p0 +.option arch, +d2p0, -zca, +xvendor1p0 add a0, a0, a1 frcsr a0 .option pop diff --git a/gas/testsuite/gas/riscv/option-arch-03.d b/gas/testsuite/gas/riscv/option-arch-03.d index 62d7f7d5ed2..06b9c6b375e 100644 --- a/gas/testsuite/gas/riscv/option-arch-03.d +++ b/gas/testsuite/gas/riscv/option-arch-03.d @@ -4,5 +4,5 @@ Attribute Section: riscv File Attributes - Tag_RISCV_arch: "rv32i2p1_c2p0" + Tag_RISCV_arch: "rv32i2p1_c2p0_zca1p0" #... diff --git a/gas/testsuite/gas/riscv/option-arch-03.s b/gas/testsuite/gas/riscv/option-arch-03.s index ccdb1c354b0..60da2605fe3 100644 --- a/gas/testsuite/gas/riscv/option-arch-03.s +++ b/gas/testsuite/gas/riscv/option-arch-03.s @@ -1,3 +1,3 @@ -.attribute arch, "rv64ic" -.option arch, +d2p0, -c +.attribute arch, "rv64i_zca" +.option arch, +d2p0, -zca .option arch, rv32i2p1c2p0