Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 46 additions & 14 deletions bfd/elfxx-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1064,35 +1064,57 @@ 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;
}

/* 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 'Zce' extension is also available
and XLEN is 32. */

static bool
check_implicit_for_f_zce (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 *rps->xlen == 32
&& riscv_subset_supports (rps, "zce");
}

/* All extension implications. */

static riscv_implicit_subset_t riscv_implicit_subsets[] =
{
{"e", "i", check_implicit_always},
{"i", "zicsr", check_implicit_for_i},
Expand Down Expand Up @@ -1179,6 +1201,10 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
{"zvksg", "zvkg", check_implicit_always},
{"zvksc", "zvks", check_implicit_always},
{"zvksc", "zvbc", check_implicit_always},
{"zce", "zca", check_implicit_always},
{"zce", "zcb", check_implicit_always},
{"zce", "zcmp", check_implicit_always},
{"zce", "zcmt", check_implicit_always},
{"zcf", "zca", check_implicit_always},
{"zcd", "zca", check_implicit_always},
{"zcb", "zca", check_implicit_always},
Expand All @@ -1191,6 +1217,9 @@ 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). */
{"f", "zcf", check_implicit_for_f_zce},
/* Tail of the list. */
{NULL, NULL, NULL}
};

Expand Down Expand Up @@ -1324,6 +1353,9 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
{"zcb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zcf", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zcd", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zce", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zcmp", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zcmt", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{NULL, 0, 0, 0, 0}
};

Expand Down Expand Up @@ -1909,7 +1941,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)
{
Expand All @@ -1921,7 +1953,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,
Expand Down
6 changes: 6 additions & 0 deletions gas/testsuite/gas/riscv/march-imply-zce-f-32.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#as: -march=rv32if_zce -march-attr -misa-spec=20191213
#readelf: -A
#source: empty.s
Attribute Section: riscv
File Attributes
Tag_RISCV_arch: "rv32i2p1_f2p2_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcf1p0_zcmp1p0_zcmt1p0"
6 changes: 6 additions & 0 deletions gas/testsuite/gas/riscv/march-imply-zce-f-64.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#as: -march=rv64if_zce -march-attr -misa-spec=20191213
#readelf: -A
#source: empty.s
Attribute Section: riscv
File Attributes
Tag_RISCV_arch: "rv64i2p1_f2p2_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0"
6 changes: 6 additions & 0 deletions gas/testsuite/gas/riscv/march-imply-zce.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#as: -march=rv32i_zce -march-attr -misa-spec=20191213
#readelf: -A
#source: empty.s
Attribute Section: riscv
File Attributes
Tag_RISCV_arch: "rv32i2p1_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0"