#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/riscv.h"
+#include "opcode/riscv.h"
#include "libiberty.h"
#include "elfxx-riscv.h"
#include "safe-ctype.h"
+#include "cpu-riscv.h"
#define MINUS_ONE ((bfd_vma)0 - 1)
"R_RISCV_BRANCH", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
- ENCODE_SBTYPE_IMM (-1U), /* dst_mask */
+ ENCODE_BTYPE_IMM (-1U), /* dst_mask */
TRUE), /* pcrel_offset */
/* 20-bit PC-relative jump offset. */
"R_RISCV_JAL", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
- ENCODE_UJTYPE_IMM (-1U), /* dst_mask */
+ ENCODE_JTYPE_IMM (-1U), /* dst_mask */
TRUE), /* pcrel_offset */
/* 32-bit PC-relative function call (AUIPC/JALR). */
"R_RISCV_RVC_BRANCH", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
- ENCODE_RVC_B_IMM (-1U), /* dst_mask */
+ ENCODE_CBTYPE_IMM (-1U), /* dst_mask */
TRUE), /* pcrel_offset */
/* 11-bit PC-relative jump offset. */
"R_RISCV_RVC_JUMP", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
- ENCODE_RVC_J_IMM (-1U), /* dst_mask */
+ ENCODE_CJTYPE_IMM (-1U), /* dst_mask */
TRUE), /* pcrel_offset */
/* High 6 bits of 18-bit absolute address. */
"R_RISCV_RVC_LUI", /* name */
FALSE, /* partial_inplace */
0, /* src_mask */
- ENCODE_RVC_IMM (-1U), /* dst_mask */
+ ENCODE_CITYPE_IMM (-1U), /* dst_mask */
FALSE), /* pcrel_offset */
/* GP-relative load. */
};
/* A mapping from BFD reloc types to RISC-V ELF reloc types. */
-
struct elf_reloc_map
{
bfd_reloc_code_real_type bfd_val;
return bfd_reloc_ok;
}
-/* Array is used to compare the all extensions' order quickly.
+#define RISCV_UNKNOWN_VERSION -1
- Zero number means it is a preserved keyword.
- Negative number means it is a prefix keyword (s, h, x, z).
- Positive number means it is a standard extension. */
+/* Array is used to compare the orders of all extensions quickly.
+ Zero value: Preserved keyword.
+ Negative value: Prefixed keyword (s, h, x, z).
+ Positive value: Standard extension. */
static int riscv_ext_order[26] = {0};
/* Similar to the strcmp. It returns an integer less than, equal to,
or greater than zero if `subset2` is found, respectively, to be less
than, to match, or be greater than `subset1`. */
-static int
+int
riscv_compare_subsets (const char *subset1, const char *subset2)
{
int order1 = riscv_ext_order[(*subset1 - 'a')];
return FALSE;
}
-/* Add arch string extension to the last of the subset list. */
+/* Add extension from ISA string to the last of the subset list. */
void
riscv_add_subset (riscv_subset_list_t *subset_list,
/* These extensions are added to the subset list for special purposes,
with the explicit versions or the RISCV_UNKNOWN_VERSION versions.
- Therefore, we won't output them to the output arch string in the
+ Therefore, we won't output them to the output ISA string in the
riscv_arch_str1, if the versions are unknown. */
static bfd_boolean
return FALSE;
}
-/* We have to add all arch string extensions first, and then start to
- add their implicit extensions. The arch string extensions must be
+/* We have to add all extensions from ISA string first, and then start to
+ add their implicit extensions. The extensions from ISA string must be
set in order, so we can add them to the last of the subset list
directly, without searching.
Arguments:
`rps`: Hooks and status for parsing extensions.
- `march`: Full arch string.
+ `march`: Full ISA string.
`p`: Curent parsing position.
`major_version`: Parsed major version.
`minor_version`: Parsed minor version.
Arguments:
`rps`: Hooks and status for parsing extensions.
- `march`: Full arch string.
+ `march`: Full ISA string.
`p`: Curent parsing position. */
static const char *
RISCV_UNKNOWN_VERSION,
RISCV_UNKNOWN_VERSION, FALSE);
/* g-ext is used to add the implicit extensions, but will
- not be output to the arch string. */
+ not be output to the ISA string. */
riscv_parse_add_subset (rps, "g",
major_version,
minor_version, FALSE);
return p;
}
-/* Classify the argument 'arch' into one of riscv_isa_ext_class_t. */
+/* Classify ARCH into one of riscv_isa_ext_class_t. */
riscv_isa_ext_class_t
riscv_get_prefix_class (const char *arch)
}
/* Structure describing parameters to use when parsing a particular
- riscv_isa_ext_class_t. One of these should be provided for each
+ riscv_isa_ext_class_t. One of these should be provided for each
possible class, except RV_ISA_CLASS_UNKNOWN. */
-
typedef struct riscv_parse_config
{
/* Class of the extension. */
Arguments:
`rps`: Hooks and status for parsing extensions.
- `march`: Full architecture string.
+ `march`: Full ISA string.
`p`: Curent parsing position.
`config`: What class and predicate function to use for the
extension. */
riscv_parse_add_subset (rps, subset,
major_version,
minor_version, FALSE);
- free (subset);
p += end_of_version - subset;
+ free (subset);
if (*p != '\0' && *p != '_')
{
static const char * const riscv_std_z_ext_strtab[] =
{
- "zicsr", "zifencei", NULL
+ "zba", "zbb", "zbc", "zicsr", "zifencei", "zihintpause", NULL
};
static const char * const riscv_std_s_ext_strtab[] =
/* Parsing order of the prefixed extensions that is specified by
the ISA spec. */
-
static const riscv_parse_config_t parse_config[] =
{
{RV_ISA_CLASS_S, "s", riscv_ext_s_valid_p},
if (inited)
return;
- /* All standard extensions' orders are positive numbers. */
+ /* The orders of all standard extensions are positive. */
order = 1;
/* Init the standard base extensions first. */
for (ext = std_remain_exts; *ext; ext++)
riscv_ext_order[(*ext - 'a')] = order++;
- /* Init the order for prefixed keywords. The orders are
- negative numbers. */
+ /* Init the order for prefixed keywords. The orders are negative. */
order = -1;
for (i = 0; parse_config[i].class != RV_ISA_CLASS_UNKNOWN; i++)
{
inited = TRUE;
}
-/* Add the implicit extensions according to the arch string extensions. */
+/* Add the implicit extensions. */
static void
riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps)
}
}
-/* Function for parsing arch string.
+/* Function for parsing ISA string.
Return Value:
Return TRUE on success.
Arguments:
`rps`: Hooks and status for parsing extensions.
- `arch`: Full arch string. */
+ `arch`: Full ISA string. */
bfd_boolean
riscv_parse_subset (riscv_parse_subset_t *rps,
}
else
{
- /* Arch string shouldn't be NULL or empty here. However,
- it might be empty only when we failed to merge the arch
+ /* ISA string shouldn't be NULL or empty here. However,
+ it might be empty only when we failed to merge the ISA
string in the riscv_merge_attributes. We have already
issued the correct error message in another side, so do
- not issue this error when the arch string is empty. */
+ not issue this error when the ISA string is empty. */
if (strlen (arch))
rps->error_handler (
_("-march=%s: ISA string must begin with rv32 or rv64"),
return riscv_estimate_arch_strlen1 (subset->next)
+ strlen (subset->name)
+ riscv_estimate_digit (subset->major_version)
- + 1 /* For version seperator: 'p'. */
+ + 1 /* For version seperator 'p'. */
+ riscv_estimate_digit (subset->minor_version)
+ 1 /* For underscore. */;
}
if (subset_t == NULL)
return;
- /* No underline between rvXX and i/e. */
+ /* No underline between rvXX and i/e. */
if ((strcasecmp (subset_t->name, "i") == 0)
|| (strcasecmp (subset_t->name, "e") == 0))
underline = "";
riscv_arch_str1 (subset_t->next, attr_str, buf, bufsz);
}
-/* Convert subset info to string with explicit version info. */
+/* Convert subset information into string with explicit versions. */
char *
riscv_arch_str (unsigned xlen, const riscv_subset_list_t *subset)