@@ -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