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:
parent
a869991180
commit
43135d3b15
@ -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.
|
||||
|
@ -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. */
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
1226
opcodes/riscv-opc.c
1226
opcodes/riscv-opc.c
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user