public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] add missing extension info to 'unrecognized opcode' error
@ 2022-01-21 17:22 Patrick O'Neill
  2022-02-23 12:07 ` Nelson Chu
  0 siblings, 1 reply; 2+ messages in thread
From: Patrick O'Neill @ 2022-01-21 17:22 UTC (permalink / raw)
  To: binutils; +Cc: nelsonc1225, palmer, Patrick O'Neill

PR 28733

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/elfxx-riscv.c                             | 94 +++++++++++++++++++
 bfd/elfxx-riscv.h                             |  3 +
 gas/config/tc-riscv.c                         | 62 +++++++++---
 gas/testsuite/gas/riscv/c-fld-fsd-fail.l      |  4 +-
 gas/testsuite/gas/riscv/march-imply-i2p1-01.l | 40 ++++----
 5 files changed, 167 insertions(+), 36 deletions(-)

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 9f52bb545ac..d52272ab0ce 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -2414,3 +2414,97 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
       return false;
     }
 }
+
+/* Each instuction is belonged to an instruction class INSN_CLASS_*.
+   Call riscv_subset_supports_ext to determine the missing extension.  */
+
+const char *
+riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
+				 enum riscv_insn_class insn_class)
+{
+  switch (insn_class)
+    {
+    case INSN_CLASS_I:
+      return "i";
+    case INSN_CLASS_ZICSR:
+      return "zicsr";
+    case INSN_CLASS_ZIFENCEI:
+      return "zifencei";
+    case INSN_CLASS_ZIHINTPAUSE:
+      return "zihintpause";
+    case INSN_CLASS_M:
+      return "m";
+    case INSN_CLASS_A:
+      return "a";
+    case INSN_CLASS_F:
+      return "f";
+    case INSN_CLASS_D:
+      return "d";
+    case INSN_CLASS_Q:
+      return "q";
+    case INSN_CLASS_C:
+      return "c";
+    case INSN_CLASS_F_AND_C:
+      if (!riscv_subset_supports (rps, "f")
+	      && !riscv_subset_supports (rps, "c"))
+		  return "f' and `c";
+	  else if (!riscv_subset_supports (rps, "f"))
+	    return "f";
+	  else
+	    return "c";
+    case INSN_CLASS_D_AND_C:
+	  if (!riscv_subset_supports (rps, "d")
+	      && !riscv_subset_supports (rps, "c"))
+		  return "d' and `c";
+	  else if (!riscv_subset_supports (rps, "d"))
+	    return "d";
+	  else
+	    return "c";
+    case INSN_CLASS_F_OR_ZFINX:
+      return "f' or `zfinx";
+    case INSN_CLASS_D_OR_ZDINX:
+      return "d' or `zdinx";
+    case INSN_CLASS_Q_OR_ZQINX:
+      return "q' or `zqinx";
+    case INSN_CLASS_ZBA:
+      return "zba";
+    case INSN_CLASS_ZBB:
+      return "zbb";
+    case INSN_CLASS_ZBC:
+      return "zbc";
+    case INSN_CLASS_ZBS:
+      return "zbs";
+    case INSN_CLASS_ZBKB:
+      return "zbkb";
+    case INSN_CLASS_ZBKC:
+      return "zbkc";
+    case INSN_CLASS_ZBKX:
+      return "zbkx";
+    case INSN_CLASS_ZBB_OR_ZBKB:
+      return "zbb' or `zbkb";
+    case INSN_CLASS_ZBC_OR_ZBKC:
+      return "zbc' or `zbkc";
+    case INSN_CLASS_ZKND:
+      return "zknd";
+    case INSN_CLASS_ZKNE:
+      return "zkne";
+    case INSN_CLASS_ZKNH:
+      return "zknh";
+    case INSN_CLASS_ZKND_OR_ZKNE:
+      return "zknd' or `zkne";
+    case INSN_CLASS_ZKSED:
+      return "zksed";
+    case INSN_CLASS_ZKSH:
+      return "zksh";
+    case INSN_CLASS_V:
+      return "v' or `zve64x' or `zve32x";
+    case INSN_CLASS_ZVEF:
+      return "v' or `zve64d' or `zve64f' or `zve32f";
+    case INSN_CLASS_SVINVAL:
+      return "svinval";
+    default:
+      rps->error_handler
+        (_("internal: unreachable INSN_CLASS_*"));
+      return NULL;
+    }
+}
diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h
index 67b7d078232..ea7126bdb4d 100644
--- a/bfd/elfxx-riscv.h
+++ b/bfd/elfxx-riscv.h
@@ -104,6 +104,9 @@ riscv_subset_supports (riscv_parse_subset_t *, const char *);
 extern bool
 riscv_multi_subset_supports (riscv_parse_subset_t *, enum riscv_insn_class);
 
+extern const char *
+riscv_multi_subset_supports_ext (riscv_parse_subset_t *, enum riscv_insn_class);
+
 extern void
 bfd_elf32_riscv_set_data_segment_info (struct bfd_link_info *, int *);
 extern void
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index ebad2e0b0a1..5e9fa75496a 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -33,6 +33,7 @@
 #include "elf/riscv.h"
 #include "opcode/riscv.h"
 
+#include <assert.h>
 #include <stdint.h>
 
 /* Information about an instruction, including its format, operands
@@ -89,6 +90,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
@@ -2225,7 +2240,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)
 {
@@ -2238,7 +2253,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;
 
@@ -2261,10 +2279,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;
 
@@ -2314,14 +2337,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;
 
@@ -3257,11 +3280,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;
     }
 
@@ -4264,17 +4292,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);
diff --git a/gas/testsuite/gas/riscv/c-fld-fsd-fail.l b/gas/testsuite/gas/riscv/c-fld-fsd-fail.l
index 7d99abbaad8..b701fac14c0 100644
--- a/gas/testsuite/gas/riscv/c-fld-fsd-fail.l
+++ b/gas/testsuite/gas/riscv/c-fld-fsd-fail.l
@@ -1,3 +1,3 @@
 .*: Assembler messages:
-.*: Error: unrecognized opcode `fld fa0,0\(a0\)'
-.*: Error: unrecognized opcode `fsd fa0,0\(a0\)'
+.*: Error: unrecognized opcode `fld fa0,0\(a0\)', extension `d' required
+.*: Error: unrecognized opcode `fsd fa0,0\(a0\)', extension `d' required
diff --git a/gas/testsuite/gas/riscv/march-imply-i2p1-01.l b/gas/testsuite/gas/riscv/march-imply-i2p1-01.l
index b54d4ae9acd..7fbee14fe83 100644
--- a/gas/testsuite/gas/riscv/march-imply-i2p1-01.l
+++ b/gas/testsuite/gas/riscv/march-imply-i2p1-01.l
@@ -1,21 +1,21 @@
 .*Assembler messages:
-.*Error: unrecognized opcode `csrr t0,ustatus'
-.*Error: unrecognized opcode `csrwi ustatus,0x0'
-.*Error: unrecognized opcode `csrsi ustatus,0x0'
-.*Error: unrecognized opcode `csrci ustatus,0x0'
-.*Error: unrecognized opcode `csrw ustatus,t0'
-.*Error: unrecognized opcode `csrw ustatus,0x0'
-.*Error: unrecognized opcode `csrs ustatus,t0'
-.*Error: unrecognized opcode `csrs ustatus,0x0'
-.*Error: unrecognized opcode `csrc ustatus,t0'
-.*Error: unrecognized opcode `csrc ustatus,0x0'
-.*Error: unrecognized opcode `csrrwi t0,ustatus,0x0'
-.*Error: unrecognized opcode `csrrsi t0,ustatus,0x0'
-.*Error: unrecognized opcode `csrrci t0,ustatus,0x0'
-.*Error: unrecognized opcode `csrrw t0,ustatus,t0'
-.*Error: unrecognized opcode `csrrw t0,ustatus,0x0'
-.*Error: unrecognized opcode `csrrs t0,ustatus,t0'
-.*Error: unrecognized opcode `csrrs t0,ustatus,0x0'
-.*Error: unrecognized opcode `csrrc t0,ustatus,t0'
-.*Error: unrecognized opcode `csrrc t0,ustatus,0x0'
-.*Error: unrecognized opcode `fence.i'
+.*Error: unrecognized opcode `csrr t0,ustatus', extension `zicsr' required
+.*Error: unrecognized opcode `csrwi ustatus,0x0', extension `zicsr' required
+.*Error: unrecognized opcode `csrsi ustatus,0x0', extension `zicsr' required
+.*Error: unrecognized opcode `csrci ustatus,0x0', extension `zicsr' required
+.*Error: unrecognized opcode `csrw ustatus,t0', extension `zicsr' required
+.*Error: unrecognized opcode `csrw ustatus,0x0', extension `zicsr' required
+.*Error: unrecognized opcode `csrs ustatus,t0', extension `zicsr' required
+.*Error: unrecognized opcode `csrs ustatus,0x0', extension `zicsr' required
+.*Error: unrecognized opcode `csrc ustatus,t0', extension `zicsr' required
+.*Error: unrecognized opcode `csrc ustatus,0x0', extension `zicsr' required
+.*Error: unrecognized opcode `csrrwi t0,ustatus,0x0', extension `zicsr' required
+.*Error: unrecognized opcode `csrrsi t0,ustatus,0x0', extension `zicsr' required
+.*Error: unrecognized opcode `csrrci t0,ustatus,0x0', extension `zicsr' required
+.*Error: unrecognized opcode `csrrw t0,ustatus,t0', extension `zicsr' required
+.*Error: unrecognized opcode `csrrw t0,ustatus,0x0', extension `zicsr' required
+.*Error: unrecognized opcode `csrrs t0,ustatus,t0', extension `zicsr' required
+.*Error: unrecognized opcode `csrrs t0,ustatus,0x0', extension `zicsr' required
+.*Error: unrecognized opcode `csrrc t0,ustatus,t0', extension `zicsr' required
+.*Error: unrecognized opcode `csrrc t0,ustatus,0x0', extension `zicsr' required
+.*Error: unrecognized opcode `fence.i', extension `zifencei' required
-- 
2.25.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] add missing extension info to 'unrecognized opcode' error
  2022-01-21 17:22 [PATCH] add missing extension info to 'unrecognized opcode' error Patrick O'Neill
@ 2022-02-23 12:07 ` Nelson Chu
  0 siblings, 0 replies; 2+ messages in thread
From: Nelson Chu @ 2022-02-23 12:07 UTC (permalink / raw)
  To: Patrick O'Neill; +Cc: Binutils, palmer, nelsonc1225

On Sat, Jan 22, 2022 at 1:23 AM Patrick O'Neill <patrick@rivosinc.com> wrote:
>
> PR 28733
>
> 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>'".

It would be better to add more testcases to test the new errors, but
we could always add them later in the future patches.  The patch looks
good to me, so committed, thanks.

Nelson

> Signed-off-by: Patrick O'Neill <patrick@rivosinc.com>
> ---
>  bfd/elfxx-riscv.c                             | 94 +++++++++++++++++++
>  bfd/elfxx-riscv.h                             |  3 +
>  gas/config/tc-riscv.c                         | 62 +++++++++---
>  gas/testsuite/gas/riscv/c-fld-fsd-fail.l      |  4 +-
>  gas/testsuite/gas/riscv/march-imply-i2p1-01.l | 40 ++++----
>  5 files changed, 167 insertions(+), 36 deletions(-)
>
> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> index 9f52bb545ac..d52272ab0ce 100644
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -2414,3 +2414,97 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
>        return false;
>      }
>  }
> +
> +/* Each instuction is belonged to an instruction class INSN_CLASS_*.
> +   Call riscv_subset_supports_ext to determine the missing extension.  */
> +
> +const char *
> +riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
> +                                enum riscv_insn_class insn_class)
> +{
> +  switch (insn_class)
> +    {
> +    case INSN_CLASS_I:
> +      return "i";
> +    case INSN_CLASS_ZICSR:
> +      return "zicsr";
> +    case INSN_CLASS_ZIFENCEI:
> +      return "zifencei";
> +    case INSN_CLASS_ZIHINTPAUSE:
> +      return "zihintpause";
> +    case INSN_CLASS_M:
> +      return "m";
> +    case INSN_CLASS_A:
> +      return "a";
> +    case INSN_CLASS_F:
> +      return "f";
> +    case INSN_CLASS_D:
> +      return "d";
> +    case INSN_CLASS_Q:
> +      return "q";
> +    case INSN_CLASS_C:
> +      return "c";
> +    case INSN_CLASS_F_AND_C:
> +      if (!riscv_subset_supports (rps, "f")
> +             && !riscv_subset_supports (rps, "c"))
> +                 return "f' and `c";
> +         else if (!riscv_subset_supports (rps, "f"))
> +           return "f";
> +         else
> +           return "c";
> +    case INSN_CLASS_D_AND_C:
> +         if (!riscv_subset_supports (rps, "d")
> +             && !riscv_subset_supports (rps, "c"))
> +                 return "d' and `c";
> +         else if (!riscv_subset_supports (rps, "d"))
> +           return "d";
> +         else
> +           return "c";
> +    case INSN_CLASS_F_OR_ZFINX:
> +      return "f' or `zfinx";
> +    case INSN_CLASS_D_OR_ZDINX:
> +      return "d' or `zdinx";
> +    case INSN_CLASS_Q_OR_ZQINX:
> +      return "q' or `zqinx";
> +    case INSN_CLASS_ZBA:
> +      return "zba";
> +    case INSN_CLASS_ZBB:
> +      return "zbb";
> +    case INSN_CLASS_ZBC:
> +      return "zbc";
> +    case INSN_CLASS_ZBS:
> +      return "zbs";
> +    case INSN_CLASS_ZBKB:
> +      return "zbkb";
> +    case INSN_CLASS_ZBKC:
> +      return "zbkc";
> +    case INSN_CLASS_ZBKX:
> +      return "zbkx";
> +    case INSN_CLASS_ZBB_OR_ZBKB:
> +      return "zbb' or `zbkb";
> +    case INSN_CLASS_ZBC_OR_ZBKC:
> +      return "zbc' or `zbkc";
> +    case INSN_CLASS_ZKND:
> +      return "zknd";
> +    case INSN_CLASS_ZKNE:
> +      return "zkne";
> +    case INSN_CLASS_ZKNH:
> +      return "zknh";
> +    case INSN_CLASS_ZKND_OR_ZKNE:
> +      return "zknd' or `zkne";
> +    case INSN_CLASS_ZKSED:
> +      return "zksed";
> +    case INSN_CLASS_ZKSH:
> +      return "zksh";
> +    case INSN_CLASS_V:
> +      return "v' or `zve64x' or `zve32x";
> +    case INSN_CLASS_ZVEF:
> +      return "v' or `zve64d' or `zve64f' or `zve32f";
> +    case INSN_CLASS_SVINVAL:
> +      return "svinval";
> +    default:
> +      rps->error_handler
> +        (_("internal: unreachable INSN_CLASS_*"));
> +      return NULL;
> +    }
> +}
> diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h
> index 67b7d078232..ea7126bdb4d 100644
> --- a/bfd/elfxx-riscv.h
> +++ b/bfd/elfxx-riscv.h
> @@ -104,6 +104,9 @@ riscv_subset_supports (riscv_parse_subset_t *, const char *);
>  extern bool
>  riscv_multi_subset_supports (riscv_parse_subset_t *, enum riscv_insn_class);
>
> +extern const char *
> +riscv_multi_subset_supports_ext (riscv_parse_subset_t *, enum riscv_insn_class);
> +
>  extern void
>  bfd_elf32_riscv_set_data_segment_info (struct bfd_link_info *, int *);
>  extern void
> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> index ebad2e0b0a1..5e9fa75496a 100644
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -33,6 +33,7 @@
>  #include "elf/riscv.h"
>  #include "opcode/riscv.h"
>
> +#include <assert.h>
>  #include <stdint.h>
>
>  /* Information about an instruction, including its format, operands
> @@ -89,6 +90,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
> @@ -2225,7 +2240,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)
>  {
> @@ -2238,7 +2253,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;
>
> @@ -2261,10 +2279,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;
>
> @@ -2314,14 +2337,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;
>
> @@ -3257,11 +3280,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;
>      }
>
> @@ -4264,17 +4292,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);
> diff --git a/gas/testsuite/gas/riscv/c-fld-fsd-fail.l b/gas/testsuite/gas/riscv/c-fld-fsd-fail.l
> index 7d99abbaad8..b701fac14c0 100644
> --- a/gas/testsuite/gas/riscv/c-fld-fsd-fail.l
> +++ b/gas/testsuite/gas/riscv/c-fld-fsd-fail.l
> @@ -1,3 +1,3 @@
>  .*: Assembler messages:
> -.*: Error: unrecognized opcode `fld fa0,0\(a0\)'
> -.*: Error: unrecognized opcode `fsd fa0,0\(a0\)'
> +.*: Error: unrecognized opcode `fld fa0,0\(a0\)', extension `d' required
> +.*: Error: unrecognized opcode `fsd fa0,0\(a0\)', extension `d' required
> diff --git a/gas/testsuite/gas/riscv/march-imply-i2p1-01.l b/gas/testsuite/gas/riscv/march-imply-i2p1-01.l
> index b54d4ae9acd..7fbee14fe83 100644
> --- a/gas/testsuite/gas/riscv/march-imply-i2p1-01.l
> +++ b/gas/testsuite/gas/riscv/march-imply-i2p1-01.l
> @@ -1,21 +1,21 @@
>  .*Assembler messages:
> -.*Error: unrecognized opcode `csrr t0,ustatus'
> -.*Error: unrecognized opcode `csrwi ustatus,0x0'
> -.*Error: unrecognized opcode `csrsi ustatus,0x0'
> -.*Error: unrecognized opcode `csrci ustatus,0x0'
> -.*Error: unrecognized opcode `csrw ustatus,t0'
> -.*Error: unrecognized opcode `csrw ustatus,0x0'
> -.*Error: unrecognized opcode `csrs ustatus,t0'
> -.*Error: unrecognized opcode `csrs ustatus,0x0'
> -.*Error: unrecognized opcode `csrc ustatus,t0'
> -.*Error: unrecognized opcode `csrc ustatus,0x0'
> -.*Error: unrecognized opcode `csrrwi t0,ustatus,0x0'
> -.*Error: unrecognized opcode `csrrsi t0,ustatus,0x0'
> -.*Error: unrecognized opcode `csrrci t0,ustatus,0x0'
> -.*Error: unrecognized opcode `csrrw t0,ustatus,t0'
> -.*Error: unrecognized opcode `csrrw t0,ustatus,0x0'
> -.*Error: unrecognized opcode `csrrs t0,ustatus,t0'
> -.*Error: unrecognized opcode `csrrs t0,ustatus,0x0'
> -.*Error: unrecognized opcode `csrrc t0,ustatus,t0'
> -.*Error: unrecognized opcode `csrrc t0,ustatus,0x0'
> -.*Error: unrecognized opcode `fence.i'
> +.*Error: unrecognized opcode `csrr t0,ustatus', extension `zicsr' required
> +.*Error: unrecognized opcode `csrwi ustatus,0x0', extension `zicsr' required
> +.*Error: unrecognized opcode `csrsi ustatus,0x0', extension `zicsr' required
> +.*Error: unrecognized opcode `csrci ustatus,0x0', extension `zicsr' required
> +.*Error: unrecognized opcode `csrw ustatus,t0', extension `zicsr' required
> +.*Error: unrecognized opcode `csrw ustatus,0x0', extension `zicsr' required
> +.*Error: unrecognized opcode `csrs ustatus,t0', extension `zicsr' required
> +.*Error: unrecognized opcode `csrs ustatus,0x0', extension `zicsr' required
> +.*Error: unrecognized opcode `csrc ustatus,t0', extension `zicsr' required
> +.*Error: unrecognized opcode `csrc ustatus,0x0', extension `zicsr' required
> +.*Error: unrecognized opcode `csrrwi t0,ustatus,0x0', extension `zicsr' required
> +.*Error: unrecognized opcode `csrrsi t0,ustatus,0x0', extension `zicsr' required
> +.*Error: unrecognized opcode `csrrci t0,ustatus,0x0', extension `zicsr' required
> +.*Error: unrecognized opcode `csrrw t0,ustatus,t0', extension `zicsr' required
> +.*Error: unrecognized opcode `csrrw t0,ustatus,0x0', extension `zicsr' required
> +.*Error: unrecognized opcode `csrrs t0,ustatus,t0', extension `zicsr' required
> +.*Error: unrecognized opcode `csrrs t0,ustatus,0x0', extension `zicsr' required
> +.*Error: unrecognized opcode `csrrc t0,ustatus,t0', extension `zicsr' required
> +.*Error: unrecognized opcode `csrrc t0,ustatus,0x0', extension `zicsr' required
> +.*Error: unrecognized opcode `fence.i', extension `zifencei' required
> --
> 2.25.1
>

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-02-23 12:07 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-21 17:22 [PATCH] add missing extension info to 'unrecognized opcode' error Patrick O'Neill
2022-02-23 12:07 ` Nelson Chu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).