RISC-V: Allow instruction require more than one extension

2018-08-29  Kito Cheng  <kito@andestech.com>

gas/
	* config/tc-riscv.c (riscv_subset_supports): New argument:
	xlen_required.
	(riscv_multi_subset_supports): New function, able to check more
	than one extension.
	(riscv_ip): Use riscv_multi_subset_supports instead of
	riscv_subset_supports.
	(riscv_set_arch): Update call-site for riscv_subset_supports.
	(riscv_after_parse_args): Likewise.

include/
	*opcode/riscv.h (MAX_SUBSET_NUM): New.
	(riscv_opcode): Add xlen_requirement field and change type of
	subset.

opcodes/
	* riscv-dis.c (riscv_disassemble_insn): Check XLEN by
	riscv_opcode.xlen_requirement.
	* riscv-opc.c (riscv_opcodes): Update for struct change.
This commit is contained in:
Jim Wilson 2018-08-30 13:23:12 -07:00
parent a869991180
commit 43135d3b15
7 changed files with 666 additions and 627 deletions

View File

@ -1,3 +1,14 @@
2018-08-30 Kito Cheng <kito@andestech.com>
* config/tc-riscv.c (riscv_subset_supports): New argument:
xlen_required.
(riscv_multi_subset_supports): New function, able to check more
than one extension.
(riscv_ip): Use riscv_multi_subset_supports instead of
riscv_subset_supports.
(riscv_set_arch): Update call-site for riscv_subset_supports.
(riscv_after_parse_args): Likewise.
2018-08-30 H.J. Lu <hongjiu.lu@intel.com>
* testsuite/gas/elf/section14.d: Skip h8300 targets.

View File

@ -113,22 +113,32 @@ struct riscv_subset
static struct riscv_subset *riscv_subsets;
static bfd_boolean
riscv_subset_supports (const char *feature)
riscv_subset_supports (unsigned xlen_required, const char *feature)
{
struct riscv_subset *s;
char *p;
unsigned xlen_required = strtoul (feature, &p, 10);
if (xlen_required && xlen != xlen_required)
return FALSE;
for (s = riscv_subsets; s != NULL; s = s->next)
if (strcasecmp (s->name, p) == 0)
if (strcasecmp (s->name, feature) == 0)
return TRUE;
return FALSE;
}
static bfd_boolean
riscv_multi_subset_supports (unsigned xlen_required, const char *features[])
{
unsigned i = 0;
bfd_boolean supported = TRUE;
for (;features[i]; ++i)
supported = supported && riscv_subset_supports (xlen_required, features[i]);
return supported;
}
static void
riscv_clear_subsets (void)
{
@ -234,16 +244,16 @@ riscv_set_arch (const char *s)
as_fatal ("-march=%s: unsupported ISA subset `%c'", s, *p);
}
if (riscv_subset_supports ("e") && riscv_subset_supports ("f"))
if (riscv_subset_supports (0, "e") && riscv_subset_supports (0, "f"))
as_fatal ("-march=%s: rv32e does not support the `f' extension", s);
if (riscv_subset_supports ("d") && !riscv_subset_supports ("f"))
if (riscv_subset_supports (0, "d") && !riscv_subset_supports (0, "f"))
as_fatal ("-march=%s: `d' extension requires `f' extension", s);
if (riscv_subset_supports ("q") && !riscv_subset_supports ("d"))
if (riscv_subset_supports (0, "q") && !riscv_subset_supports (0, "d"))
as_fatal ("-march=%s: `q' extension requires `d' extension", s);
if (riscv_subset_supports ("q") && xlen < 64)
if (riscv_subset_supports (0, "q") && xlen < 64)
as_fatal ("-march=%s: rv32 does not support the `q' extension", s);
free (extension);
@ -1480,7 +1490,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
argsStart = s;
for ( ; insn && insn->name && strcmp (insn->name, str) == 0; insn++)
{
if (!riscv_subset_supports (insn->subset))
if (!riscv_multi_subset_supports (insn->xlen_requirement, insn->subset))
continue;
create_insn (ip, insn);
@ -2297,14 +2307,14 @@ riscv_after_parse_args (void)
/* Add the RVC extension, regardless of -march, to support .option rvc. */
riscv_set_rvc (FALSE);
if (riscv_subset_supports ("c"))
if (riscv_subset_supports (0, "c"))
riscv_set_rvc (TRUE);
else
riscv_add_subset ("c");
/* Enable RVE if specified by the -march option. */
riscv_set_rve (FALSE);
if (riscv_subset_supports ("e"))
if (riscv_subset_supports (0, "e"))
riscv_set_rve (TRUE);
/* Infer ABI from ISA if not specified on command line. */

View File

@ -1,3 +1,9 @@
2018-08-30 Kito Cheng <kito@andestech.com>
* opcode/riscv.h (MAX_SUBSET_NUM): New.
(riscv_opcode): Add xlen_requirement field and change type of
subset.
2018-08-29 Chenghua Xu <paul.hua.gm@gmail.com>
* elf/mips.h (E_MIPS_MACH_XXX): New E_MIPS_MACH_GS264E.

View File

@ -281,14 +281,20 @@ static const char * const riscv_pred_succ[16] =
#define EXTRACT_OPERAND(FIELD, INSN) \
EXTRACT_BITS ((INSN), OP_MASK_##FIELD, OP_SH_##FIELD)
/* The maximal number of subset can be required. */
#define MAX_SUBSET_NUM 4
/* This structure holds information for a particular instruction. */
struct riscv_opcode
{
/* The name of the instruction. */
const char *name;
/* The ISA subset name (I, M, A, F, D, Xextension). */
const char *subset;
/* The requirement of xlen for the instruction, 0 if no requirement. */
int xlen_requirement;
/* An array of ISA subset name (I, M, A, F, D, Xextension), must ended
with a NULL pointer sential. */
const char *subset[MAX_SUBSET_NUM];
/* A string describing the arguments for this instruction. */
const char *args;
/* The basic opcode for the instruction. When assembling, this

View File

@ -1,3 +1,9 @@
2018-08-30 Kito Cheng <kito@andestech.com>
* riscv-dis.c (riscv_disassemble_insn): Check XLEN by
riscv_opcode.xlen_requirement.
* riscv-opc.c (riscv_opcodes): Update for struct change.
2018-08-29 Martin Aberg <maberg@gaisler.com>
* sparc-opc.c (sparc_opcodes): Add Leon specific partial write

View File

@ -430,7 +430,7 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
if (no_aliases && (op->pinfo & INSN_ALIAS))
continue;
/* Is this instruction restricted to a certain value of XLEN? */
if (isdigit (op->subset[0]) && atoi (op->subset) != xlen)
if ((op->xlen_requirement != 0) && (op->xlen_requirement != xlen))
continue;
/* It's a match. */

File diff suppressed because it is too large Load Diff