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;
+ }
+}
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
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
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)
{
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;
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;
&& 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;
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;
}
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);
.*: 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
.*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