aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorPatrick O'Neill <patrick@rivosinc.com>2022-01-21 09:22:46 -0800
committerNelson Chu <nelson.chu@sifive.com>2022-02-23 19:45:52 +0800
commite4028336b19998e74a51dd0918a8b3922e08a537 (patch)
tree4c350a0187b397546a7a109acb0e1163e563e2b5 /gas/config
parentdf0a549ebdae74ef9d233243b869d424e6a33c73 (diff)
downloadgdb-e4028336b19998e74a51dd0918a8b3922e08a537.zip
gdb-e4028336b19998e74a51dd0918a8b3922e08a537.tar.gz
gdb-e4028336b19998e74a51dd0918a8b3922e08a537.tar.bz2
RISC-V: PR28733, add missing extension info to 'unrecognized opcode' error
Currently we report errors as "unrecognized opcode `fence.i'" when the opcode isn't part of the selected extensions. This patch expands that error message to include the missing extension information. For example, now the error message would be "unrecognized opcode `fence.i', extension `zifencei' required". If the opcode is not a part of any extension, the error message reverts to "unrecognized opcode `<op statement>'". Signed-off-by: Patrick O'Neill <patrick@rivosinc.com> bfd/ pr 28733 * elfxx-riscv.c (riscv_multi_subset_supports_ext): New function, used to return the extension string for each INSN_CLASS_*. * elfxx-riscv.h: Added extern riscv_multi_subset_supports_ext. gas/ pr 28733 * config/tc-riscv.c (struct riscv_ip_error): New structure, contains information about errors that occur within the riscv_ip. (riscv_ip): Use struct riscv_ip_error to report more detailed errors. * testsuite/gas/riscv/c-fld-fsd-fail.l: Updated. * testsuite/gas/riscv/march-imply-i2p1-01.: Likewise.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-riscv.c61
1 files changed, 47 insertions, 14 deletions
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 55799b1..322e0f0 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -89,6 +89,20 @@ struct riscv_csr_extra
struct riscv_csr_extra *next;
};
+/* This structure contains information about errors that occur within the
+ riscv_ip function */
+struct riscv_ip_error
+{
+ /* General error message */
+ const char* msg;
+
+ /* Statement that caused the error */
+ char* statement;
+
+ /* Missing extension that needs to be enabled */
+ const char* missing_ext;
+};
+
#ifndef DEFAULT_ARCH
#define DEFAULT_ARCH "riscv64"
#endif
@@ -2221,7 +2235,7 @@ riscv_is_priv_insn (insn_t insn)
side effect, it sets the global variable imm_reloc to the type of
relocation to do if one of the operands is an address expression. */
-static const char *
+static struct riscv_ip_error
riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
bfd_reloc_code_real_type *imm_reloc, htab_t hash)
{
@@ -2234,7 +2248,10 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
unsigned int regno;
int argnum;
const struct percent_op_match *p;
- const char *error = "unrecognized opcode";
+ struct riscv_ip_error error;
+ error.msg = "unrecognized opcode";
+ error.statement = str;
+ error.missing_ext = NULL;
/* Indicate we are assembling instruction with CSR. */
bool insn_with_csr = false;
@@ -2257,10 +2274,15 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
continue;
if (!riscv_multi_subset_supports (&riscv_rps_as, insn->insn_class))
- continue;
+ {
+ error.missing_ext = riscv_multi_subset_supports_ext (&riscv_rps_as,
+ insn->insn_class);
+ continue;
+ }
/* Reset error message of the previous round. */
- error = _("illegal operands");
+ error.msg = _("illegal operands");
+ error.missing_ext = NULL;
create_insn (ip, insn);
argnum = 1;
@@ -2310,14 +2332,14 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
&& riscv_subset_supports (&riscv_rps_as, "zve32x")
&& !riscv_subset_supports (&riscv_rps_as, "zve64x"))
{
- error = _("illegal opcode for zve32x");
+ error.msg = _("illegal opcode for zve32x");
break;
}
}
if (*asarg != '\0')
break;
/* Successful assembly. */
- error = NULL;
+ error.msg = NULL;
insn_with_csr = false;
goto out;
@@ -3253,11 +3275,16 @@ md_assemble (char *str)
riscv_mapping_state (MAP_INSN, 0);
- const char *error = riscv_ip (str, &insn, &imm_expr, &imm_reloc, op_hash);
+ const struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
+ &imm_reloc, op_hash);
- if (error)
+ if (error.msg)
{
- as_bad ("%s `%s'", error, str);
+ if (error.missing_ext)
+ as_bad ("%s `%s', extension `%s' required", error.msg,
+ error.statement, error.missing_ext);
+ else
+ as_bad ("%s `%s'", error.msg, error.statement);
return;
}
@@ -4266,17 +4293,23 @@ s_riscv_insn (int x ATTRIBUTE_UNUSED)
riscv_mapping_state (MAP_INSN, 0);
- const char *error = riscv_ip (str, &insn, &imm_expr,
+ struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
&imm_reloc, insn_type_hash);
- if (error)
+ if (error.msg)
{
char *save_in = input_line_pointer;
- error = riscv_ip_hardcode (str, &insn, &imm_expr, error);
+ error.msg = riscv_ip_hardcode (str, &insn, &imm_expr, error.msg);
input_line_pointer = save_in;
}
- if (error)
- as_bad ("%s `%s'", error, str);
+ if (error.msg)
+ {
+ if (error.missing_ext)
+ as_bad ("%s `%s', extension `%s' required", error.msg, error.statement,
+ error.missing_ext);
+ else
+ as_bad ("%s `%s'", error.msg, error.statement);
+ }
else
{
gas_assert (insn.insn_mo->pinfo != INSN_MACRO);