#include <stdint.h>
#include <ctype.h>
+/* Current XLEN for the disassembler. */
+unsigned xlen = 0;
+
+/* Default ISA specification version (constant as of now). */
static enum riscv_spec_class default_isa_spec = ISA_SPEC_CLASS_DRAFT - 1;
-static enum riscv_spec_class default_priv_spec = PRIV_SPEC_CLASS_NONE;
-unsigned xlen = 0;
+/* Default privileged specification
+ (as specified by the ELF attributes or the `priv-spec' option). */
+static enum riscv_spec_class default_priv_spec = PRIV_SPEC_CLASS_NONE;
static riscv_subset_list_t riscv_subsets;
static riscv_parse_subset_t riscv_rps_dis =
static bfd_vma last_stop_offset = 0;
enum riscv_seg_mstate last_map_state;
+/* Register names as used by the disassembler. */
static const char * const *riscv_gpr_names;
static const char * const *riscv_fpr_names;
/* If set, disassemble as most general instruction. */
static int no_aliases;
+
+/* Set default RISC-V disassembler options. */
+
static void
set_default_riscv_dis_options (void)
{
no_aliases = 0;
}
+/* Parse RISC-V disassembler option (without arguments). */
+
static bool
parse_riscv_dis_option_without_args (const char *option)
{
return true;
}
+/* Parse RISC-V disassembler option (possibly with arguments). */
+
static void
parse_riscv_dis_option (const char *option)
{
}
}
+/* Parse RISC-V disassembler options. */
+
static void
parse_riscv_dis_options (const char *opts_in)
{
(*info->fprintf_styled_func) (info->stream, dis_style_text, "%s", s);
}
+/* If we need to print an address, set its value and state. */
+
static void
maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
int wide)
break;
case 'u':
print (info->stream, dis_style_immediate, "0x%x",
- (int)(EXTRACT_CITYPE_IMM (l) & (RISCV_BIGIMM_REACH-1)));
+ (unsigned)(EXTRACT_CITYPE_IMM (l) & (RISCV_BIGIMM_REACH-1)));
break;
case '>':
print (info->stream, dis_style_immediate, "0x%x",
- (int)EXTRACT_CITYPE_IMM (l) & 0x3f);
+ (unsigned)EXTRACT_CITYPE_IMM (l) & 0x3f);
break;
case '<':
print (info->stream, dis_style_immediate, "0x%x",
- (int)EXTRACT_CITYPE_IMM (l) & 0x1f);
+ (unsigned)EXTRACT_CITYPE_IMM (l) & 0x1f);
break;
case 'T': /* Floating-point RS2. */
print (info->stream, dis_style_register, "%s",
(int)EXTRACT_RVV_OFFSET (l));
break;
case 'm':
- if (! EXTRACT_OPERAND (VMASK, l))
- print (info->stream, dis_style_register, ",%s",
- riscv_vecm_names_numeric[0]);
+ if (!EXTRACT_OPERAND (VMASK, l))
+ {
+ print (info->stream, dis_style_text, ",");
+ print (info->stream, dis_style_register, "%s",
+ riscv_vecm_names_numeric[0]);
+ }
break;
}
break;
break;
case 'y':
- print (info->stream, dis_style_text, "0x%x",
- (int)EXTRACT_OPERAND (BS, l));
+ print (info->stream, dis_style_immediate, "0x%x",
+ (unsigned)EXTRACT_OPERAND (BS, l));
break;
case 'z':
case '>':
print (info->stream, dis_style_immediate, "0x%x",
- (int)EXTRACT_OPERAND (SHAMT, l));
+ (unsigned)EXTRACT_OPERAND (SHAMT, l));
break;
case '<':
print (info->stream, dis_style_immediate, "0x%x",
- (int)EXTRACT_OPERAND (SHAMTW, l));
+ (unsigned)EXTRACT_OPERAND (SHAMTW, l));
break;
case 'S':
}
if (riscv_csr_hash[csr] != NULL)
- print (info->stream, dis_style_text, "%s", riscv_csr_hash[csr]);
+ print (info->stream, dis_style_register, "%s",
+ riscv_csr_hash[csr]);
else
- print (info->stream, dis_style_text, "0x%x", csr);
+ print (info->stream, dis_style_immediate, "0x%x", csr);
break;
}
case 'Y':
- print (info->stream, dis_style_text, "0x%x",
- (int) EXTRACT_OPERAND (RNUM, l));
+ print (info->stream, dis_style_immediate, "0x%x",
+ (unsigned) EXTRACT_OPERAND (RNUM, l));
break;
case 'Z':
- print (info->stream, dis_style_text, "%d", rs1);
+ print (info->stream, dis_style_immediate, "%d", rs1);
break;
case 'X': /* Integer immediate. */
switch (*++oparg)
{
+ case 'l': /* Literal. */
+ oparg++;
+ while (*oparg && *oparg != ',')
+ {
+ print (info->stream, dis_style_immediate, "%c", *oparg);
+ oparg++;
+ }
+ oparg--;
+ break;
case 's': /* 'XsN@S' ... N-bit signed immediate at bit S. */
sign = true;
goto print_imm;
sign = false;
goto print_imm;
print_imm:
- n = strtol (++oparg, (char **)&oparg, 10);
+ n = strtol (oparg + 1, (char **)&oparg, 10);
if (*oparg != '@')
goto undefined_modifier;
- s = strtol (++oparg, (char **)&oparg, 10);
+ s = strtol (oparg + 1, (char **)&oparg, 10);
oparg--;
if (!sign)
- print (info->stream, dis_style_immediate, "%u",
- (unsigned)EXTRACT_U_IMM (n, s, l));
+ print (info->stream, dis_style_immediate, "%lu",
+ (unsigned long)EXTRACT_U_IMM (n, s, l));
else
- print (info->stream, dis_style_immediate, "%i",
- (unsigned)EXTRACT_S_IMM (n, s, l));
+ print (info->stream, dis_style_immediate, "%li",
+ (signed long)EXTRACT_S_IMM (n, s, l));
break;
default:
goto undefined_modifier;
xlen = ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? 64 : 32;
}
- /* If arch has ZFINX flags, use gpr for disassemble. */
- if(riscv_subset_supports (&riscv_rps_dis, "zfinx"))
+ /* If arch has the Zfinx extension, replace FPR with GPR. */
+ if (riscv_subset_supports (&riscv_rps_dis, "zfinx"))
riscv_fpr_names = riscv_gpr_names;
for (; op->name; op++)
/* Is this instruction restricted to a certain value of XLEN? */
if ((op->xlen_requirement != 0) && (op->xlen_requirement != xlen))
continue;
-
+ /* Is this instruction supported by the current architecture? */
if (!riscv_multi_subset_supports (&riscv_rps_dis, op->insn_class))
continue;
case 4:
case 8:
(*info->fprintf_styled_func)
- (info->stream, dis_style_assembler_directive, ".%dbyte\t", insnlen);
+ (info->stream, dis_style_assembler_directive, ".%dbyte", insnlen);
+ (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
(*info->fprintf_styled_func) (info->stream, dis_style_immediate,
"0x%llx", (unsigned long long) word);
break;
{
int i;
(*info->fprintf_styled_func)
- (info->stream, dis_style_assembler_directive, ".byte\t");
+ (info->stream, dis_style_assembler_directive, ".byte");
+ (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
for (i = 0; i < insnlen; ++i)
{
if (i > 0)
case 1:
info->bytes_per_line = 6;
(*info->fprintf_styled_func)
- (info->stream, dis_style_assembler_directive, ".byte\t");
- (*info->fprintf_styled_func)
- (info->stream, dis_style_assembler_directive, "0x%02llx",
- (unsigned long long) data);
+ (info->stream, dis_style_assembler_directive, ".byte");
+ (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
+ (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
+ "0x%02x", (unsigned)data);
break;
case 2:
info->bytes_per_line = 8;
(*info->fprintf_styled_func)
- (info->stream, dis_style_assembler_directive, ".short\t");
+ (info->stream, dis_style_assembler_directive, ".short");
+ (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
(*info->fprintf_styled_func)
- (info->stream, dis_style_immediate, "0x%04llx",
- (unsigned long long) data);
+ (info->stream, dis_style_immediate, "0x%04x", (unsigned) data);
break;
case 4:
info->bytes_per_line = 8;
(*info->fprintf_styled_func)
- (info->stream, dis_style_assembler_directive, ".word\t");
+ (info->stream, dis_style_assembler_directive, ".word");
+ (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
(*info->fprintf_styled_func)
- (info->stream, dis_style_immediate, "0x%08llx",
- (unsigned long long) data);
+ (info->stream, dis_style_immediate, "0x%08lx",
+ (unsigned long) data);
break;
case 8:
info->bytes_per_line = 8;
(*info->fprintf_styled_func)
- (info->stream, dis_style_assembler_directive, ".dword\t");
+ (info->stream, dis_style_assembler_directive, ".dword");
+ (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
(*info->fprintf_styled_func)
(info->stream, dis_style_immediate, "0x%016llx",
(unsigned long long) data);
int
print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info)
{
- bfd_byte packet[8];
+ bfd_byte packet[RISCV_MAX_INSN_LEN];
insn_t insn = 0;
bfd_vma dump_size;
int status;