Skip to content

Commit 9b2620d

Browse files
committed
arcv: dis: apex: Add instruction decoding in disassembler.
Introduce support for disassembling APEX Custom-0 instructions (opcode 0xB). This adds: - Type predicates for identifying XD, XS, XI, and XC formats. - Sub-opcode extractors for each format: - XD: bits 31..25 and bit 14 - XS: bits 23..20 and bits 14..13 - XI/XC: bits 19..15 - Format-specific offsets into the arcv_apex_insns[] table. If we don't find a match in the riscv_opcodes[], the instructions with opcode 0xB are checked against the APEX formats, their sub-opcodes extracted, and the corresponding entry retrieved from arcv_apex_insns[]. Signed-off-by: Luis Silva <luiss@synopsys.com>
1 parent 5936cd9 commit 9b2620d

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed

opcodes/riscv-dis.c

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,74 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
897897
}
898898
}
899899

900+
/* Check if instruction is an APEX XD-type.
901+
XD is identified by bits [13:12] == 00. */
902+
903+
static bool
904+
arcv_apex_xd_type_p (insn_t num)
905+
{
906+
return ((num >> 12) & 0x3) == 0x0;
907+
}
908+
909+
/* Check if instruction is an APEX XS-type.
910+
XS is identified by bit [12] == 1. */
911+
912+
static bool
913+
arcv_apex_xs_type_p (insn_t num)
914+
{
915+
return ((num >> 12) & 0x1) == 0x1;
916+
}
917+
918+
/* Check if instruction is an APEX XI-type.
919+
XI is identified by bits [14:12] == 010. */
920+
921+
static bool
922+
arcv_apex_xi_type_p (insn_t num)
923+
{
924+
return ((num >> 12) & 0x7) == 0x2;
925+
}
926+
927+
/* Check if instruction is an APEX XC-type.
928+
XC is identified by bits [14:12] == 110. */
929+
930+
static bool
931+
arcv_apex_xc_type_p (insn_t num)
932+
{
933+
return ((num >> 12) & 0x7) == 0x6;
934+
}
935+
936+
/* Extract the sub-opcode for an XD-format instruction.
937+
Bits 31..25 are shifted left by 1, bit 14 is OR-ed in. */
938+
939+
static int
940+
opcode_extract_xd_type (uint64_t num)
941+
{
942+
uint64_t bits_31_25 = (num >> 25) & 0x7F;
943+
uint64_t bit_14 = (num >> 14) & 1;
944+
return (bits_31_25 << 1) | bit_14;
945+
}
946+
947+
/* Extract the sub-opcode for an XS-format instruction.
948+
Bits 23..20 form the high part, bits 14..13 form the low part. */
949+
950+
static int
951+
opcode_extract_xs_type (uint32_t num)
952+
{
953+
uint32_t bits_14_13 = ((num >> 13) & 0x3);
954+
uint32_t bits_23_20 = ((num >> 20) & 0xF);
955+
return (bits_23_20 << 2) | bits_14_13;
956+
}
957+
958+
/* Extract the sub-opcode for XI/XC-format instructions.
959+
Bits 19..15 are used directly as the sub-opcode. */
960+
961+
static int
962+
opcode_extract_xi_xc_type (uint32_t num)
963+
{
964+
uint32_t bits_19_15 = ((num >> 15) & 0x1F);
965+
return bits_19_15;
966+
}
967+
900968
/* Print the RISC-V instruction at address MEMADDR in debugged memory,
901969
on using INFO. Returns length of the instruction, in bytes.
902970
BIGENDIAN must be 1 if this is big-endian code, 0 if
@@ -1027,6 +1095,47 @@ riscv_disassemble_insn (bfd_vma memaddr,
10271095
}
10281096
}
10291097

1098+
/* We did not find a match, check if the instruction is a custom APEX
1099+
Custom-0 instruction (opcode 0xB). If so, determine the format
1100+
(XD, XS, XI, XC) using the type predicates, extract the appropriate
1101+
sub-opcode, calculate the format-specific offset, and look up the
1102+
instruction in arcv_apex_insns[]. */
1103+
if ((word & 0xF) == 0xB)
1104+
{
1105+
unsigned int offset, sub_opcode;
1106+
if (arcv_apex_xd_type_p (word))
1107+
{
1108+
sub_opcode = opcode_extract_xd_type (word);
1109+
offset = ARCV_APEX_OFFSET_XD;
1110+
}
1111+
else if (arcv_apex_xs_type_p (word))
1112+
{
1113+
sub_opcode = opcode_extract_xs_type (word);
1114+
offset = ARCV_APEX_OFFSET_XS;
1115+
}
1116+
else if (arcv_apex_xi_type_p (word))
1117+
{
1118+
sub_opcode = opcode_extract_xi_xc_type (word);
1119+
offset = ARCV_APEX_OFFSET_XI;
1120+
}
1121+
else if (arcv_apex_xc_type_p (word))
1122+
{
1123+
sub_opcode = opcode_extract_xi_xc_type (word);
1124+
offset = ARCV_APEX_OFFSET_XC;
1125+
}
1126+
op = arcv_apex_insns[sub_opcode + offset];
1127+
1128+
/* Does the opcode match? */
1129+
if (op && (op->match_func) (op, word))
1130+
{
1131+
/* It's a match. */
1132+
(*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
1133+
"%s", op->name);
1134+
print_insn_args (op->args, word, memaddr, info);
1135+
return insnlen;
1136+
}
1137+
}
1138+
10301139
/* We did not find a match, so just print the instruction bits in
10311140
the shape of an assembler .insn directive. */
10321141
info->insn_type = dis_noninsn;

0 commit comments

Comments
 (0)