Skip to content

Commit 97f006b

Browse files
committed
RISC-V: Better support for long instructions (disassembler)
Commit bb99669 ("RISC-V/gas: allow generating up to 176-bit instructions with .insn") tried to start supporting long instructions but it was insufficient. On the disassembler, correct ".byte" output was limited to the first 64-bits of an instruction. After that, zeroes are incorrectly printed. Note that, it only happens on ".byte" output (instruction part) and not on hexdump (data) part. For example, before this commit, hexdump and ".byte" produces different values: Assembly: .insn 22, 0xfedcba98765432100123456789abcdef55aa33cc607f objdump output example (before the fix): 10: 607f 33cc 55aa cdef .byte 0x7f, 0x60, 0xcc, 0x33, 0xaa, 0x55, 0xef, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 18: 89ab 4567 0123 3210 20: 7654 ba98 fedc Note that, after 0xcd (after first 64-bits of the target instruction), all ".byte" values are incorrectly printed as zero while hexdump prints correct instruction bits. To resolve this, this commit adds "packet" argument to support dumping instructions longer than 64-bits (to print correct instruction bits on ".byte"). This commit will be tested on the separate commit. Assembly: .insn 22, 0xfedcba98765432100123456789abcdef55aa33cc607f objdump output example (after the fix): 10: 607f 33cc 55aa cdef .byte 0x7f, 0x60, 0xcc, 0x33, 0xaa, 0x55, 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe 18: 89ab 4567 0123 3210 20: 7654 ba98 fedc opcodes/ChangeLog: * riscv-dis.c (riscv_disassemble_insn): Print unknown instruction using the new argument packet. (riscv_disassemble_data): Add unused argument packet. (print_insn_riscv): Pass packet to the disassemble function.
1 parent 2dc5f50 commit 97f006b

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

opcodes/riscv-dis.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,10 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
641641
this is little-endian code. */
642642

643643
static int
644-
riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
644+
riscv_disassemble_insn (bfd_vma memaddr,
645+
insn_t word,
646+
const bfd_byte *packet,
647+
disassemble_info *info)
645648
{
646649
const struct riscv_opcode *op;
647650
static bool init = false;
@@ -806,8 +809,7 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
806809
", ");
807810
(*info->fprintf_styled_func) (info->stream, dis_style_immediate,
808811
"0x%02x",
809-
(unsigned int) (word & 0xff));
810-
word >>= 8;
812+
(unsigned int) (*packet++));
811813
}
812814
}
813815
break;
@@ -983,6 +985,7 @@ riscv_data_length (bfd_vma memaddr,
983985
static int
984986
riscv_disassemble_data (bfd_vma memaddr ATTRIBUTE_UNUSED,
985987
insn_t data,
988+
const bfd_byte *packet ATTRIBUTE_UNUSED,
986989
disassemble_info *info)
987990
{
988991
info->display_endian = info->endian;
@@ -1037,7 +1040,8 @@ print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info)
10371040
bfd_vma dump_size;
10381041
int status;
10391042
enum riscv_seg_mstate mstate;
1040-
int (*riscv_disassembler) (bfd_vma, insn_t, struct disassemble_info *);
1043+
int (*riscv_disassembler) (bfd_vma, insn_t, const bfd_byte *,
1044+
struct disassemble_info *);
10411045

10421046
if (info->disassembler_options != NULL)
10431047
{
@@ -1081,7 +1085,7 @@ print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info)
10811085
}
10821086
insn = (insn_t) bfd_get_bits (packet, dump_size * 8, false);
10831087

1084-
return (*riscv_disassembler) (memaddr, insn, info);
1088+
return (*riscv_disassembler) (memaddr, insn, packet, info);
10851089
}
10861090

10871091
disassembler_ftype

0 commit comments

Comments
 (0)