aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormmc28a <78873583+mmc28a@users.noreply.github.com>2024-06-05 10:32:55 +0100
committerGitHub <noreply@github.com>2024-06-05 10:32:55 +0100
commit662828c82625f2436153d2e4f22cbf269c5f959b (patch)
treeee0f49d6b24b4d1b11695ca3478bd3c3d52b8c67
parent5e267967c8e81b31b7c59b1da3c735b446ea9672 (diff)
Fix disassembly of Neon FCM, RDM and dot product instructions (#98)HEADmain
Disassembling some FCM, RDM and dot product instructions could report vector types that are undefined for the associated mnemonics. Fix this and add tests.
-rw-r--r--src/aarch64/disasm-aarch64.cc16
-rw-r--r--test/aarch64/test-disasm-aarch64.cc10
-rw-r--r--test/aarch64/test-disasm-neon-aarch64.cc45
3 files changed, 61 insertions, 10 deletions
diff --git a/src/aarch64/disasm-aarch64.cc b/src/aarch64/disasm-aarch64.cc
index b94ecfbe..6a25271f 100644
--- a/src/aarch64/disasm-aarch64.cc
+++ b/src/aarch64/disasm-aarch64.cc
@@ -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;
}
diff --git a/test/aarch64/test-disasm-aarch64.cc b/test/aarch64/test-disasm-aarch64.cc
index 2babb9e6..28eb2836 100644
--- a/test/aarch64/test-disasm-aarch64.cc
+++ b/test/aarch64/test-disasm-aarch64.cc
@@ -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
diff --git a/test/aarch64/test-disasm-neon-aarch64.cc b/test/aarch64/test-disasm-neon-aarch64.cc
index 0b377945..c2824c9e 100644
--- a/test/aarch64/test-disasm-neon-aarch64.cc
+++ b/test/aarch64/test-disasm-neon-aarch64.cc
@@ -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();
}