Fix disassembly of Neon FCM, RDM and dot product instructions (#98)

Disassembling some FCM, RDM and dot product instructions could report vector
types that are undefined for the associated mnemonics. Fix this and add tests.
This commit is contained in:
mmc28a 2024-06-05 10:32:55 +01:00 committed by GitHub
parent 5e267967c8
commit 662828c826
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 61 additions and 10 deletions

View File

@ -2374,13 +2374,19 @@ void Disassembler::VisitNEON3SameFP16(const Instruction *instr) {
}
void Disassembler::VisitNEON3SameExtra(const Instruction *instr) {
static const NEONFormatMap map_usdot = {{30}, {NF_8B, NF_16B}};
static const NEONFormatMap map_dot =
{{23, 22, 30}, {NF_UNDEF, NF_UNDEF, NF_UNDEF, NF_UNDEF, NF_2S, NF_4S}};
static const NEONFormatMap map_fc =
{{23, 22, 30},
{NF_UNDEF, NF_UNDEF, NF_4H, NF_8H, NF_2S, NF_4S, NF_UNDEF, NF_2D}};
static const NEONFormatMap map_rdm =
{{23, 22, 30}, {NF_UNDEF, NF_UNDEF, NF_4H, NF_8H, NF_2S, NF_4S}};
const char *mnemonic = mnemonic_.c_str();
const char *form = "'Vd.%s, 'Vn.%s, 'Vm.%s";
const char *suffix = NULL;
NEONFormatDecoder nfd(instr);
NEONFormatDecoder nfd(instr, &map_fc);
switch (form_hash_) {
case "fcmla_asimdsame2_c"_h:
@ -2393,11 +2399,11 @@ void Disassembler::VisitNEON3SameExtra(const Instruction *instr) {
case "sdot_asimdsame2_d"_h:
case "udot_asimdsame2_d"_h:
case "usdot_asimdsame2_d"_h:
nfd.SetFormatMap(1, &map_usdot);
nfd.SetFormatMap(2, &map_usdot);
nfd.SetFormatMaps(nfd.LogicalFormatMap());
nfd.SetFormatMap(0, &map_dot);
break;
default:
// sqrdml[as]h - nothing to do.
nfd.SetFormatMaps(&map_rdm);
break;
}

View File

@ -3543,8 +3543,8 @@ TEST(architecture_features) {
COMPARE_PREFIX(dci(0xf8e08000), "swpal"); // SWPAL_64_memop
// ARMv8.1 - RDM
COMPARE_PREFIX(dci(0x2e008400), "sqrdmlah"); // SQRDMLAH_asimdsame2_only
COMPARE_PREFIX(dci(0x2e008c00), "sqrdmlsh"); // SQRDMLSH_asimdsame2_only
COMPARE_PREFIX(dci(0x2e808400), "sqrdmlah"); // SQRDMLAH_asimdsame2_only
COMPARE_PREFIX(dci(0x2e808c00), "sqrdmlsh"); // SQRDMLSH_asimdsame2_only
COMPARE_PREFIX(dci(0x2f40d000), "sqrdmlah"); // SQRDMLAH_asimdelem_R
COMPARE_PREFIX(dci(0x2f40f000), "sqrdmlsh"); // SQRDMLSH_asimdelem_R
COMPARE_PREFIX(dci(0x7e008400), "sqrdmlah"); // SQRDMLAH_asisdsame2_only
@ -3553,9 +3553,9 @@ TEST(architecture_features) {
COMPARE_PREFIX(dci(0x7f40f000), "sqrdmlsh"); // SQRDMLSH_asisdelem_R
// ARMv8.2 - DotProd
COMPARE_PREFIX(dci(0x0e009400), "sdot"); // SDOT_asimdsame2_D
COMPARE_PREFIX(dci(0x0e809400), "sdot"); // SDOT_asimdsame2_D
COMPARE_PREFIX(dci(0x0f00e000), "sdot"); // SDOT_asimdelem_D
COMPARE_PREFIX(dci(0x2e009400), "udot"); // UDOT_asimdsame2_D
COMPARE_PREFIX(dci(0x2e809400), "udot"); // UDOT_asimdsame2_D
COMPARE_PREFIX(dci(0x2f00e000), "udot"); // UDOT_asimdelem_D
// ARMv8.2 - FHM
@ -3810,7 +3810,7 @@ TEST(architecture_features) {
// ARMv8.3 - FCMA
COMPARE_PREFIX(dci(0x2e40c400), "fcmla"); // FCMLA_asimdsame2_C
COMPARE_PREFIX(dci(0x2e00e400), "fcadd"); // FCADD_asimdsame2_C
COMPARE_PREFIX(dci(0x2e40e400), "fcadd"); // FCADD_asimdsame2_C
COMPARE_PREFIX(dci(0x2f401000), "fcmla"); // FCMLA_asimdelem_C_H
COMPARE_PREFIX(dci(0x6f801000), "fcmla"); // FCMLA_asimdelem_C_S

View File

@ -1792,6 +1792,34 @@ TEST(neon_3same) {
COMPARE_MACRO(Pmul(v6.V16B(), v7.V16B(), v8.V16B()),
"pmul v6.16b, v7.16b, v8.16b");
// Check unallocated vector types for SDOT.
COMPARE(dci(0x0e009400), "unallocated (Unallocated)"); // 8B
COMPARE(dci(0x4e009400), "unallocated (Unallocated)"); // 16B
COMPARE(dci(0x0e409400), "unallocated (Unallocated)"); // 4H
COMPARE(dci(0x4e409400), "unallocated (Unallocated)"); // 8H
COMPARE(dci(0x0ec09400), "unallocated (Unallocated)"); // 1D
COMPARE(dci(0x4ec09400), "unallocated (Unallocated)"); // 2D
// Check unallocated vector types for UDOT.
COMPARE(dci(0x2e009400), "unallocated (Unallocated)"); // 8B
COMPARE(dci(0x6e009400), "unallocated (Unallocated)"); // 16B
COMPARE(dci(0x2e409400), "unallocated (Unallocated)"); // 4H
COMPARE(dci(0x6e409400), "unallocated (Unallocated)"); // 8H
COMPARE(dci(0x2ec09400), "unallocated (Unallocated)"); // 1D
COMPARE(dci(0x6ec09400), "unallocated (Unallocated)"); // 2D
// Check unallocated vector types for SQRDMLAH.
COMPARE(dci(0x2e008400), "unallocated (Unallocated)"); // 8B
COMPARE(dci(0x6e008400), "unallocated (Unallocated)"); // 16B
COMPARE(dci(0x2ec08400), "unallocated (Unallocated)"); // 1D
COMPARE(dci(0x6ec08400), "unallocated (Unallocated)"); // 2D
// Check unallocated vector types for SQRDMLSH.
COMPARE(dci(0x2e008c00), "unallocated (Unallocated)"); // 8B
COMPARE(dci(0x6e008c00), "unallocated (Unallocated)"); // 16B
COMPARE(dci(0x2ec08c00), "unallocated (Unallocated)"); // 1D
COMPARE(dci(0x6ec08c00), "unallocated (Unallocated)"); // 2D
CLEANUP();
}
@ -1924,6 +1952,16 @@ TEST(neon_3same_extra_fcadd) {
COMPARE(dci(0x2e00ec00), "unallocated (Unallocated)"); // opcode = 0x1101
COMPARE(dci(0x2e00fc00), "unallocated (Unallocated)"); // opcode = 0x1111
// Check unallocated vector types for FCADD.
COMPARE(dci(0x2e00e400), "unallocated (Unallocated)"); // 8B
COMPARE(dci(0x6e00e400), "unallocated (Unallocated)"); // 16B
COMPARE(dci(0x2ec0e400), "unallocated (Unallocated)"); // 1D
// Check unallocated vector types for FCMLA.
COMPARE(dci(0x2e00c400), "unallocated (Unallocated)"); // 8B
COMPARE(dci(0x6e00c400), "unallocated (Unallocated)"); // 16B
COMPARE(dci(0x2ec0c400), "unallocated (Unallocated)"); // 1D
CLEANUP();
}
@ -2594,6 +2632,13 @@ TEST(neon_fp_byelement) {
COMPARE_MACRO(Fcmla(v0.V8H(), v1.V8H(), v31.H(), 3, 0),
"fcmla v0.8h, v1.8h, v31.h[3], #0");
// Check unallocated vector types for FCMLA.
COMPARE(dci(0x2f001000), "unallocated (Unallocated)"); // 8B
COMPARE(dci(0x6f001000), "unallocated (Unallocated)"); // 16B
COMPARE(dci(0x2f801000), "unallocated (Unallocated)"); // 2S
COMPARE(dci(0x2fc01000), "unallocated (Unallocated)"); // 1D
COMPARE(dci(0x6fc01000), "unallocated (Unallocated)"); // 2D
CLEANUP();
}